lumberjack 1.2.10 → 1.4.0

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.
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lumberjack
4
+ # A tag context provides an interface for manipulating a tag hash.
5
+ class TagContext
6
+ def initialize(tags)
7
+ @tags = tags
8
+ end
9
+
10
+ # Merge new tags into the context tags. Tag values will be flattened using dot notation
11
+ # on the keys. So `{ a: { b: 'c' } }` will become `{ 'a.b' => 'c' }`.
12
+ #
13
+ # If a block is given, then the tags will only be added for the duration of the block.
14
+ #
15
+ # @param tags [Hash] The tags to set.
16
+ # @return [void]
17
+ def tag(tags)
18
+ @tags.merge!(Utils.flatten_tags(tags))
19
+ end
20
+
21
+ # Get a tag value.
22
+ #
23
+ # @param name [String, Symbol] The tag key.
24
+ # @return [Object] The tag value.
25
+ def [](name)
26
+ return nil if @tags.empty?
27
+
28
+ name = name.to_s
29
+ return @tags[name] if @tags.include?(name)
30
+
31
+ # Check for partial matches in dot notation and return the hash representing the partial match.
32
+ prefix_key = "#{name}."
33
+ matching_tags = {}
34
+ @tags.each do |key, value|
35
+ if key.start_with?(prefix_key)
36
+ # Remove the prefix to get the relative key
37
+ relative_key = key[prefix_key.length..-1]
38
+ matching_tags[relative_key] = value
39
+ end
40
+ end
41
+
42
+ return nil if matching_tags.empty?
43
+ matching_tags
44
+ end
45
+
46
+ # Set a tag value.
47
+ #
48
+ # @param name [String, Symbol] The tag name.
49
+ # @param value [Object] The tag value.
50
+ # @return [void]
51
+ def []=(name, value)
52
+ if value.is_a?(Hash)
53
+ @tags.merge!(Utils.flatten_tags(name => value))
54
+ else
55
+ @tags[name.to_s] = value
56
+ end
57
+ end
58
+
59
+ # Remove tags from the context.
60
+ #
61
+ # @param names [Array<String, Symbol>] The tag names to remove.
62
+ # @return [void]
63
+ def delete(*names)
64
+ names.each do |name|
65
+ prefix_key = "#{name}."
66
+ @tags.delete_if { |k, _| k == name.to_s || k.start_with?(prefix_key) }
67
+ end
68
+ nil
69
+ end
70
+
71
+ # Return a copy of the tags as a hash.
72
+ #
73
+ # @return [Hash]
74
+ def to_h
75
+ @tags.dup
76
+ end
77
+ end
78
+ end
@@ -11,13 +11,14 @@ module Lumberjack
11
11
  class TagFormatter
12
12
  def initialize
13
13
  @formatters = {}
14
+ @class_formatters = {}
14
15
  @default_formatter = nil
15
16
  end
16
17
 
17
18
  # Add a default formatter applied to all tag values. This can either be a Lumberjack::Formatter
18
19
  # or an object that responds to `call` or a block.
19
20
  #
20
- # @param [Lumberjack::Formatter, #call, nil] formatter The formatter to use.
21
+ # @param formatter [Lumberjack::Formatter, #call, nil] The formatter to use.
21
22
  # If this is nil, then the block will be used as the formatter.
22
23
  # @return [Lumberjack::TagFormatter] self
23
24
  def default(formatter = nil, &block)
@@ -35,22 +36,37 @@ module Lumberjack
35
36
  self
36
37
  end
37
38
 
38
- # Add a formatter for specific tag names. This can either be a Lumberjack::Formatter
39
- # or an object that responds to `call` or a block. The default formatter will not be
40
- # applied.
39
+ # Add a formatter for specific tag names or object classes. This can either be a Lumberjack::Formatter
40
+ # or an object that responds to `call` or a block. The formatter will be applied if it matches either a tag name
41
+ # or if the tag value is an instance of a registered class. Tag name formatters will take precedence
42
+ # over class formatters. The default formatter will not be applied to a value if a tag formatter
43
+ # is applied to it.
41
44
  #
