lib/timber/logger.rb in timber-2.1.4 vs lib/timber/logger.rb in timber-2.1.5
- old
+ new
@@ -6,67 +6,18 @@
require "timber/event"
require "timber/log_devices"
require "timber/log_entry"
module Timber
- # The Timber Logger behaves exactly like `::Logger`, except that it supports a transparent API
- # for logging structured messages. It ensures your log messages are communicated properly
- # with the Timber.io API.
+ # The Timber Logger behaves exactly like the standard Ruby `::Logger`, except that it supports a
+ # transparent API for logging structured data and events.
#
- # To adhere to our no code debt / no lock-in promise, the Timber Logger will *never* deviate
- # from the `::Logger` interface. That is, it will *never* add methods, or alter any
- # method signatures. This ensures Timber can be removed without consequence.
- #
- # @example Basic example (the original ::Logger interface remains untouched):
+ # @example Basic logging
# logger.info "Payment rejected for customer #{customer_id}"
#
- # @example Using a Hash
- # # The :message key is required, the other additional key is your event type and data
- # # :type is the namespace used in timber for the :data
+ # @example Logging an event
# logger.info "Payment rejected", payment_rejected: {customer_id: customer_id, amount: 100}
- #
- # @example Using a Struct (a simple, more structured way, to define events)
- # PaymentRejectedEvent = Struct.new(:customer_id, :amount, :reason) do
- # # `#message` and `#type` are required, otherwise they will not be logged properly.
- # # `#type` is the namespace used in timber for the struct data
- # def message; "Payment rejected for #{customer_id}"; end
- # def type; :payment_rejected; end
- # end
- # Logger.info PaymentRejectedEvent.new("abcd1234", 100, "Card expired")
- #
- # @example Using typed Event classes
- # # Event implementation is left to you. Events should be simple classes.
- # # The only requirement is that it responds to #to_timber_event and return the
- # # appropriate Timber::Events::* type.
- # class Event
- # def to_hash
- # hash = {}
- # instance_variables.each { |var| hash[var.to_s.delete("@")] = instance_variable_get(var) }
- # hash
- # end
- # alias to_h to_hash
- #
- # def to_timber_event
- # Timber::Events::Custom.new(type: type, message: message, data: to_hash)
- # end
- #
- # def message; raise NotImplementedError.new; end
- # def type; raise NotImplementedError.new; end
- # end
- #
- # class PaymentRejectedEvent < Event
- # attr_accessor :customer_id, :amount
- # def initialize(customer_id, amount)
- # @customer_id = customer_id
- # @amount = amount
- # end
- # def message; "Payment rejected for customer #{customer_id}"; end
- # def type; :payment_rejected_event; end
- # end
- #
- # Logger.info PymentRejectedEvent.new("abcd1234", 100)
- #
class Logger < ::Logger
# @private
class Formatter
# Formatters get the formatted level from the logger.
@@ -207,20 +158,18 @@
# @example Logging to a file and the Timber HTTP device (multiple log devices)
# http_device = Timber::LogDevices::HTTP.new("my-timber-api-key")
# file_device = Logger::LogDevice.new("path/to/file.log")
# logger = Timber::Logger.new(http_device, file_device)
def initialize(*io_devices)
- io_device = \
- if io_devices.size == 0
- raise ArgumentError.new("At least one IO device must be provided when instantiating " +
- "a Timber::Logger. Ex: Timber::Logger.new(STDOUT).")
- elsif io_devices.size > 1
- LogDevices::Multi.new(io_devices)
- else
- io_devices.first
- end
+ if io_devices.size == 0
+ raise ArgumentError.new("At least one IO device must be provided when instantiating " +
+ "a Timber::Logger. Ex: Timber::Logger.new(STDOUT).")
+ end
+ @extra_loggers = io_devices[1..-1].collect { |io_device| self.class.new(io_device) }
+ io_device = io_devices[0]
+
super(io_device)
# Ensure we sync STDOUT to avoid buffering
if io_device.respond_to?(:"sync=")
io_device.sync = true
@@ -273,9 +222,14 @@
# Patch to ensure that the {#level} method is used instead of `@level`.
# This is required because of Rails' monkey patching on Logger via `::LoggerSilence`.
def add(severity, message = nil, progname = nil, &block)
return true if @logdev.nil? || (severity || UNKNOWN) < level
+
+ @extra_loggers.each do |logger|
+ logger.add(severity, message, progname, &block)
+ end
+
super
end
# Backwards compatibility with older ActiveSupport::Logger versions
Logger::Severity.constants.each do |severity|
\ No newline at end of file