lorekeeper 1.7.1 → 1.11.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: eacd166a17c5e6f4ad24a5f03fe872a25290dd5e
4
- data.tar.gz: 9c85bd94a282067e28010081ff0e79e0963fc830
2
+ SHA256:
3
+ metadata.gz: de74418ad428e6556541729fb0e7a4a87d8f9da9eb2274d6a7837cdc89066f6b
4
+ data.tar.gz: f0a7097544c0e29cf894b1c608a9c2048f09f8c6aac16a976f24968c693af1ae
5
5
  SHA512:
6
- metadata.gz: 2e1c6718980ffaf6736fcee85a5d01dabed7df31b3af84c39efede9b69cc994ab602c010ca1f34e9301daa66f9eddce2ee773849c6d82234a5a15c8cd07be58b
7
- data.tar.gz: 2dae7e8356d9d03280c08a16ac90827dda1ae25945c94854fa8f6da9c57a2602297a08815672801b9936738fdd0b2dd9a83bf420e715dd1e4a8412e7a1da4dc3
6
+ metadata.gz: 81ff827913aff25a84222514e0b7feaca8cca96edd92d86c2b29e477d9f243c60cf377fb4d6a90647ddfec60783d3b26c9bb3a751c400d9ae5a445d72f314305
7
+ data.tar.gz: 178f3cb38c3d70fb063e7a0ef0149ce8dca7fc22b610d5f0dc0fd9e065aa87db0301a5d2e0018da04f20829ff00c0a380a2f80dd743171eeff35bd06df6161db
data/.travis.yml CHANGED
@@ -2,11 +2,8 @@ language: ruby
2
2
  cache: bundler
3
3
 
4
4
  rvm:
5
- - 2.1.10
6
- - 2.2.10
7
- - 2.3.8
8
- - 2.4.5
9
- - 2.5.3
10
- - 2.6.0-rc1
5
+ - 2.4.9
6
+ - 2.5.7
7
+ - 2.6.5
11
8
 
12
9
  script: bundle exec rspec
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ # 1.11.0
2
+ * Support for activerecord-session_store v2 which calls only silence and not silence_logger
3
+
4
+ # 1.10.0
5
+ * Use ActiveSupport::BacktraceCleaner to reduce noise in stacktrace output
6
+
7
+ # 1.9.0
8
+ * Remove Newrelic instrumentation information from stacktrace output
9
+
10
+ # 1.8.0
11
+ * Allow to use named parameters in the .exception method
12
+
13
+ # 1.7.2
14
+ * Add a second parameter to respond_to? to avoid Ruby 2.6 warnings
15
+ * Drop support for unsupported Ruby 2.1 and Ruby 2.2
16
+
1
17
  # 1.7.1
2
18
  * Ensure `data` is not nil when logging wrong #exception usage
3
19
 
data/Gemfile CHANGED
@@ -1,8 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- group :development do
4
- gem 'mutant-rspec', '~> 0.8'
5
- end
6
-
7
3
  # Specify your gem's dependencies in lorekeeper.gemspec
8
4
  gemspec
data/README.md CHANGED
@@ -141,6 +141,52 @@ Will output:
141
141
  }