42
- # @param [String, Array<String>] names The tag names to apply the formatter to.
43
- # @param [Lumberjack::Formatter, #call, nil] formatter The formatter to use.
45
+ # Name formatters can be applied to nested hashes using dot syntax. For example, if you add a formatter
46
+ # for "foo.bar", it will be applied to the value of the "bar" key in the "foo" tag if that value is a hash.
47
+ #
48
+ # Class formatters will be applied recursively to nested hashes and arrays.
49
+ #
50
+ # @param names_or_classes [String, Module, Array<String, Module>] The tag names or object classes
51
+ # to apply the formatter to.
52
+ # @param formatter [Lumberjack::Formatter, #call, nil] The formatter to use.
44
53
  # If this is nil, then the block will be used as the formatter.
45
54
  # @return [Lumberjack::TagFormatter] self
46
- def add(names, formatter = nil, &block)
55
+ #
56
+ # @example
57
+ # tag_formatter.add("password", &:redact)
58
+ def add(names_or_classes, formatter = nil, &block)
47
59
  formatter ||= block
48
60
  formatter = dereference_formatter(formatter)
49
61
  if formatter.nil?
50
62
  remove(key)
51
63
  else
52
- Array(names).each do |name|
53
- @formatters[name.to_s] = formatter
64
+ Array(names_or_classes).each do |key|
65
+ if key.is_a?(Module)
66
+ @class_formatters[key] = formatter
67
+ else
68
+ @formatters[key.to_s] = formatter
69
+ end
54
70
  end
55
71
  end
56
72
  self
@@ -58,11 +74,15 @@ module Lumberjack
58
74
 
59
75
  # Remove formatters for specific tag names. The default formatter will still be applied.
60
76
  #
61
- # @param [String, Array<String>] names The tag names to remove the formatter from.
77
+ # @param names_or_classes [String, Module, Array<String, Module>] The tag names or classes to remove the formatter from.
62
78
  # @return [Lumberjack::TagFormatter] self
63
- def remove(names)
64
- Array(names).each do |name|
65
- @formatters.delete(name.to_s)
79
+ def remove(names_or_classes)
80
+ Array(names_or_classes).each do |key|
81
+ if key.is_a?(Module)
82
+ @class_formatters.delete(key)
83
+ else
84
+ @formatters.delete(key.to_s)
85
+ end
66
86
  end
67
87
  self
68
88
  end
@@ -78,28 +98,66 @@ module Lumberjack
78
98
 
79
99
  # Format a hash of tags using the formatters
80
100
  #
81
- # @param [Hash] tags The tags to format.
101
+ # @param tags [Hash] The tags to format.
82
102
  # @return [Hash] The formatted tags.
83
103
  def format(tags)
84
104
  return nil if tags.nil?
85
- if @default_formatter.nil? && (@formatters.empty? || (@formatters.keys & tags.keys).empty?)
86
- tags
105
+ if @default_formatter.nil? && @formatters.empty? && @class_formatters.empty?
106
+ return tags
107
+ end
108
+
109
+ formated_tags(tags)
110
+ end
111
+
112
+ private
113
+
114
+ def formated_tags(tags, skip_classes: nil, prefix: nil)
115
+ formatted = {}
116
+
117
+ tags.each do |name, value|
118
+ name = name.to_s
119
+ formatted[name] = formatted_tag_value(name, value, skip_classes: skip_classes, prefix: prefix)
120
+ end
121
+
122
+ formatted
123
+ end
124
+
125
+ def formatted_tag_value(name, value, skip_classes: nil, prefix: nil)
126
+ prefixed_name = prefix ? "#{prefix}#{name}" : name
127
+ using_class_formatter = false
128
+
129
+ formatter = @formatters[prefixed_name]
130
+ if formatter.nil? && (skip_classes.nil? || !skip_classes.include?(value.class))
131
+ formatter = class_formatter(value.class)
132
+ using_class_formatter = true if formatter
133
+ end
134
+
135
+ formatter ||= @default_formatter
136
+
137
+ formatted_value = if formatter.is_a?(Lumberjack::Formatter)
138
+ formatter.format(value)
139
+ elsif formatter.respond_to?(:call)
140
+ formatter.call(value)
87
141
  else
