Slog

Easy structured logging.

Slog::Logger extends the base Logger with JSON serialization, colorization, and more. Output is suitable for collection by Logstash or Franz.

require 'slog'


# Full initializer
Slog::Logger.new \
             out: $stdout,         # Set the log output handle
       shift_age: 7,               # Number of log files to keep
      shift_size: 1_048_576,       # Maximum size of log files (in bytes)
        colorize: true,            # Toggle colorized output
        prettify: true,            # Toggle pretty JSON output
           level: :info,           # Set log level (Logger constant or Symbol)
 level_transform: 'downcase',      # Transform the log level (String methods)
     level_field: 'level',         # Set level field name (nil to disable)
   message_field: 'message',       # Set message field name (nil to disable)
 timestamp_field: '@timestamp',    # Set timestamp field name (nil to disable)
timestamp_format: '%FT%T.%3N%:z',  # Set timestamp format (Time#strftime)
       # Map each log level to fore- and background colors
       # Colors provided by the fantastic "colorize" gem
       color_map: { 'debug' => [ :blue,    :default ],
                    'info'  => [ :green,   :default ],
                    'warn'  => [ :yellow,  :default ],
                    'error' => [ :red,     :default ],
                    'fatal' => [ :red,     :black   ] }


# These two are equivalent
Slog::Logger.new
Slog.new


# By default, output is pretty and colored (I swear)
Slog.new.info 'example'
#
#   {
#     "level": "info",
#     "@timestamp": "2014-12-25T06:22:43.459-08:00",
#     "message": "example"
#   }
#


# When logging to file, you prolly want to disable that
Slog.new(out: 'test.log', colorize: false, prettify: false).info 'example'
#
#   {"level":"info","@timestamp":"2014-12-25T06:25:54.793-08:00","message":"example"}
#


# You'll no doubt have noticed you passed a String into the Logger, but a Hash
# came out the other end. That's "structured" logging. The String turned into
# the "message" field, and "level" and "@timestamp" fields were added. All
# that's totally configurable:
Slog.new({
  message_field: nil,
  timestamp_field: 'date',
  timestamp_format: '%Y.%m.%d'
}).info 'example'
#
#   {
#     "level": "info",
#     "date": "2014.12.25"
#   }
#


# You can write structured logs by passing a Hash
Slog.new({
  level_field: nil,
}).info event: 'example', level: 'MINE', '@timestamp' => nil
#
#   {
#     "event": "example",
#     "level": "MINE",
#     "@timestamp": null
#   }
#