class Lumberjack::Logger

Logger is a thread safe logging object. It has a compatible API with the Ruby standard library Logger class, the Log4r gem, and ActiveSupport::BufferedLogger.

Example

logger = Lumberjack::Logger.new
logger.info("Starting processing")
logger.debug("Processing options #{options.inspect}")
logger.fatal("OMG the application is on fire!")

Log entries are written to a logging Device if their severity meets or exceeds the log level.

Devices may use buffers internally and the log entries are not guaranteed to be written until you call the flush method. Sometimes this can result in problems when trying to track down extraordinarily long running sections of code since it is likely that none of the messages logged before the long running code will appear in the log until the entire process finishes. You can set the :flush_seconds option on the constructor to force the device to be flushed periodically. This will create a new monitoring thread, but its use is highly recommended.

Each log entry records the log message and severity along with the time it was logged, the program name, process id, and unit of work id. The message will be converted to a string, but otherwise, it is up to the device how these values are recorded. Messages are converted to strings using a Formatter associated with the logger.

Attributes

device[RW]

The device being written to

last_flushed_at[R]

The time that the device was last flushed.

progname[W]

Set the name of the program to attach to log entries.

silencer[RW]

Set silencer to false to disable silencing the log.

tag_formatter[RW]

The TagFormatter used for formatting tags for output

Public Class Methods

new(device = $stdout, options = {}) click to toggle source

Create a new logger to log to a Device.

The device argument can be in any one of several formats.

If it is a Device object, that object will be used. If it has a write method, it will be wrapped in a Device::Writer class. If it is :null, it will be a Null device that won't record any output. Otherwise, it will be assumed to be file path and wrapped in a Device::LogFile class.

This method can take the following options:

  • :level - The logging level below which messages will be ignored.

  • :formatter - The formatter to use for outputting messages to the log.

  • :datetime_format - The format to use for log timestamps.

  • :tag_formatter - The TagFormatter to use for formatting tags.

  • :progname - The name of the program that will be recorded with each log entry.

  • :flush_seconds - The maximum number of seconds between flush calls.

  • :roll - If the log device is a file path, it will be a Device::DateRollingLogFile if this is set.

  • :max_size - If the log device is a file path, it will be a Device::SizeRollingLogFile if this is set.

All other options are passed to the device constuctor.

# File lib/lumberjack/logger.rb, line 66
def initialize(device = $stdout, options = {})
  options = options.dup
  self.level = options.delete(:level) || INFO
  self.progname = options.delete(:progname)
  max_flush_seconds = options.delete(:flush_seconds).to_f

  @device = open_device(device, options) if device
  self.formatter = (options[:formatter] || Formatter.new)
  @tag_formatter = (options[:tag_formatter] || TagFormatter.new)
  time_format = (options[:datetime_format] || options[:time_format])
  self.datetime_format = time_format if time_format
  @last_flushed_at = Time.now
  @silencer = true
  @tags = {}
  @closed = false

  create_flusher_thread(max_flush_seconds) if max_flush_seconds > 0
end

Public Instance Methods

<<(msg) click to toggle source
# File lib/lumberjack/logger.rb, line 312
def <<(msg)
  add_entry(UNKNOWN, msg)
end
add(severity, message = nil, progname = nil, &block) click to toggle source

::Logger compatible method to add a log entry.

# File lib/lumberjack/logger.rb, line 194
def add(severity, message = nil, progname = nil, &block)
  if message.nil?
    if block
      message = block
    else
      message = progname
      progname = nil
    end
  end
  add_entry(severity, message, progname)
end
Also aliased as: log
add_entry(severity, message, progname = nil, tags = nil) click to toggle source

Add a message to the log with a given severity. The message can be either passed in the message argument or supplied with a block. This method is not normally called. Instead call one of the helper functions fatal, error, warn, info, or debug.

The severity can be passed in either as one of the Severity constants, or as a Severity label.

Example