88
- formatted = {}
89
- tags.each do |name, value|
90
- formatter = (@formatters[name.to_s] || @default_formatter)
91
- if formatter.is_a?(Lumberjack::Formatter)
92
- value = formatter.format(value)
93
- elsif formatter.respond_to?(:call)
94
- value = formatter.call(value)
142
+ value
143
+ end
144
+
145
+ if formatted_value.is_a?(Enumerable)
146
+ skip_classes ||= []
147
+ skip_classes << value.class if using_class_formatter
148
+ sub_prefix = "#{prefixed_name}."
149
+
150
+ formatted_value = if formatted_value.is_a?(Hash)
151
+ formated_tags(formatted_value, skip_classes: skip_classes, prefix: sub_prefix)
152
+ else
153
+ formatted_value.collect do |item|
154
+ formatted_tag_value(nil, item, skip_classes: skip_classes, prefix: sub_prefix)
95
155
  end
96
- formatted[name.to_s] = value
97
156
  end
98
- formatted
99
157
  end
100
- end
101
158
 
102
- private
159
+ formatted_value
160
+ end
103
161
 
104
162
  def dereference_formatter(formatter)
105
163
  if formatter.is_a?(TaggedLoggerSupport::Formatter)
@@ -111,5 +169,22 @@ module Lumberjack
111
169
  formatter
112
170
  end
113
171
  end
172
+
173
+ def class_formatter(klass)
174
+ formatter = @class_formatters[klass]
175
+ return formatter if formatter
176
+
177
+ formatters = @class_formatters.select { |k, _| klass <= k }
178
+ return formatters.values.first if formatters.length <= 1
179
+
180
+ superclass = klass.superclass
181
+ while superclass
182
+ formatter = formatters[superclass]
183
+ return formatter if formatter
184
+ superclass = superclass.superclass
185
+ end
186
+
187
+ formatters.values.first
188
+ end
114
189
  end
115
190
  end
@@ -38,15 +38,19 @@ module Lumberjack
38
38
  end
39
39
 
40
40
  # Compatibility with ActiveSupport::TaggedLogging which only supports adding tags as strings.
41
- # If a tag looks like "key:value" or "key=value", it will be added as a key value pair.
42
- # Otherwise it will be appended to a list named "tagged".
41
+ # Tags will be added to the "tagged" key in the logger's tags hash as an array.
43
42
  def tagged(*tags, &block)
44
- tag_hash = {}
45
- tags.flatten.each do |tag|
46
- tagged_values = Array(tag_hash["tagged"] || self.tags["tagged"])
47
- tag_hash["tagged"] = tagged_values + [tag]
43
+ tagged_values = Array(tag_value("tagged"))
44
+ flattened_tags = tags.flatten.collect(&:to_s).reject do |tag|
45
+ tag.respond_to?(:blank?) ? tag.blank? : tag.empty?
46
+ end
47
+ tagged_values += flattened_tags unless flattened_tags.empty?
48
+
49
+ if block || in_tag_context?
50
+ tag("tagged" => tagged_values, &block)
51
+ else
52
+ tag_globally("tagged" => tagged_values)
48
53
  end
49
- tag(tag_hash, &block)
50
54
  end
51
55
 
52
56
  def push_tags(*tags)
@@ -54,13 +58,24 @@ module Lumberjack
54
58
  end
55
59
 
56
60
  def pop_tags(size = 1)
57
- tagged_values = Array(@tags["tagged"])
61
+ tagged_values = tag_value("tagged")
62
+ return unless tagged_values.is_a?(Array)
63
+
58
64
  tagged_values = ((tagged_values.size > size) ? tagged_values[0, tagged_values.size - size] : nil)