142
142
  ```
143
143
 
144
+ This method also accepts a custom message, data and log level.
145
+
146
+ ```ruby
147
+ rescue => e
148
+ logger.exception(e, "custom msg!", { some: { data: 123 } }, :warn)
149
+ end
150
+ ```
151
+
152
+ Will output:
153
+
154
+ ```javascript
155
+ {
156
+ "message": "custom msg!",
157
+ "timestamp": "1970-01-01T00:00:00.000+0100",
158
+ "level": "warning",
159
+ "data": {
160
+ ":some": {
161
+ ":data": 123
162
+ }
163
+ },
164
+ "exception": "<exception name>",
165
+ "stack": [
166
+ "<stacktraceline1>",
167
+ "<stacktraceline2>"
168
+ ]
169
+ }
170
+ ```
171
+
172
+ Alternatively you can use named parameters:
173
+
174
+
175
+ ```ruby
176
+ rescue => e
177
+ logger.exception(e, message: "custom msg!", data: { some: { data: 123 } }, level: :warn)
178
+ end
179
+ ```
180
+
181
+ This is specially useful when there is no custom message or data:
182
+
183
+ ```ruby
184
+ rescue => e
185
+ logger.exception(e, level: :warn)
186
+ end
187
+ ```
188
+
189
+
144
190
 
145
191
  ## License
146
192
 
data/Rakefile CHANGED
@@ -50,10 +50,10 @@ task :benchmark do
50
50
  simple_log = create_simple_logger
51
51
 
52
52
  Benchmark.ips do |bm|
53
- bm.report('short content') { log.error(contents) }
54
- bm.report('Logger short content') { simple_log.info(contents) }
55
- bm.report('long content') { log.info(long_contents) }
56
- bm.report('Logger long content') { simple_log.info(long_contents) }
53
+ bm.report('JSON short content') { log.debug(contents) }
54
+ bm.report('Logger short content') { simple_log.debug(contents) }
55
+ bm.report('JSON long content') { log.debug(long_contents) }
56
+ bm.report('Logger long content') { simple_log.debug(long_contents) }
57
57
  bm.compare!
58
58
  end
59
59
 
@@ -68,6 +68,11 @@ module Lorekeeper
68
68
  yield if block_given?
69
69
  end
70
70
 
71
+ # activerecord-session_store v2 is now simply calling silence instead of silence_logger
72
+ def silence(&block)
73
+ yield if block_given?
74
+ end
75
+
71
76
  # inherited classes probably want to reimplement this
72
77
  def log_data(_severity, message)
73
78
  @iodevice.write(message)
@@ -9,6 +9,7 @@ module Lorekeeper
9
9
  def initialize(file)
10
10
  reset_state
11
11
  @base_fields = { MESSAGE => '', TIMESTAMP => '', LEVEL => '' }
12
+ @backtrace_cleaner = set_backtrace_cleaner
12
13
  super(file)
13
14
  end
14
15
 
@@ -29,7 +30,7 @@ module Lorekeeper
29
30
  LOGGING_METHODS.each do |method_name|
30
31
  define_method "#{method_name}_with_data", ->(message_param = nil, data = {}, &block) do
31
32
  return true if METHOD_SEVERITY_MAP[method_name] < @level
32
- extra_fields = { 'data' => (data || {}) }
33
+ extra_fields = { DATA => (data || {}) }
33
34
  with_extra_fields(extra_fields) { # Using do/end here only valid on Ruby>= 2.3
34
35
  add(METHOD_SEVERITY_MAP[method_name], message_param, nil, &block)
35
36
  }
@@ -61,25 +62,31 @@ module Lorekeeper
61
62
  end
62
63
 
63
64
  # @param exception: instance of a class inheriting from Exception
64
- # We will output backtrace twice. Once inside the stack so it can be parsed by software
65
- # And the other inside the message so it is readable to humans
66
- def exception(exception, custom_message = nil, custom_data = nil, level = :error)
67
- log_level = METHOD_SEVERITY_MAP[level] || ERROR
65
+ # By default message comes from exception.message
66
+ # Optional and named parameters to overwrite message, level and add data
67
+ def exception(exception, custom_message = nil, custom_data = nil, custom_level = :error,
68
+ message: nil, data: nil, level: nil) # Backwards compatible named params
69
+
70
+ param_level = level || custom_level
71
+ param_data = data || custom_data
72
+ param_message = message || custom_message
73
+
74
+ log_level = METHOD_SEVERITY_MAP[param_level] || ERROR
68
75
 
69
76
  if exception.is_a?(Exception)
70
- backtrace = exception.backtrace || []
77
+ backtrace = clean_backtrace(exception.backtrace || [])
71
78
  exception_fields = {
72
- 'exception' => "#{exception.class}: #{exception.message}",
73
- 'stack' => backtrace
79
+ EXCEPTION => "#{exception.class}: #{exception.message}",
80
+ STACK => backtrace
74
81
  }
75
- exception_fields['data'] = custom_data if custom_data
82
+ exception_fields[DATA] = param_data if param_data
76
83
 
77
- message = custom_message || exception.message
84
+ message = param_message || exception.message
78
85
  with_extra_fields(exception_fields) { log_data(log_level, message) }
79
86
  else
80
87
  log_data(METHOD_SEVERITY_MAP[:warn], 'Logger exception called without exception class.')
81
- message = "#{exception.class}: #{exception.inspect} #{custom_message}"
82
- with_extra_fields('data' => (custom_data || {})) { log_data(log_level, message) }
88
+ message = "#{exception.class}: #{exception.inspect} #{param_message}"
89
+ with_extra_fields(DATA => (param_data || {})) { log_data(log_level, message) }
83
90
  end
84
91
  end
85
92
 
@@ -89,11 +96,32 @@ module Lorekeeper
89
96
 
90
97
  private
91
98
 
99
+ # Some instrumentation libraries pollute the stacktrace and create a large output which may
100
+ # cause problems with certain logging backends.
101
+ # Hardcording newrelic and active_support/callbacks now here.
102
+ # In the future if this list grows, we may make it configurable.
103
+ def clean_backtrace(backtrace)
104
+ @backtrace_cleaner&.clean(backtrace) || backtrace
105
+ end
106
+
107
+ def set_backtrace_cleaner
108
+ return nil unless defined?(ActiveSupport::BacktraceCleaner)
109
+
110
+ cleaner = ActiveSupport::BacktraceCleaner.new
111
+ cleaner.remove_silencers!
112
+ cleaner.add_silencer { |line| line.match?(BLACKLISTED_FINGERPRINT) }
113
+ cleaner
114
+ end
115
+
92
116
  THREAD_KEY = 'lorekeeper_jsonlogger_key' # Shared by all threads but unique by thread
93
117
  LEVEL = 'level'
94
118
  MESSAGE = 'message'
95
119
  TIMESTAMP = 'timestamp'
96
120
  DATE_FORMAT = '%FT%T.%6NZ'
121
+ EXCEPTION = 'exception'
122
+ STACK = 'stack'
123
+ DATA = 'data'
124
+ BLACKLISTED_FINGERPRINT = %r{newrelic_rpm|active_support/callbacks.rb}.freeze
97
125
 
98
126
  def with_extra_fields(fields)
99
127
  state[:extra_fields] = fields
@@ -108,11 +136,12 @@ module Lorekeeper
108
136
  end
109
137
 
110
138
  def log_data(severity, message)
139
+ current_state = state # Accessing state is slow. Do it only once per call.
111
140
  # merging is slow, we do not want to merge with empty hash if possible
112
- fields_to_log = if state[:extra_fields].empty?
113
- state[:base_fields]
141
+ fields_to_log = if current_state[:extra_fields].empty?
142
+ current_state[:base_fields]
114
143
  else
115
- state[:base_fields].merge(state[:extra_fields])
144
+ current_state[:base_fields].merge(current_state[:extra_fields])
116
145
  end
117
146
 
118
147
  fields_to_log[MESSAGE] = message
@@ -16,9 +16,15 @@ module Lorekeeper
16
16
  "Lorekeeper multilogger, loggers: #{@loggers.map(&:inspect)}"
17
17
  end
18
18
 
19
+ if RUBY_VERSION > "2.6"
20
+ def respond_to?(method, all_included = false)
21
+ @loggers.all? { |logger| logger.respond_to?(method, all_included) }
22
+ end
23
+ else
19
24
  def respond_to?(method)
20
25
  @loggers.all? { |logger| logger.respond_to?(method) }
21
26
  end
27
+ end
22
28
 
23
29
  def method_missing(method, *args, &block)
24
30
  result = @loggers.map do |logger|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lorekeeper
4
- VERSION = '1.7.1'
4
+ VERSION = '1.11.0'
5
5
  end
data/lorekeeper.gemspec CHANGED
@@ -20,16 +20,18 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ['lib']
22
22
 
23
- spec.required_ruby_version = '>= 2.1.0'
23
+ spec.required_ruby_version = '>= 2.4.0'
24
24
 
25
25
  spec.add_dependency 'oj', '>= 3.4', '< 4.0'
26
26
 
27
+ spec.add_development_dependency 'activesupport', '>= 4.0'
27
28
  spec.add_development_dependency 'bundler', '>= 1.16', '< 3.0'
28
29
  spec.add_development_dependency 'rake', '~> 12.0'
29
- spec.add_development_dependency 'rspec', '~> 3.4'
30
+ spec.add_development_dependency 'rspec', '~> 3.8'
30
31
  spec.add_development_dependency 'benchmark-ips', '~> 2.3'
31
32
  spec.add_development_dependency 'timecop', '~> 0.8'
32
- spec.add_development_dependency 'byebug', '~> 8.0'
33
+ spec.add_development_dependency 'byebug', '~> 11.0'
33
34
  spec.add_development_dependency 'rbtrace', '~> 0.4'
34
35
  spec.add_development_dependency 'simplecov', '~> 0.16'
36
+ spec.add_development_dependency 'mutant-rspec', '~> 0.8'
35
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lorekeeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordi Polo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-12 00:00:00.000000000 Z
11
+ date: 2021-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '4.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: activesupport
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '4.0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '4.0'
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: bundler
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -70,14 +84,14 @@ dependencies:
70
84
  requirements:
71
85
  - - "~>"
72
86
  - !ruby/object:Gem::Version
73
- version: '3.4'
87
+ version: '3.8'
74
88
  type: :development
75
89
  prerelease: false
76
90
  version_requirements: !ruby/object:Gem::Requirement
77
91
  requirements:
78
92
  - - "~>"
79
93
  - !ruby/object:Gem::Version
80
- version: '3.4'
94
+ version: '3.8'
81
95
  - !ruby/object:Gem::Dependency
82
96
  name: benchmark-ips
83
97
  requirement: !ruby/object:Gem::Requirement
@@ -112,14 +126,14 @@ dependencies:
112
126
  requirements:
113
127
  - - "~>"
114
128
  - !ruby/object:Gem::Version
115
- version: '8.0'
129
+ version: '11.0'
116
130
  type: :development
117
131
  prerelease: false
118
132
  version_requirements: !ruby/object:Gem::Requirement
119
133
  requirements:
120
134
  - - "~>"
121
135
  - !ruby/object:Gem::Version
122
- version: '8.0'
136
+ version: '11.0'
123
137
  - !ruby/object:Gem::Dependency
124
138
  name: rbtrace
125
139
  requirement: !ruby/object:Gem::Requirement
@@ -148,6 +162,20 @@ dependencies:
148
162
  - - "~>"
149
163
  - !ruby/object:Gem::Version
150
164
  version: '0.16'
165
+ - !ruby/object:Gem::Dependency
166
+ name: mutant-rspec
167
+ requirement: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - "~>"
170
+ - !ruby/object:Gem::Version
171
+ version: '0.8'
172
+ type: :development
173
+ prerelease: false
174
+ version_requirements: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - "~>"
177
+ - !ruby/object:Gem::Version
178
+ version: '0.8'
151
179
  description: Opinionated logger which outputs messages in JSON format
152
180
  email:
153
181
  - mumismo@gmail.com
@@ -185,15 +213,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
185
213
  requirements:
186
214
  - - ">="
187
215
  - !ruby/object:Gem::Version
188
- version: 2.1.0
216
+ version: 2.4.0
189
217
  required_rubygems_version: !ruby/object:Gem::Requirement
190
218
  requirements:
191
219
  - - ">="
192
220
  - !ruby/object:Gem::Version
193
221
  version: '0'
194
222
  requirements: []
195
- rubyforge_project:
196
- rubygems_version: 2.6.14
223
+ rubygems_version: 3.0.3
197
224
  signing_key:
198
225
  specification_version: 4
199
226
  summary: Very fast JSON logger