logger.add_entry(Logger::ERROR, exception)
logger.add_entry(Logger::INFO, "Request completed")
logger.add_entry(:warn, "Request took a long time")
logger.add_entry(Logger::DEBUG){"Start processing with options #{options.inspect}"}
# File lib/lumberjack/logger.rb, line 158
def add_entry(severity, message, progname = nil, tags = nil)
  begin
    severity = Severity.label_to_level(severity) unless severity.is_a?(Integer)
    return true unless device && severity && severity >= level

    return true if Thread.current[:lumberjack_logging]
    Thread.current[:lumberjack_logging] = true

    time = Time.now
    message = message.call if message.is_a?(Proc)
    message = formatter.format(message)
    progname ||= self.progname

    current_tags = self.tags
    tags = nil unless tags.is_a?(Hash)
    if current_tags.empty?
      tags = Tags.stringify_keys(tags) unless tags.nil?
    else
      tags = if tags.nil?
        current_tags.dup
      else
        current_tags.merge(Tags.stringify_keys(tags))
      end
    end
    tags = Tags.expand_runtime_values(tags)
    tags = tag_formatter.format(tags) if tag_formatter

    entry = LogEntry.new(time, severity, message, progname, $$, tags)
    write_to_device(entry)
  ensure
    Thread.current[:lumberjack_logging] = nil
  end
  true
end
close() click to toggle source

Close the logging device.

# File lib/lumberjack/logger.rb, line 216
def close
  flush
  device.close if device.respond_to?(:close)
  @closed = true
end
closed?() click to toggle source
# File lib/lumberjack/logger.rb, line 222
def closed?
  @closed
end
datetime_format() click to toggle source

Get the timestamp format on the device if it has one.

# File lib/lumberjack/logger.rb, line 86
def datetime_format
  device.datetime_format if device.respond_to?(:datetime_format)
end
datetime_format=(format) click to toggle source

Set the timestamp format on the device if it is supported.

# File lib/lumberjack/logger.rb, line 91
def datetime_format=(format)
  if device.respond_to?(:datetime_format=)
    device.datetime_format = format
  end
end
debug(message_or_progname_or_tags = nil, progname_or_tags = nil, &block) click to toggle source

Log a DEBUG message. The message can be passed in either the message argument or in a block.