59
- tag("tagged" => tagged_values)
65
+
66
+ if in_tag_context?
67
+ tag("tagged" => tagged_values)
68
+ else
69
+ tag_globally("tagged" => tagged_values)
70
+ end
60
71
  end
61
72
 
62
73
  def clear_tags!
63
- tag("tagged" => nil)
74
+ if in_tag_context?
75
+ tag("tagged" => nil)
76
+ else
77
+ tag_globally("tagged" => nil)
78
+ end
64
79
  end
65
80
  end
66
81
  end
@@ -12,14 +12,8 @@ module Lumberjack
12
12
  return nil if hash.nil?
13
13
  if hash.keys.all? { |key| key.is_a?(String) }
14
14
  hash
15
- elsif hash.respond_to?(:transform_keys)
16
- hash.transform_keys(&:to_s)
17
15
  else
18
- copy = {}
19
- hash.each do |key, value|
20
- copy[key.to_s] = value
21
- end
22
- copy
16
+ hash.transform_keys(&:to_s)
23
17
  end
24
18
  end
25
19
 
@@ -99,7 +99,7 @@ module Lumberjack
99
99
  return [nil] * (tag_vars.size + 1) if tags.nil? || tags.size == 0
100
100
 
101
101
  tags_string = +""
102
- tags.each do |name, value|
102
+ Lumberjack::Utils.flatten_tags(tags).each do |name, value|
103
103
  unless value.nil? || tag_vars.include?(name)
104
104
  value = value.to_s
