lumberjack 1.2.7 → 1.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +114 -56
- data/README.md +6 -5
- data/VERSION +1 -1
- data/lib/lumberjack/context.rb +13 -0
- data/lib/lumberjack/device/date_rolling_log_file.rb +16 -7
- data/lib/lumberjack/device/log_file.rb +13 -6
- data/lib/lumberjack/device/multi.rb +7 -6
- data/lib/lumberjack/device/null.rb +1 -1
- data/lib/lumberjack/device/rolling_log_file.rb +44 -20
- data/lib/lumberjack/device/size_rolling_log_file.rb +9 -9
- data/lib/lumberjack/device/writer.rb +32 -12
- data/lib/lumberjack/device.rb +27 -12
- data/lib/lumberjack/formatter/date_time_formatter.rb +3 -3
- data/lib/lumberjack/formatter/exception_formatter.rb +2 -2
- data/lib/lumberjack/formatter/id_formatter.rb +3 -2
- data/lib/lumberjack/formatter/pretty_print_formatter.rb +6 -4
- data/lib/lumberjack/formatter/structured_formatter.rb +2 -0
- data/lib/lumberjack/formatter/truncate_formatter.rb +27 -0
- data/lib/lumberjack/formatter.rb +69 -23
- data/lib/lumberjack/log_entry.rb +16 -10
- data/lib/lumberjack/logger.rb +167 -29
- data/lib/lumberjack/rack/request_id.rb +1 -1
- data/lib/lumberjack/rack/unit_of_work.rb +1 -1
- data/lib/lumberjack/rack.rb +3 -3
- data/lib/lumberjack/severity.rb +9 -2
- data/lib/lumberjack/tag_formatter.rb +20 -3
- data/lib/lumberjack/tagged_logger_support.rb +1 -2
- data/lib/lumberjack/tagged_logging.rb +1 -1
- data/lib/lumberjack/tags.rb +7 -1
- data/lib/lumberjack/template.rb +15 -3
- data/lib/lumberjack.rb +51 -30
- data/lumberjack.gemspec +11 -14
- metadata +9 -50
| @@ -8,30 +8,30 @@ module Lumberjack | |
| 8 8 | 
             
                # production.log.1, then production.log.2, etc.
         | 
| 9 9 | 
             
                class SizeRollingLogFile < RollingLogFile
         | 
| 10 10 | 
             
                  attr_reader :max_size
         | 
| 11 | 
            -
             | 
| 11 | 
            +
             | 
| 12 12 | 
             
                  # Create an new log device to the specified file. The maximum size of the log file is specified with
         | 
| 13 13 | 
             
                  # the :max_size option. The unit can also be specified: "32K", "100M", "2G" are all valid.
         | 
| 14 14 | 
             
                  def initialize(path, options = {})
         | 
| 15 15 | 
             
                    @manual = options[:manual]
         | 
| 16 16 | 
             
                    @max_size = options[:max_size]
         | 
| 17 17 | 
             
                    if @max_size.is_a?(String)
         | 
| 18 | 
            -
                      if @max_size | 
| 18 | 
            +
                      if @max_size =~ /^(\d+(\.\d+)?)([KMG])?$/i
         | 
| 19 19 | 
             
                        @max_size = $~[1].to_f
         | 
| 20 20 | 
             
                        units = $~[3].to_s.upcase
         | 
| 21 21 | 
             
                        case units
         | 
| 22 22 | 
             
                        when "K"
         | 
| 23 23 | 
             
                          @max_size *= 1024
         | 
| 24 24 | 
             
                        when "M"
         | 
| 25 | 
            -
                          @max_size *= 1024 | 
| 25 | 
            +
                          @max_size *= 1024**2
         | 
| 26 26 | 
             
                        when "G"
         | 
| 27 | 
            -
                          @max_size *= 1024 | 
| 27 | 
            +
                          @max_size *= 1024**3
         | 
| 28 28 | 
             
                        end
         | 
| 29 29 | 
             
                        @max_size = @max_size.round
         | 
| 30 30 | 
             
                      else
         | 
| 31 31 | 
             
                        raise ArgumentError.new("illegal value for :max_size (#{@max_size})")
         | 
| 32 32 | 
             
                      end
         | 
| 33 33 | 
             
                    end
         | 
| 34 | 
            -
             | 
| 34 | 
            +
             | 
| 35 35 | 
             
                    super
         | 
| 36 36 | 
             
                  end
         | 
| 37 37 |  | 
| @@ -44,15 +44,15 @@ module Lumberjack | |
| 44 44 | 
             
                  rescue SystemCallError
         | 
| 45 45 | 
             
                    false
         | 
| 46 46 | 
             
                  end
         | 
| 47 | 
            -
             | 
| 47 | 
            +
             | 
| 48 48 | 
             
                  protected
         | 
| 49 | 
            -
             | 
| 49 | 
            +
             | 
| 50 50 | 
             
                  # Calculate the next archive file name extension.
         | 