# File lib/lumberjack/logger.rb, line 292
def debug(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
  call_add_entry(DEBUG, message_or_progname_or_tags, progname_or_tags, &block)
end
debug!() click to toggle source

Set the log level to debug.

# File lib/lumberjack/logger.rb, line 302
def debug!
  self.level = DEBUG
end
debug?() click to toggle source

Return true if DEBUG messages are being logged.

# File lib/lumberjack/logger.rb, line 297
def debug?
  level <= DEBUG
end
error(message_or_progname_or_tags = nil, progname_or_tags = nil, &block) click to toggle source

Log an ERROR message. The message can be passed in either the message argument or in a block.

# File lib/lumberjack/logger.rb, line 247
def error(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
  call_add_entry(ERROR, message_or_progname_or_tags, progname_or_tags, &block)
end
error!() click to toggle source

Set the log level to error.

# File lib/lumberjack/logger.rb, line 257
def error!
  self.level = ERROR
end
error?() click to toggle source

Return true if ERROR messages are being logged.

# File lib/lumberjack/logger.rb, line 252
def error?
  level <= ERROR
end
fatal(message_or_progname_or_tags = nil, progname_or_tags = nil, &block) click to toggle source

Log a FATAL message. The message can be passed in either the message argument or in a block.

# File lib/lumberjack/logger.rb, line 232
def fatal(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
  call_add_entry(FATAL, message_or_progname_or_tags, progname_or_tags, &block)
end
fatal!() click to toggle source

Set the log level to fatal.

# File lib/lumberjack/logger.rb, line 242
def fatal!
  self.level = FATAL
end
fatal?() click to toggle source

Return true if FATAL messages are being logged.

# File lib/lumberjack/logger.rb, line 237
def fatal?
  level <= FATAL
end
flush() click to toggle source

Flush the logging device. Messages are not guaranteed to be written until this method is called.

# File lib/lumberjack/logger.rb, line 209
def flush
  device.flush
  @last_flushed_at = Time.now
  nil
end
formatter() click to toggle source

Get the Lumberjack::Formatter used to format objects for logging as messages.

# File lib/lumberjack/logger.rb, line 123
def formatter
  if respond_to?(:tagged)
    # Wrap in an object that supports ActiveSupport::TaggedLogger API
    TaggedLoggerSupport::Formatter.new(logger: self, formatter: @_formatter)
  else
    @_formatter
  end
end
formatter=(value) click to toggle source

Set the Lumberjack::Formatter used to format objects for logging as messages.

# File lib/lumberjack/logger.rb, line 118
def formatter=(value)
  @_formatter = (value.is_a?(TaggedLoggerSupport::Formatter) ? value.__formatter : value)
end
info(message_or_progname_or_tags = nil, progname_or_tags = nil, &block) click to toggle source

Log an INFO message. The message can be passed in either the message argument or in a block.

# File lib/lumberjack/logger.rb, line 277
def info(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
  call_add_entry(INFO, message_or_progname_or_tags, progname_or_tags, &block)
end
info!() click to toggle source

Set the log level to info.

# File lib/lumberjack/logger.rb, line 287
def info!
  self.level = INFO
end
info?() click to toggle source

Return true if INFO messages are being logged.

# File lib/lumberjack/logger.rb, line 282
def info?
  level <= INFO
end
level() click to toggle source

Get the level of severity of entries that are logged. Entries with a lower severity level will be ignored.

# File lib/lumberjack/logger.rb, line 99
def level
  thread_local_value(:lumberjack_logger_level) || @level
end
Also aliased as: sev_threshold
level=(value) click to toggle source

Set the log level using either an integer level like Logger::INFO or a label like :info or “info”

# File lib/lumberjack/logger.rb, line 107
def level=(value)
  @level = if value.is_a?(Integer)
    value
  else
    Severity.label_to_level(value)
  end
end
Also aliased as: sev_threshold=
log(severity, message = nil, progname = nil, &block)
Alias for: add
progname() click to toggle source

Get the program name associated with log messages.

# File lib/lumberjack/logger.rb, line 347
def progname
  thread_local_value(:lumberjack_logger_progname) || @progname
end
remove_tag(*tag_names) click to toggle source

Remove a tag from the current tag context. If this is called inside a block to a call to `tag`, the tags will only be removed for the duration of that block. Otherwise they will be removed from the global tags.

# File lib/lumberjack/logger.rb, line 374
def remove_tag(*tag_names)
  thread_tags = thread_local_value(:lumberjack_logger_tags)
  if thread_tags
    tag_names.each { |name| thread_tags.delete(name.to_s) }
  else
    tag_names.each { |name| @tags.delete(name.to_s) }
  end
end
reopen(logdev = nil) click to toggle source
# File lib/lumberjack/logger.rb, line 226
def reopen(logdev = nil)
  @closed = false
  device.reopen(logdev) if device.respond_to?(:reopen)
end
set_progname(value, &block) click to toggle source

Set the program name that is associated with log messages. If a block is given, the program name will be valid only within the block.

# File lib/lumberjack/logger.rb, line 338
def set_progname(value, &block)
  if block
    push_thread_local_value(:lumberjack_logger_progname, value, &block)
  else
    self.progname = value
  end
end
sev_threshold()
Alias for: level
sev_threshold=(value)
Alias for: level=
silence(temporary_level = ERROR) { || ... } click to toggle source

Silence the logger by setting a new log level inside a block. By default, only ERROR or FATAL messages will be logged.

Example

logger.level = Logger::INFO
logger.silence do
  do_something   # Log level inside the block is +ERROR+
end
# File lib/lumberjack/logger.rb, line 325
def silence(temporary_level = ERROR, &block)
  if silencer
    unless temporary_level.is_a?(Integer)
      temporary_level = Severity.label_to_level(temporary_level)
    end
    push_thread_local_value(:lumberjack_logger_level, temporary_level, &block)
  else
    yield
  end
end
tag(tags, &block) click to toggle source

Set a hash of tags on logger. If a block is given, the tags will only be set for the duration of the block. If this method is called inside such a block, the tags will only be defined on the tags in that block. When the parent block exits, all the tags will be reverted. If there is no block, then the tags will be defined as global and apply to all log statements.

# File lib/lumberjack/logger.rb, line 356
def tag(tags, &block)
  tags = Tags.stringify_keys(tags)
  thread_tags = thread_local_value(:lumberjack_logger_tags)
  if block
    merged_tags = (thread_tags ? thread_tags.merge(tags) : tags.dup)
    push_thread_local_value(:lumberjack_logger_tags, merged_tags, &block)
  elsif thread_tags
    thread_tags.merge!(tags)
    nil
  else
    @tags.merge!(tags)
    nil
  end
end
tagged_logger!() click to toggle source

Enable this logger to function like an ActiveSupport::TaggedLogger. This will make the logger API compatible with ActiveSupport::TaggedLogger and is provided as a means of compatibility with other libraries that assume they can call the `tagged` method on a logger to add tags.

The tags added with this method are just strings so they are stored in the logger tags in an array under the “tagged” tag. So calling `logger.tagged(“foo”, “bar”)` will result in tags `{“tagged” => [“foo”, “bar”]}`.

# File lib/lumberjack/logger.rb, line 139
def tagged_logger!
  extend(TaggedLoggerSupport)
  self
end
tags() click to toggle source

Return all tags in scope on the logger including global tags set on the Lumberjack context, tags set on the logger, and tags set on the current block for the logger.

# File lib/lumberjack/logger.rb, line 385
def tags
  tags = {}
  context_tags = Lumberjack.context_tags
  tags.merge!(context_tags) if context_tags && !context_tags.empty?
  tags.merge!(@tags) if !@tags.empty? && !thread_local_value(:lumberjack_logger_untagged)
  scope_tags = thread_local_value(:lumberjack_logger_tags)
  tags.merge!(scope_tags) if scope_tags && !scope_tags.empty?
  tags
end
unknown(message_or_progname_or_tags = nil, progname_or_tags = nil, &block) click to toggle source

Log a message when the severity is not known. Unknown messages will always appear in the log. The message can be passed in either the message argument or in a block.

# File lib/lumberjack/logger.rb, line 308
def unknown(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
  call_add_entry(UNKNOWN, message_or_progname_or_tags, progname_or_tags, &block)
end
untagged(&block) click to toggle source

Remove all tags on the current logger and logging context within a block. You can still set new block scoped tags within theuntagged block and provide tags on individual log methods.

# File lib/lumberjack/logger.rb, line 398
def untagged(&block)
  Lumberjack.use_context(nil) do
    scope_tags = thread_local_value(:lumberjack_logger_tags)
    untagged = thread_local_value(:lumberjack_logger_untagged)
    begin
      set_thread_local_value(:lumberjack_logger_untagged, true)
      set_thread_local_value(:lumberjack_logger_tags, nil)
      tag({}, &block)
    ensure
      set_thread_local_value(:lumberjack_logger_untagged, untagged)
      set_thread_local_value(:lumberjack_logger_tags, scope_tags)
    end
  end
end
warn(message_or_progname_or_tags = nil, progname_or_tags = nil, &block) click to toggle source

Log a WARN message. The message can be passed in either the message argument or in a block.

# File lib/lumberjack/logger.rb, line 262
def warn(message_or_progname_or_tags = nil, progname_or_tags = nil, &block)
  call_add_entry(WARN, message_or_progname_or_tags, progname_or_tags, &block)
end
warn!() click to toggle source

Set the log level to warn.

# File lib/lumberjack/logger.rb, line 272
def warn!
  self.level = WARN
end
warn?() click to toggle source

Return true if WARN messages are being logged.

# File lib/lumberjack/logger.rb, line 267
def warn?
  level <= WARN
end