105
105
  value = value.gsub(Lumberjack::LINE_SEPARATOR, " ") if value.include?(Lumberjack::LINE_SEPARATOR)
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+
5
+ module Lumberjack
6
+ module Utils
7
+ UNDEFINED = Object.new.freeze
8
+ private_constant :UNDEFINED
9
+
10
+ NON_SLUGGABLE_PATTERN = /[^A-Za-z0-9_.-]+/.freeze
11
+ private_constant :NON_SLUGGABLE_PATTERN
12
+
13
+ @deprecations = nil
14
+ @deprecations_lock = nil
15
+ @hostname = UNDEFINED
16
+
17
+ class << self
18
+ # Print warning when deprecated methods are called the first time. This can be disabled
19
+ # by setting the environment variable `LUMBERJACK_NO_DEPRECATION_WARNINGS` to "true".
20
+ # You can see every usage of a deprecated method along with a full stack trace by setting
21
+ # the environment variable `VERBOSE_LUMBERJACK_DEPRECATION_WARNING` to "true".
22
+ #
23
+ # @param method [String] The name of the deprecated method.
24
+ # @param message [String] Optional message to include in the warning.
25
+ # @yield The block to execute after the warning.
26
+ def deprecated(method, message)
27
+ @deprecations_lock ||= Mutex.new
28
+ unless @deprecations&.include?(method)
29
+ @deprecations_lock.synchronize do
30
+ @deprecations ||= {}
31
+ unless @deprecations.include?(method)
32
+ trace = caller[3..-1]
33
+ unless ENV["VERBOSE_LUMBERJACK_DEPRECATION_WARNING"] == "true"
34
+ trace = [trace.first]
35
+ @deprecations[method] = true
36
+ end
37
+ message = "DEPRECATION WARNING: #{message} Called from #{trace.join("\n")}"
38
+ warn(message) unless ENV["LUMBERJACK_NO_DEPRECATION_WARNINGS"] == "true"
39
+ end
40
+ end
41
+ end
42
+
43
+ yield
44
+ end
45
+
46
+ # Get the hostname of the machine. The returned value will be in UTF-8 encoding.
47
+ #
48
+ # @return [String] The hostname of the machine.
49
+ def hostname
50
+ if @hostname.equal?(UNDEFINED)
51
+ @hostname = force_utf8(Socket.gethostname)
52
+ end
53
+ @hostname
54
+ end
55
+
56
+ # Set the hostname to a specific value. If this is not specified, it will use the system hostname.
57
+ #
58
+ # @param hostname [String]
59
+ # @return [void]
60
+ def hostname=(hostname)
61
+ @hostname = force_utf8(hostname)
62
+ end
63
+
64
+ # Generate a global process ID that includes the hostname and process ID.
65
+ #
66
+ # @return [String] The global process ID.
67
+ def global_pid
68
+ if hostname
69
+ "#{hostname}-#{Process.pid}"
70
+ else
71
+ Process.pid.to_s
72
+ end
73
+ end
74
+
75
+ # Generate a global thread ID that includes the global process ID and the thread name.
76
+ #
77
+ # @return [String] The global thread ID.
78
+ def global_thread_id
79
+ "#{global_pid}-#{thread_name}"
80
+ end
81
+
82
+ # Get the name of a thread. The value will be based on the thread's name if it exists.
83
+ # Otherwise a unique id is generated based on the thread's object id. Only alphanumeric
84
+ # characters, underscores, dashes, and periods are kept in thread name.
85
+ #
86
+ # @param thread [Thread] The thread to get the name for. Defaults to the current thread.
87
+ # @return [String] The name of the thread.
88
+ def thread_name(thread = Thread.current)
89
+ thread.name ? slugify(thread.name) : thread.object_id.to_s(36)
90
+ end
91
+
92
+ # Force encode a string to UTF-8. Any invalid byte sequences will be
93
+ # ignored and replaced with an empty string.
94
+ #
95
+ # @param str [String] The string to encode.
96
+ # @return [String] The UTF-8 encoded string.
97
+ def force_utf8(str)
98
+ return nil if str.nil?
99
+
100
+ str.dup.force_encoding("ASCII-8BIT").encode("UTF-8", invalid: :replace, undef: :replace, replace: "")
101
+ end
102
+
103
+ # Flatten a tag hash to a single level hash with dot notation for nested keys.
104
+ #
105
+ # @param tag_hash [Hash] The hash to flatten.
106
+ # @return [Hash<String, Object>] The flattened hash.
107
+ # @example
108
+ # expand_tags(user: {id: 123, name: "Alice"}, action: "login")})
109
+ # # => {"user.id" => 123, "user.name" => "Alice", "action" => "login"}
110
+ def flatten_tags(tag_hash)
111
+ return {} unless tag_hash.is_a?(Hash)
112
+
113
+ flatten_hash_recursive(tag_hash)
114
+ end
115
+
116
+ # Expand a hash of tags that may contain nested hashes or dot notation keys. Dot notation tags
117
+ # will be expanded into nested hashes.
118
+ #
119
+ # @param tags [Hash] The hash of tags to expand.
120
+ # @return [Hash] The expanded hash with dot notation keys.
121
+ #
122
+ # @example
123
+ # expand_tags({"user.id" => 123, "user.name" => "Alice", "action" => "login"})
124
+ # # => {"user" => {"id" => 123, "name" => "Alice"}, "action" => "login"}
125
+ def expand_tags(tags)
126
+ return {} unless tags.is_a?(Hash)
127
+
128
+ expand_dot_notation_hash(tags)
129
+ end
130
+
131
+ private
132
+
133
+ def flatten_hash_recursive(hash, prefix = nil)
134
+ hash.each_with_object({}) do |(key, value), result|
135
+ full_key = prefix ? "#{prefix}.#{key}" : key.to_s
136
+ if value.is_a?(Hash)
137
+ result.merge!(flatten_hash_recursive(value, full_key))
138
+ else
139
+ result[full_key] = value
140
+ end
141
+ end
142
+ end
143
+
144
+ def slugify(str)
145
+ return nil if str.nil?
146
+
147
+ str = str.gsub(NON_SLUGGABLE_PATTERN, "-")
148
+ str.delete_prefix!("-")
149
+ str.chomp!("-")
150
+ str
151
+ end
152
+
153
+ def expand_dot_notation_hash(hash, expanded = {})
154
+ return hash unless hash.is_a?(Hash)
155
+
156
+ hash.each do |key, value|
157
+ key = key.to_s
158
+ if key.include?(".")
159
+ main_key, sub_key = key.split(".", 2)
160
+ main_key_hash = expanded[main_key]
161
+ unless main_key_hash.is_a?(Hash)
162
+ main_key_hash = {}
163
+ expanded[main_key] = main_key_hash
164
+ end
165
+ expand_dot_notation_hash({sub_key => value}, main_key_hash)
166
+ elsif value.is_a?(Hash)
167
+ key_hash = expanded[key]
168
+ unless key_hash.is_a?(Hash)
169
+ key_hash = {}
170
+ expanded[key] = key_hash
171
+ end
172
+ expand_dot_notation_hash(value, key_hash)
173
+ else
174
+ expanded[key] = value
175
+ end
176
+ end
177
+
178
+ expanded
179
+ end
180
+ end
181
+ end
182
+ end
data/lib/lumberjack.rb CHANGED
@@ -17,11 +17,13 @@ module Lumberjack
17
17
  require_relative "lumberjack/device"
