logging snippets

How to add logging to CakePHP applications

Tagged cakephp, logging, debug, php  Languages php

Note that Pear's Logging package is a lot more flexible, so I recommend you use that instead of CakePHP's built-in logging.

Use this code to add a debug message to the CakePHP debug log:

$this->log("Upload action accessed", LOG_DEBUG);

Note that using something other than LOG_DEBUG will log the message as an error.

Run the code once and you should be able to see the message in $CAKE_APP/tmp/logs/debug.log.

Logging to a file with Elixir

Tagged logging, elixir, file  Languages elixir

mix.exs:

  def application do
    [
      applications: [:logger, :logger_file_backend, ...],
      mod: {Snippets, []}
    ]
  end

  def deps do
    [
      {:cowboy, "~> 1.0.0"}, # web server
      {:logger_file_backend, "~> 0.0.7"} # writes log messages to a file, LOL
      ....
    ]
   end

config/dev.exs:

config :logger, :error_log,
  path: "log/app.log",
  level: :debug

Logging in Golang (including line numbers)

Tagged line numbers, go, log, logging, debug, info, wrapper  Languages go, bash

Features

  • Prints location of errors including line number
  • Debug mode

Code

var debug bool

func init() {
    debug = os.Getenv("DEBUG") != ""
}

// Info example:
//
// Info("timezone %s", timezone)
//
func Info(msg string, vars ...interface{}) {
    log.Printf(strings.Join([]string{"[INFO ]", msg}, " "), vars...)
}

// Debug example:
//
// Debug("timezone %s", timezone)
//
func Debug(msg string, vars ...interface{}) {
    if debug {
        log.Printf(strings.Join([]string{"[DEBUG]", msg}, " "), vars...)
    }
}

// Fatal example:
//
// Fatal(errors.New("db timezone must be UTC"))
//
func Fatal(err error) {
    pc, fn, line, _ := runtime.Caller(1)
    // Include function name if debugging
    if debug {
        log.Fatalf("[FATAL] %s [%s:%s:%d]", err, runtime.FuncForPC(pc).Name(), fn, line)
    } else {
        log.Fatalf("[FATAL] %s [%s:%d]", err, fn, line)
    }
}

// Error example:
//
// Error(errors.Errorf("Invalid timezone %s", timezone))
//
func Error(err error) {
    pc, fn, line, _ := runtime.Caller(1)
    // Include function name if debugging
    if debug {
        log.Printf("[ERROR] %s [%s:%s:%d]", err, runtime.FuncForPC(pc).Name(), fn, line)
    } else {
        log.Printf("[ERROR] %s [%s:%d]", err, fn, line)
    }
}

Example

2019/05/30 11:31:30 [FATAL] pq: unsupported sslmode "ddisable"; only "require" (default), "verify-full", "verify-ca", and "disable" supported [github.com/christianhellsten/goscheduler/poller.go:52]

Log shipping with rsyslog

Tagged logs, remote, rsyslog, shipping, logging  Languages 

Server

/etc/rsyslog.conf

$ModLoad imtcp
 
#
# Disable rate-limiting
#
# "interval = 1 AND burst = 1000" means rsyslog starts dropping messages if more than 1000 messages are received within 1 seconds. 
$SystemLogRateLimitInterval 0
$SystemLogRateLimitBurst 0

/etc/rsyslog.d/35-remote-logs.conf

input(type="imtcp" port="514" ruleset="remote")
template(name="PerRemoteHostLogFileName" type="list") {
   constant(value="/var/log/hosts/")
   property(name="$year")
   constant(value="/")
   property(name="$month")
   constant(value="/")
   property(name="hostname" securepath="replace")
   constant(value="/")
   property(name="programname" securepath="replace")
   constant(value=".log")
}
ruleset(name="remote") {
   $FileCreateMode 0640
   $DirCreateMode 0755
   ?PerRemoteHostLogFileName
}

Client

/etc/rsyslog.conf

# Disable rate-limiting
$SystemLogRateLimitInterval 0
$SystemLogRateLimitBurst 0

#
# Send all logs to centralized log server over TCP
#
*.*       @@{{log_server_ip_addr}}