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
The device being written to
The time that the device was last flushed.
Set the name of the program to attach to log entries.
Set silencer
to false to disable silencing the log.
The TagFormatter
used for formatting tags for output
Public Class Methods
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
# File lib/lumberjack/logger.rb, line 312 def <<(msg) add_entry(UNKNOWN, msg) end
::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
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 the logging device.
# File lib/lumberjack/logger.rb, line 216 def close flush device.close if device.respond_to?(:close) @closed = true end
# File lib/lumberjack/logger.rb, line 222 def closed? @closed end
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
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
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
Set the log level to debug.
# File lib/lumberjack/logger.rb, line 302 def debug! self.level = DEBUG end
Return true
if DEBUG
messages are being logged.
# File lib/lumberjack/logger.rb, line 297 def debug? level <= DEBUG end
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
Set the log level to error.
# File lib/lumberjack/logger.rb, line 257 def error! self.level = ERROR end
Return true
if ERROR
messages are being logged.
# File lib/lumberjack/logger.rb, line 252 def error? level <= ERROR end
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
Set the log level to fatal.
# File lib/lumberjack/logger.rb, line 242 def fatal! self.level = FATAL end
Return true
if FATAL
messages are being logged.
# File lib/lumberjack/logger.rb, line 237 def fatal? level <= FATAL end
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
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
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
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
Set the log level to info.
# File lib/lumberjack/logger.rb, line 287 def info! self.level = INFO end
Return true
if INFO
messages are being logged.
# File lib/lumberjack/logger.rb, line 282 def info? level <= INFO end
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
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
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 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
# File lib/lumberjack/logger.rb, line 226 def reopen(logdev = nil) @closed = false device.reopen(logdev) if device.respond_to?(:reopen) end
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
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
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
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
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
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
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
Set the log level to warn.
# File lib/lumberjack/logger.rb, line 272 def warn! self.level = WARN end
Return true
if WARN
messages are being logged.
# File lib/lumberjack/logger.rb, line 267 def warn? level <= WARN end