18
18
  require_relative "lumberjack/logger"
19
19
  require_relative "lumberjack/tags"
20
+ require_relative "lumberjack/tag_context"
20
21
  require_relative "lumberjack/tag_formatter"
21
22
  require_relative "lumberjack/tagged_logger_support"
22
23
  require_relative "lumberjack/tagged_logging"
23
24
  require_relative "lumberjack/template"
24
25
  require_relative "lumberjack/rack"
26
+ require_relative "lumberjack/utils"
25
27
 
26
28
  class << self
27
29
  # Define a unit of work within a block. Within the block supplied to this
@@ -34,24 +36,29 @@ module Lumberjack
34
36
  # For the common use case of treating a single web request as a unit of work, see the
35
37
  # Lumberjack::Rack::UnitOfWork class.
36
38
  #
37
- # @param [String] id The id for the unit of work.
39
+ # @param id [String] The id for the unit of work.
38
40
  # @return [void]
41
+ # @deprecated Use tags instead. This will be removed in version 2.0.
39
42
  def unit_of_work(id = nil)
40
- id ||= SecureRandom.hex(6)
41
- context do
42
- context[:unit_of_work_id] = id
43
- yield
43
+ Lumberjack::Utils.deprecated("Lumberjack.unit_of_work", "Lumberjack.unit_of_work will be removed in version 2.0. Use Lumberjack::Logger#tag(unit_of_work: id) instead.") do
44
+ id ||= SecureRandom.hex(6)
45
+ context do
46
+ context[:unit_of_work_id] = id
47
+ yield
48
+ end
44
49
  end
45
50
  end
46
51
 
47
52
  # Get the UniqueIdentifier for the current unit of work.
48
53
  #
49
54
  # @return [String, nil] The id for the current unit of work.
55
+ # @deprecated Use tags instead. This will be removed in version 2.0.
50
56
  def unit_of_work_id
51
57
  context[:unit_of_work_id]
52
58
  end
53
59
 
54
60
  # Contexts can be used to store tags that will be attached to all log entries in the block.
61
+ # The context will apply to all Lumberjack loggers that are used within the block.
55
62
  #
56
63
  # If this method is called with a block, it will set a logging context for the scope of a block.
57
64
  # If there is already a context in scope, a new one will be created that inherits
data/lumberjack.gemspec CHANGED
@@ -4,10 +4,16 @@ Gem::Specification.new do |spec|
4
4
  spec.authors = ["Brian Durand"]
5
5
  spec.email = ["bbdurand@gmail.com"]
6
6
 
7
- spec.summary = "A simple, powerful, and very fast logging utility that can be a drop in replacement for Logger or ActiveSupport::BufferedLogger."
7
+ spec.summary = "A simple, powerful, and fast logging utility with excellent structured logging support that can be a drop in replacement for the standard library Logger."
8
8
  spec.homepage = "https://github.com/bdurand/lumberjack"
9
9
  spec.license = "MIT"
10
10
 
11
+ spec.metadata = {
12
+ "homepage_uri" => spec.homepage,
13
+ "source_code_uri" => spec.homepage,
14
+ "changelog_uri" => "#{spec.homepage}/blob/main/CHANGELOG.md"
15
+ }
16
+
11
17
  # Specify which files should be added to the gem when it is released.