| 51 51 | 
             
                  def next_archive_number # :nodoc:
         | 
| 52 52 | 
             
                    max = 0
         | 
| 53 53 | 
             
                    Dir.glob("#{path}.*").each do |filename|
         | 
| 54 | 
            -
                      if  | 
| 55 | 
            -
                        suffix = filename.split( | 
| 54 | 
            +
                      if /\.\d+\z/ =~ filename
         | 
| 55 | 
            +
                        suffix = filename.split(".").last.to_i
         | 
| 56 56 | 
             
                        max = suffix if suffix > max
         | 
| 57 57 | 
             
                      end
         | 
| 58 58 | 
             
                    end
         | 
| @@ -60,6 +60,9 @@ module Lumberjack | |
| 60 60 | 
             
                  # work id will only appear if it is present.
         | 
| 61 61 | 
             
                  #
         | 
| 62 62 | 
             
                  # The size of the internal buffer in bytes can be set by providing :buffer_size (defaults to 32K).
         | 
| 63 | 
            +
                  #
         | 
| 64 | 
            +
                  # @param [IO] stream The stream to write log entries to.
         | 
| 65 | 
            +
                  # @param [Hash] options The options for the device.
         | 
| 63 66 | 
             
                  def initialize(stream, options = {})
         | 
| 64 67 | 
             
                    @lock = Mutex.new
         | 
| 65 68 | 
             
                    @stream = stream
         | 
| @@ -71,18 +74,24 @@ module Lumberjack | |
| 71 74 | 
             
                      @template = template
         | 
| 72 75 | 
             
                    else
         | 
| 73 76 | 
             
                      additional_lines = (options[:additional_lines] || DEFAULT_ADDITIONAL_LINES_TEMPLATE)
         | 
| 74 | 
            -
                      @template = Template.new(template, : | 
| 77 | 
            +
                      @template = Template.new(template, additional_lines: additional_lines, time_format: options[:time_format])
         | 
| 75 78 | 
             
                    end
         | 
| 76 79 | 
             
                  end
         | 
| 77 80 |  | 
| 78 81 | 
             
                  # Set the buffer size in bytes. The device will only be physically written to when the buffer size
         | 
| 79 82 | 
             
                  # is exceeded.
         | 
| 83 | 
            +
                  #
         | 
| 84 | 
            +
                  # @param [Integer] value The size of the buffer in bytes.
         | 
| 85 | 
            +
                  # @return [void]
         | 
| 80 86 | 
             
                  def buffer_size=(value)
         | 
| 81 87 | 
             
                    @buffer_size = value
         | 
| 82 88 | 
             
                    flush
         | 
| 83 89 | 
             
                  end
         | 
| 84 90 |  | 
| 85 91 | 
             
                  # Write an entry to the stream. The entry will be converted into a string using the defined template.
         | 
| 92 | 
            +
                  #
         | 
| 93 | 
            +
                  # @param [LogEntry, String] entry The entry to write to the stream.
         | 
| 94 | 
            +
                  # @return [void]
         | 
| 86 95 | 
             
                  def write(entry)
         | 
| 87 96 | 
             
                    string = (entry.is_a?(LogEntry) ? @template.call(entry) : entry)
         | 
| 88 97 | 
             
                    return if string.nil?
         | 
| @@ -105,12 +114,16 @@ module Lumberjack | |
| 105 114 | 
             
                  end
         | 
| 106 115 |  | 
| 107 116 | 
             
                  # Close the underlying stream.
         | 
| 117 | 
            +
                  #
         | 
| 118 | 
            +
                  # @return [void]
         | 
| 108 119 | 
             
                  def close
         | 
| 109 120 | 
             
                    flush
         | 
| 110 121 | 
             
                    stream.close
         | 
| 111 122 | 
             
                  end
         | 
| 112 123 |  | 
| 113 124 | 
             
                  # Flush the underlying stream.
         | 
| 125 | 
            +
                  #
         | 
| 126 | 
            +
                  # @return [void]
         | 
| 114 127 | 
             
                  def flush
         | 
| 115 128 | 
             
                    lines = nil
         | 
| 116 129 | 
             
                    @lock.synchronize do
         | 
| @@ -120,10 +133,17 @@ module Lumberjack | |
| 120 133 | 
             
                    write_to_stream(lines) if lines
         | 
| 121 134 | 
             
                  end
         | 
| 122 135 |  | 
| 136 | 
            +
                  # Get the datetime format.
         | 
| 137 | 
            +
                  #
         | 
| 138 | 
            +
                  # @return [String] The datetime format.
         | 
| 123 139 | 
             
                  def datetime_format
         | 
| 124 140 | 
             
                    @template.datetime_format if @template.respond_to?(:datetime_format)
         | 
| 125 141 | 
             
                  end
         | 
| 126 142 |  | 
| 143 | 
            +
                  # Set the datetime format.
         | 
| 144 | 
            +
                  #
         | 
| 145 | 
            +
                  # @param [String] format The datetime format.
         | 
| 146 | 
            +
                  # @return [void]
         | 
| 127 147 | 
             
                  def datetime_format=(format)
         | 
| 128 148 | 
             
                    if @template.respond_to?(:datetime_format=)
         | 
| 129 149 | 
             
                      @template.datetime_format = format
         | 
| @@ -133,14 +153,10 @@ module Lumberjack | |
| 133 153 | 
             
                  protected
         | 
| 134 154 |  | 
| 135 155 | 
             
                  # Set the underlying stream.
         | 
| 136 | 
            -
                   | 
| 137 | 
            -
                    @stream = stream
         | 
| 138 | 
            -
                  end
         | 
| 156 | 
            +
                  attr_writer :stream
         | 
| 139 157 |  | 
| 140 158 | 
             
                  # Get the underlying stream.
         | 
| 141 | 
            -
                   | 
| 142 | 
            -
                    @stream
         | 
| 143 | 
            -
                  end
         | 
| 159 | 
            +
                  attr_reader :stream
         | 
| 144 160 |  | 
| 145 161 | 
             
                  private
         | 
| 146 162 |  | 
| @@ -149,10 +165,10 @@ module Lumberjack | |
| 149 165 | 
             
                    lines = lines.first if lines.is_a?(Array) && lines.size == 1
         | 
| 150 166 |  | 
| 151 167 | 
             
                    out = nil
         | 
| 152 | 
            -
                    if lines.is_a?(Array)
         | 
| 153 | 
            -
                       | 
| 168 | 
            +
                    out = if lines.is_a?(Array)
         | 
| 169 | 
            +
                      "#{lines.join(Lumberjack::LINE_SEPARATOR)}#{Lumberjack::LINE_SEPARATOR}"
         | 
| 154 170 | 
             
                    else
         | 
| 155 | 
            -
                       | 
| 171 | 
            +
                      "#{lines}#{Lumberjack::LINE_SEPARATOR}"
         | 
| 156 172 | 
             
                    end
         | 
| 157 173 |  | 
| 158 174 | 
             
                    begin
         | 
| @@ -170,9 +186,13 @@ module Lumberjack | |
| 170 186 | 
             
                          end
         | 
| 171 187 | 
             
                        end
         | 
| 172 188 | 
             
                      end
         | 
| 173 | 
            -
                       | 
| 189 | 
            +
                      begin
         | 
| 190 | 
            +
                        stream.flush
         | 
| 191 | 
            +
                      rescue
         | 
| 192 | 
            +
                        nil
         | 
| 193 | 
            +
                      end
         | 
| 174 194 | 
             
                    rescue => e
         | 
| 175 | 
            -
                      $stderr.write("#{e.class.name}: #{e.message}#{ | 
| 195 | 
            +
                      $stderr.write("#{e.class.name}: #{e.message}#{" at " + e.backtrace.first if e.backtrace}")
         | 
| 176 196 | 
             
                      $stderr.write(out)
         | 
| 177 197 | 
             
                      $stderr.flush
         | 
| 178 198 | 
             
                    end
         | 
    
        data/lib/lumberjack/device.rb
    CHANGED
    
    | @@ -4,38 +4,53 @@ module Lumberjack | |
| 4 4 | 
             
              # This is an abstract class for logging devices. Subclasses must implement the +write+ method and
         | 
| 5 5 | 
             
              # may implement the +close+ and +flush+ methods if applicable.
         | 
| 6 6 | 
             
              class Device
         | 
| 7 | 
            -
                require_relative "device/writer | 
| 8 | 
            -
                require_relative "device/log_file | 
| 9 | 
            -
                require_relative "device/rolling_log_file | 
| 10 | 
            -
                require_relative "device/date_rolling_log_file | 
| 11 | 
            -
                require_relative "device/size_rolling_log_file | 
| 12 | 
            -
                require_relative "device/multi | 
| 13 | 
            -
                require_relative "device/null | 
| 7 | 
            +
                require_relative "device/writer"
         | 
| 8 | 
            +
                require_relative "device/log_file"
         | 
| 9 | 
            +
                require_relative "device/rolling_log_file"
         | 
| 10 | 
            +
                require_relative "device/date_rolling_log_file"
         | 
| 11 | 
            +
                require_relative "device/size_rolling_log_file"
         | 
| 12 | 
            +
                require_relative "device/multi"
         | 
| 13 | 
            +
                require_relative "device/null"
         | 
| 14 14 |  | 
| 15 15 | 
             
                # Subclasses must implement this method to write a LogEntry.
         | 
| 16 | 
            +
                #
         | 
| 17 | 
            +
                # @param [Lumberjack::LogEntry] entry The entry to write.
         | 
| 18 | 
            +
                # @return [void]
         | 
| 16 19 | 
             
                def write(entry)
         | 
| 17 20 | 
             
                  raise NotImplementedError
         | 
| 18 21 | 
             
                end
         | 
| 19 | 
            -
             | 
| 22 | 
            +
             | 
| 20 23 | 
             
                # Subclasses may implement this method to close the device.
         | 
| 24 | 
            +
                #
         | 
| 25 | 
            +
                # @return [void]
         | 
| 21 26 | 
             
                def close
         | 
| 22 27 | 
             
                  flush
         | 
| 23 28 | 
             
                end
         | 
| 24 | 
            -
             | 
| 29 | 
            +
             | 
| 25 30 | 
             
                # Subclasses may implement this method to reopen the device.
         | 
| 31 | 
            +
                #
         | 
| 32 | 
            +
                # @param [Object] logdev The log device to use.
         | 
| 33 | 
            +
                # @return [void]
         | 
| 26 34 | 
             
                def reopen(logdev = nil)
         | 
| 27 35 | 
             
                  flush
         | 
| 28 36 | 
             
                end
         | 
| 29 | 
            -
             | 
| 37 | 
            +
             | 
| 30 38 | 
             
                # Subclasses may implement this method to flush any buffers used by the device.
         | 
| 39 | 
            +
                #
         | 
| 40 | 
            +
                # @return [void]
         | 
| 31 41 | 
             
                def flush
         | 
| 32 42 | 
             
                end
         | 
| 33 | 
            -
             | 
| 43 | 
            +
             | 
| 34 44 | 
             
                # Subclasses may implement this method to get the format for log timestamps.
         | 
| 45 | 
            +
                #
         | 
| 46 | 
            +
                # @return [String] The format for log timestamps.
         | 
| 35 47 | 
             
                def datetime_format
         | 
| 36 48 | 
             
                end
         | 
| 37 | 
            -
             | 
| 49 | 
            +
             | 
| 38 50 | 
             
                # Subclasses may implement this method to set a format for log timestamps.
         | 
| 51 | 
            +
                #
         | 
| 52 | 
            +
                # @param [String] format The format for log timestamps.
         | 
| 53 | 
            +
                # @return [void]
         | 
| 39 54 | 
             
                def datetime_format=(format)
         | 
| 40 55 | 
             
                end
         | 
| 41 56 | 
             
              end
         | 
| @@ -5,13 +5,13 @@ module Lumberjack | |
| 5 5 | 
             
                # Format a Date, Time, or DateTime object. If you don't specify a format in the constructor,
         | 
| 6 6 | 
             
                # it will use the ISO-8601 format.
         | 
| 7 7 | 
             
                class DateTimeFormatter
         | 
| 8 | 
            -
                        
         | 
| 9 8 | 
             
                  attr_reader :format
         | 
| 10 | 
            -
             | 
| 9 | 
            +
             | 
| 10 | 
            +
                  # @param [String] format The format to use when formatting the date/time object.
         | 
| 11 11 | 
             
                  def initialize(format = nil)
         | 
| 12 12 | 
             
                    @format = format.dup.to_s.freeze unless format.nil?
         | 
| 13 13 | 
             
                  end
         | 
| 14 | 
            -
             | 
| 14 | 
            +
             | 
| 15 15 | 
             
                  def call(obj)
         | 
| 16 16 | 
             
                    if @format && obj.respond_to?(:strftime)
         | 
| 17 17 | 
             
                      obj.strftime(@format)
         | 
| @@ -7,9 +7,10 @@ module Lumberjack | |
| 7 7 | 
             
                # passed to this object and the returned array is what will be logged. You can
         | 
| 8 8 | 
             
                # use this to clean out superfluous lines.
         | 
| 9 9 | 
             
                class ExceptionFormatter
         | 
| 10 | 
            -
             | 
| 11 10 | 
             
                  attr_accessor :backtrace_cleaner
         | 
| 12 11 |  | 
| 12 | 
            +
                  # @param [#call] backtrace_cleaner An object that responds to `call` and takes
         | 
| 13 | 
            +
                  #   an array of strings (the backtrace) and returns an array of strings (the
         | 
| 13 14 | 
             
                  def initialize(backtrace_cleaner = nil)
         | 
| 14 15 | 
             
                    self.backtrace_cleaner = backtrace_cleaner
         | 
| 15 16 | 
             
                  end
         | 
| @@ -33,7 +34,6 @@ module Lumberjack | |
| 33 34 | 
             
                      trace
         | 
| 34 35 | 
             
                    end
         | 
| 35 36 | 
             
                  end
         | 
| 36 | 
            -
             | 
| 37 37 | 
             
                end
         | 
| 38 38 | 
             
              end
         | 
| 39 39 | 
             
            end
         | 
| @@ -6,14 +6,15 @@ module Lumberjack | |
| 6 6 | 
             
                # as a default formatter for objects pulled from a data store. By default it will use :id as the
         | 
| 7 7 | 
             
                # id attribute.
         | 
| 8 8 | 
             
                class IdFormatter
         | 
| 9 | 
            +
                  # @param [Symbol, String] id_attribute The attribute to use as the id.
         | 
| 9 10 | 
             
                  def initialize(id_attribute = :id)
         | 
| 10 11 | 
             
                    @id_attribute = id_attribute
         | 
| 11 12 | 
             
                  end
         | 
| 12 | 
            -
             | 
| 13 | 
            +
             | 
| 13 14 | 
             
                  def call(obj)
         | 
| 14 15 | 
             
                    if obj.respond_to?(@id_attribute)
         | 
| 15 16 | 
             
                      id = obj.send(@id_attribute)
         | 
| 16 | 
            -
                      { | 
| 17 | 
            +
                      {"class" => obj.class.name, "id" => id}
         | 
| 17 18 | 
             
                    else
         | 
| 18 19 | 
             
                      obj.to_s
         | 
| 19 20 | 
             
                    end
         | 
| @@ -1,20 +1,22 @@ | |
| 1 1 | 
             
            # frozen_string_literals: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require  | 
| 4 | 
            -
            require  | 
| 3 | 
            +
            require "pp"
         | 
| 4 | 
            +
            require "stringio"
         | 
| 5 5 |  | 
| 6 6 | 
             
            module Lumberjack
         | 
| 7 7 | 
             
              class Formatter
         | 
| 8 8 | 
             
                # Format an object with it's pretty print method.
         | 
| 9 9 | 
             
                class PrettyPrintFormatter
         | 
| 10 10 | 
             
                  attr_accessor :width
         | 
| 11 | 
            -
             | 
| 11 | 
            +
             | 
| 12 12 | 
             
                  # Create a new formatter. The maximum width of the message can be specified with the width
         | 
| 13 13 | 
             
                  # parameter (defaults to 79 characters).
         | 
| 14 | 
            +
                  #
         | 
| 15 | 
            +
                  # @param [Integer] width The maximum width of the message.
         | 
| 14 16 | 
             
                  def initialize(width = 79)
         | 
| 15 17 | 
             
                    @width = width
         | 
| 16 18 | 
             
                  end
         | 
| 17 | 
            -
             | 
| 19 | 
            +
             | 
| 18 20 | 
             
                  def call(obj)
         | 
| 19 21 | 
             
                    s = StringIO.new
         | 
| 20 22 | 
             
                    PP.pp(obj, s)
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # frozen_string_literals: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Lumberjack
         | 
| 4 | 
            +
              class Formatter
         | 
| 5 | 
            +
                # Truncate a string object to a specific length. This is useful
         | 
| 6 | 
            +
                # for formatting messages when there is a limit on the number of
         | 
| 7 | 
            +
                # characters that can be logged per message. This formatter should
         | 
| 8 | 
            +
                # only be used when necessary since it is a lossy formatter.
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                # When a string is truncated, it will have a unicode ellipsis
         | 
| 11 | 
            +
                # character (U+2026) appended to the end of the string.
         | 
| 12 | 
            +
                class TruncateFormatter
         | 
| 13 | 
            +
                  # @param [Integer] length The maximum length of the string (defaults to 32K)
         | 
| 14 | 
            +
                  def initialize(length = 32768)
         | 
| 15 | 
            +
                    @length = length
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def call(obj)
         | 
| 19 | 
            +
                    if obj.is_a?(String) && obj.length > @length
         | 
| 20 | 
            +
                      "#{obj[0, @length - 1]}…"
         | 
| 21 | 
            +
                    else
         | 
| 22 | 
            +
                      obj
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
    
        data/lib/lumberjack/formatter.rb
    CHANGED
    
    | @@ -12,25 +12,28 @@ module Lumberjack | |
| 12 12 | 
             
              #
         | 
| 13 13 | 
             
              # Enumerable objects (including Hash and Array) will call the formatter recursively for each element.
         | 
| 14 14 | 
             
              class Formatter
         | 
| 15 | 
            -
                require_relative "formatter/date_time_formatter | 
| 16 | 
            -
                require_relative "formatter/exception_formatter | 
| 17 | 
            -
                require_relative "formatter/id_formatter | 
| 18 | 
            -
                require_relative "formatter/inspect_formatter | 
| 19 | 
            -
                require_relative "formatter/object_formatter | 
| 20 | 
            -
                require_relative "formatter/pretty_print_formatter | 
| 21 | 
            -
                require_relative "formatter/string_formatter | 
| 22 | 
            -
                require_relative "formatter/strip_formatter | 
| 23 | 
            -
                require_relative "formatter/structured_formatter | 
| 15 | 
            +
                require_relative "formatter/date_time_formatter"
         | 
| 16 | 
            +
                require_relative "formatter/exception_formatter"
         | 
| 17 | 
            +
                require_relative "formatter/id_formatter"
         | 
| 18 | 
            +
                require_relative "formatter/inspect_formatter"
         | 
| 19 | 
            +
                require_relative "formatter/object_formatter"
         | 
| 20 | 
            +
                require_relative "formatter/pretty_print_formatter"
         | 
| 21 | 
            +
                require_relative "formatter/string_formatter"
         | 
| 22 | 
            +
                require_relative "formatter/strip_formatter"
         | 
| 23 | 
            +
                require_relative "formatter/structured_formatter"
         | 
| 24 | 
            +
                require_relative "formatter/truncate_formatter"
         | 
| 24 25 |  | 
| 25 26 | 
             
                class << self
         | 
| 26 27 | 
             
                  # Returns a new empty formatter with no mapping. For historical reasons, a formatter
         | 
| 27 28 | 
             
                  # is initialized with mappings to help output objects as strings. This will return one
         | 
| 28 29 | 
             
                  # without the default mappings.
         | 
| 30 | 
            +
                  #
         | 
| 31 | 
            +
                  # @return [Lumberjack::Formatter] a new empty formatter
         | 
| 29 32 | 
             
                  def empty
         | 
| 30 33 | 
             
                    new.clear
         | 
| 31 34 | 
             
                  end
         | 
| 32 35 | 
             
                end
         | 
| 33 | 
            -
             | 
| 36 | 
            +
             | 
| 34 37 | 
             
                def initialize
         | 
| 35 38 | 
             
                  @class_formatters = {}
         | 
| 36 39 | 
             
                  @module_formatters = {}
         | 
| @@ -45,7 +48,17 @@ module Lumberjack | |
| 45 48 | 
             
                # that responds to the +call+ method or as a symbol representing one of the predefined
         | 
| 46 49 | 
             
                # formatters, or as a block to the method call.
         | 
| 47 50 | 
             
                #
         | 
| 48 | 
            -
                # The predefined formatters are: | 
| 51 | 
            +
                # The predefined formatters are:
         | 
| 52 | 
            +
                #   - :date_time
         | 
| 53 | 
            +
                #   - :exception
         | 
| 54 | 
            +
                #   - :id
         | 
| 55 | 
            +
                #   - :inspect
         | 
| 56 | 
            +
                #   - :object
         | 
| 57 | 
            +
                #   - :pretty_print
         | 
| 58 | 
            +
                #   - :string
         | 
| 59 | 
            +
                #   - :strip
         | 
| 60 | 
            +
                #   - :structured
         | 
| 61 | 
            +
                #   - :truncate
         | 
| 49 62 | 
             
                #
         | 
| 50 63 | 
             
                # You can add multiple classes at once by passing an array of classes.
         | 
| 51 64 | 
             
                #
         | 
| @@ -53,7 +66,18 @@ module Lumberjack | |
| 53 66 | 
             
                # help avoid loading dependency issues. This applies only to classes; modules cannot be
         | 
| 54 67 | 
             
                # passed in as strings.
         | 
| 55 68 | 
             
                #
         | 
| 56 | 
            -
                #  | 
| 69 | 
            +
                # @param [Class, Module, String, Array<Class, Module, String>] klass The class or module to add a formatter for.
         | 
| 70 | 
            +
                # @param [Symbol, Class, String, #call] formatter The formatter to use for the class.
         | 
| 71 | 
            +
                #   If a symbol is passed in, it will be used to load one of the predefined formatters.
         | 
| 72 | 
            +
                #   If a class is passed in, it will be initialized with the args passed in.
         | 
| 73 | 
            +
                #   Otherwise, the object will be used as the formatter and must respond to call method.
         | 
| 74 | 
            +
                # @param [Array] args Arguments to pass to the formatter when it is initialized.
         | 
| 75 | 
            +
                # @yield [obj] A block that will be used as the formatter for the class.
         | 
| 76 | 
            +
                # @yieldparam [Object] obj The object to format.
         | 
| 77 | 
            +
                # @yieldreturn [String] The formatted string.
         | 
| 78 | 
            +
                # @return [self] Returns itself so that add statements can be chained together.
         | 
| 79 | 
            +
                #
         | 
| 80 | 
            +
                # @example
         | 
| 57 81 | 
             
                #
         | 
| 58 82 | 
             
                #   # Use a predefined formatter
         | 
| 59 83 | 
             
                #   formatter.add(MyClass, :pretty_print)
         | 
| @@ -66,18 +90,27 @@ module Lumberjack | |
| 66 90 | 
             
                #
         | 
| 67 91 | 
             
                #   # Add statements can be chained together
         | 
| 68 92 | 
             
                #   formatter.add(MyClass, :pretty_print).add(YourClass){|obj| obj.humanize}
         | 
| 69 | 
            -
                def add(klass, formatter = nil, &block)
         | 
| 93 | 
            +
                def add(klass, formatter = nil, *args, &block)
         | 
| 70 94 | 
             
                  formatter ||= block
         | 
| 71 95 | 
             
                  if formatter.nil?
         | 
| 72 96 | 
             
                    remove(klass)
         | 
| 73 97 | 
             
                  else
         | 
| 98 | 
            +
                    formatter_class_name = nil
         | 
| 74 99 | 
             
                    if formatter.is_a?(Symbol)
         | 
| 75 | 
            -
                      formatter_class_name = "#{formatter.to_s.gsub(/(^|_)([a-z])/){|m| $~[2].upcase}}Formatter"
         | 
| 76 | 
            -
             | 
| 100 | 
            +
                      formatter_class_name = "#{formatter.to_s.gsub(/(^|_)([a-z])/) { |m| $~[2].upcase }}Formatter"
         | 
| 101 | 
            +
                    elsif formatter.is_a?(String)
         | 
| 102 | 
            +
                      formatter_class_name = formatter
         | 
| 103 | 
            +
                    end
         | 
| 104 | 
            +
                    if formatter_class_name
         | 
| 105 | 
            +
                      formatter = Formatter.const_get(formatter_class_name)
         | 
| 77 106 | 
             
                    end
         | 
| 78 | 
            -
             | 
| 107 | 
            +
             | 
| 108 | 
            +
                    if formatter.is_a?(Class)
         | 
| 109 | 
            +
                      formatter = formatter.new(*args)
         | 
| 110 | 
            +
                    end
         | 
| 111 | 
            +
             | 
| 79 112 | 
             
                    Array(klass).each do |k|
         | 
| 80 | 
            -
                      if k. | 
| 113 | 
            +
                      if k.instance_of?(Module)
         | 
| 81 114 | 
             
                        @module_formatters[k] = formatter
         | 
| 82 115 | 
             
                      else
         | 
| 83 116 | 
             
                        k = k.name if k.is_a?(Class)
         | 
| @@ -95,9 +128,12 @@ module Lumberjack | |
| 95 128 | 
             
                # You can also pass class names as strings instead of the classes themselves. This can
         | 
| 96 129 | 
             
                # help avoid loading dependency issues. This applies only to classes; modules cannot be
         | 
| 97 130 | 
             
                # passed in as strings.
         | 
| 131 | 
            +
                #
         | 
| 132 | 
            +
                # @param [Class, Module, String, Array<Class, Module, String>] klass The class or module to remove the formatters for.
         | 
| 133 | 
            +
                # @return [self] Returns itself so that remove statements can be chained together.
         | 
| 98 134 | 
             
                def remove(klass)
         | 
| 99 135 | 
             
                  Array(klass).each do |k|
         | 
| 100 | 
            -
                    if k. | 
| 136 | 
            +
                    if k.instance_of?(Module)
         | 
| 101 137 | 
             
                      @module_formatters.delete(k)
         | 
| 102 138 | 
             
                    else
         | 
| 103 139 | 
             
                      k = k.name if k.is_a?(Class)
         | 
| @@ -106,18 +142,23 @@ module Lumberjack | |
| 106 142 | 
             
                  end
         | 
| 107 143 | 
             
                  self
         | 
| 108 144 | 
             
                end
         | 
| 109 | 
            -
             | 
| 145 | 
            +
             | 
| 110 146 | 
             
                # Remove all formatters including the default formatter. Can be chained to add method calls.
         | 
| 147 | 
            +
                #
         | 
| 148 | 
            +
                # @return [self] Returns itself so that clear statements can be chained together.
         | 
| 111 149 | 
             
                def clear
         | 
| 112 150 | 
             
                  @class_formatters.clear
         | 
| 113 151 | 
             
                  @module_formatters.clear
         | 
| 114 152 | 
             
                  self
         | 
| 115 153 | 
             
                end
         | 
| 116 154 |  | 
| 117 | 
            -
                # Format a message object  | 
| 155 | 
            +
                # Format a message object by applying all formatters attached to it.
         | 
| 156 | 
            +
                #
         | 
| 157 | 
            +
                # @param [Object] message The message object to format.
         | 
| 158 | 
            +
                # @return [Object] The formatted object.
         | 
| 118 159 | 
             
                def format(message)
         | 
| 119 160 | 
             
                  formatter = formatter_for(message.class)
         | 
| 120 | 
            -
                  if formatter | 
| 161 | 
            +
                  if formatter&.respond_to?(:call)
         | 
| 121 162 | 
             
                    formatter.call(message)
         | 
| 122 163 | 
             
                  else
         | 
| 123 164 | 
             
                    message
         | 
| @@ -126,6 +167,11 @@ module Lumberjack | |
| 126 167 |  | 
| 127 168 | 
             
                # Compatibility with the Logger::Formatter signature. This method will just convert the message
         | 
| 128 169 | 
             
                # object to a string and ignores the other parameters.
         | 
| 170 | 
            +
                #
         | 
| 171 | 
            +
                # @param [Integer, String, Symbol] severity The severity of the message.
         | 
| 172 | 
            +
                # @param [Time] timestamp The time the message was logged.
         | 
| 173 | 
            +
                # @param [String] progname The name of the program logging the message.
         | 
| 174 | 
            +
                # @param [Object] msg The message object to format.
         | 
| 129 175 | 
             
                def call(severity, timestamp, progname, msg)
         | 
| 130 176 | 
             
                  "#{format(msg)}#{Lumberjack::LINE_SEPARATOR}"
         | 
| 131 177 | 
             
                end
         | 
| @@ -133,9 +179,9 @@ module Lumberjack | |
| 133 179 | 
             
                private
         | 
| 134 180 |  | 
| 135 181 | 
             
                # Find the formatter for a class by looking it up using the class hierarchy.
         | 
| 136 | 
            -
                def formatter_for(klass)  | 
| 182 | 
            +
                def formatter_for(klass) # :nodoc:
         | 
| 137 183 | 
             
                  check_modules = true
         | 
| 138 | 
            -
                   | 
| 184 | 
            +
                  until klass.nil?
         | 
| 139 185 | 
             
                    formatter = @class_formatters[klass.name]
         | 
| 140 186 | 
             
                    return formatter if formatter
         | 
| 141 187 |  | 
    
        data/lib/lumberjack/log_entry.rb
    CHANGED
    
    | @@ -10,6 +10,14 @@ module Lumberjack | |
| 10 10 |  | 
| 11 11 | 
             
                UNIT_OF_WORK_ID = "unit_of_work_id"
         | 
| 12 12 |  | 
| 13 | 
            +
                # Create a new log entry.
         | 
| 14 | 
            +
                #
         | 
| 15 | 
            +
                # @param [Time] time The time the log entry was created.
         | 
| 16 | 
            +
                # @param [Integer, String] severity The severity of the log entry.
         | 
| 17 | 
            +
                # @param [String] message The message to log.
         | 
| 18 | 
            +
                # @param [String] progname The name of the program that created the log entry.
         | 
| 19 | 
            +
                # @param [Integer] pid The process id of the program that created the log entry.
         | 
| 20 | 
            +
                # @param [Hash] tags A hash of tags to associate with the log entry.
         | 
| 13 21 | 
             
                def initialize(time, severity, message, progname, pid, tags)
         | 
| 14 22 | 
             
                  @time = time
         | 
| 15 23 | 
             
                  @severity = (severity.is_a?(Integer) ? severity : Severity.label_to_level(severity))
         | 
| @@ -17,10 +25,10 @@ module Lumberjack | |
| 17 25 | 
             
                  @progname = progname
         | 
| 18 26 | 
             
                  @pid = pid
         | 
| 19 27 | 
             
                  # backward compatibility with 1.0 API where the last argument was the unit of work id
         | 
| 20 | 
            -
                  if tags.nil? || tags.is_a?(Hash)
         | 
| 21 | 
            -
                     | 
| 28 | 
            +
                  @tags = if tags.nil? || tags.is_a?(Hash)
         | 
| 29 | 
            +
                    tags
         | 
| 22 30 | 
             
                  else
         | 
| 23 | 
            -
                     | 
| 31 | 
            +
                    {UNIT_OF_WORK_ID => tags}
         | 
| 24 32 | 
             
                  end
         | 
| 25 33 | 
             
                end
         | 
| 26 34 |  | 
| @@ -29,7 +37,7 @@ module Lumberjack | |
| 29 37 | 
             
                end
         | 
| 30 38 |  | 
| 31 39 | 
             
                def to_s
         | 
| 32 | 
            -
                  "[#{time.strftime(TIME_FORMAT)}.#{(time.usec / 1000.0).round.to_s.rjust(3,  | 
| 40 | 
            +
                  "[#{time.strftime(TIME_FORMAT)}.#{(time.usec / 1000.0).round.to_s.rjust(3, "0")} #{severity_label} #{progname}(#{pid})#{tags_to_s}] #{message}"
         | 
| 33 41 | 
             
                end
         | 
| 34 42 |  | 
| 35 43 | 
             
                def inspect
         | 
| @@ -46,10 +54,10 @@ module Lumberjack | |
| 46 54 | 
             
                  if tags
         | 
| 47 55 | 
             
                    tags[UNIT_OF_WORK_ID] = value
         | 
| 48 56 | 
             
                  else
         | 
| 49 | 
            -
                    @tags = { | 
| 57 | 
            +
                    @tags = {UNIT_OF_WORK_ID => value}
         | 
| 50 58 | 
             
                  end
         | 
| 51 59 | 
             
                end
         | 
| 52 | 
            -
             | 
| 60 | 
            +
             | 
| 53 61 | 
             
                # Return the tag with the specified name.
         | 
| 54 62 | 
             
                def tag(name)
         | 
| 55 63 | 
             
                  tags[name.to_s] if tags
         | 
| @@ -58,10 +66,8 @@ module Lumberjack | |
| 58 66 | 
             
                private
         | 
| 59 67 |  | 
| 60 68 | 
             
                def tags_to_s
         | 
| 61 | 
            -
                  tags_string =  | 
| 62 | 
            -
                   | 
| 63 | 
            -
                    tags.each { |name, value| tags_string << " #{name}:#{value.inspect}" }
         | 
| 64 | 
            -
                  end
         | 
| 69 | 
            +
                  tags_string = ""
         | 
| 70 | 
            +
                  tags&.each { |name, value| tags_string << " #{name}:#{value.inspect}" }
         | 
| 65 71 | 
             
                  tags_string
         | 
| 66 72 | 
             
                end
         | 
| 67 73 | 
             
              end
         |