12
18
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
13
19
  ignore_files = %w[
@@ -25,7 +31,7 @@ Gem::Specification.new do |spec|
25
31
 
26
32
  spec.require_paths = ["lib"]
27
33
 
28
- spec.required_ruby_version = ">= 2.3.0"
34
+ spec.required_ruby_version = ">= 2.5.0"
29
35
 
30
36
  spec.add_development_dependency "bundler"
31
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lumberjack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.10
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Durand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-13 00:00:00.000000000 Z
11
+ date: 2025-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -31,6 +31,7 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - ARCHITECTURE.md
34
35
  - CHANGELOG.md
35
36
  - MIT_LICENSE.txt
36
37
  - README.md
@@ -50,11 +51,15 @@ files:
50
51
  - lib/lumberjack/formatter/exception_formatter.rb
51
52
  - lib/lumberjack/formatter/id_formatter.rb
52
53
  - lib/lumberjack/formatter/inspect_formatter.rb
54
+ - lib/lumberjack/formatter/multiply_formatter.rb
53
55
  - lib/lumberjack/formatter/object_formatter.rb
54
56
  - lib/lumberjack/formatter/pretty_print_formatter.rb
57
+ - lib/lumberjack/formatter/redact_formatter.rb
58
+ - lib/lumberjack/formatter/round_formatter.rb
55
59
  - lib/lumberjack/formatter/string_formatter.rb
56
60
  - lib/lumberjack/formatter/strip_formatter.rb
57
61
  - lib/lumberjack/formatter/structured_formatter.rb
62
+ - lib/lumberjack/formatter/tagged_message.rb
58
63
  - lib/lumberjack/formatter/truncate_formatter.rb
59
64
  - lib/lumberjack/log_entry.rb
60
65
  - lib/lumberjack/logger.rb
@@ -63,16 +68,21 @@ files:
63
68
  - lib/lumberjack/rack/request_id.rb
64
69
  - lib/lumberjack/rack/unit_of_work.rb
65
70
  - lib/lumberjack/severity.rb
71
+ - lib/lumberjack/tag_context.rb
66
72
  - lib/lumberjack/tag_formatter.rb
67
73
  - lib/lumberjack/tagged_logger_support.rb
68
74
  - lib/lumberjack/tagged_logging.rb
69
75
  - lib/lumberjack/tags.rb
70
76
  - lib/lumberjack/template.rb
77
+ - lib/lumberjack/utils.rb
71
78
  - lumberjack.gemspec
72
79
  homepage: https://github.com/bdurand/lumberjack
73
80
  licenses:
74
81
  - MIT
75
- metadata: {}
82
+ metadata:
83
+ homepage_uri: https://github.com/bdurand/lumberjack
84
+ source_code_uri: https://github.com/bdurand/lumberjack
85
+ changelog_uri: https://github.com/bdurand/lumberjack/blob/main/CHANGELOG.md
76
86
  post_install_message:
77
87
  rdoc_options: []
78
88
  require_paths:
@@ -81,16 +91,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
81
91
  requirements:
82
92
  - - ">="
83
93
  - !ruby/object:Gem::Version
84
- version: 2.3.0
94
+ version: 2.5.0
85
95
  required_rubygems_version: !ruby/object:Gem::Requirement
86
96
  requirements:
87
97
  - - ">="
88
98
  - !ruby/object:Gem::Version
89
99
  version: '0'
90
100
  requirements: []
91
- rubygems_version: 3.4.20
101
+ rubygems_version: 3.4.10
92
102
  signing_key:
93
103
  specification_version: 4
94
- summary: A simple, powerful, and very fast logging utility that can be a drop in replacement
95
- for Logger or ActiveSupport::BufferedLogger.
104
+ summary: A simple, powerful, and fast logging utility with excellent structured logging
105
+ support that can be a drop in replacement for the standard library Logger.
96
106
  test_files: []