lorekeeper 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92b989dbf8ed93f0ef8a14a4c38c96942e34fdfb11c09048bbbe4077c4c0e493
4
- data.tar.gz: 994f2c997387e2bf60e991b858a7683de6e0e53f21a7868b42844606e2d93a30
3
+ metadata.gz: 8099634bb3a3f3d4d348737b0c9634a3a70743c1d868ebec42c194865df7a13c
4
+ data.tar.gz: c216efb9f7f6c2e06c357aee59d1f0ad8299445c5becc0d8fc4f2d444e5193ec
5
5
  SHA512:
6
- metadata.gz: 2626986445dd5884ed83d2853e8654be86eced615ab9b82aab90bae74c3e9e6a2e081acb5c8a3afe27143213cc588f331cd35fb5356c0bab5c196c15d2d19052
7
- data.tar.gz: 28e4416df69d092dffe46ed3317c33ef0e4d893c3484425d45cf7a4ae8bcfa0768f540dbee6969bc92836008ce71c51d029a3f8ee6fab297228d9fa16a74ffdf
6
+ metadata.gz: 93af9f7d3142bdc8166a14e2324b71fe3e51c3f150ea2fccee8557fc2d17b92517b3d6214e8021ed86bdbf632bed836b12027bf438f4bba0099ef1bbaed32e63
7
+ data.tar.gz: d81128b6905c1f70e7946bf7be63bf35923d40056d9c9ab7274397b7ff8726da582109f83c0c2905768c0c694ac48c2fa8574dd894f10a0b60d6c3b0ac28dfbb
@@ -14,7 +14,7 @@ jobs:
14
14
  runs-on: ubuntu-latest
15
15
  strategy:
16
16
  matrix:
17
- ruby-version: ['2.7', '3.0', '3.1']
17
+ ruby-version: ['2.7', '3.0', '3.1', '3.2']
18
18
 
19
19
  steps:
20
20
  - uses: actions/checkout@v2
@@ -23,6 +23,8 @@ jobs:
23
23
  with:
24
24
  ruby-version: ${{ matrix.ruby-version }}
25
25
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
26
+ - name: Run rubocop
27
+ run: bundle exec rubocop
26
28
  - name: Run tests
27
29
  run: bundle exec rspec
28
30
  - name: Run benchmark
data/.rubocop.yml CHANGED
@@ -1,6 +1,42 @@
1
- Metrics/LineLength:
2
- Max: 120
3
- # https://github.com/rubocop/rubocop/blob/20990ed3831589c0d9f202107b1b580ead8ef2c5/lib/rubocop/cop/style/single_line_methods.rb#L11
1
+ require:
2
+ - rubocop-performance
3
+
4
+ inherit_gem:
5
+ rubocop-mdsol: rubocop.yml
6
+
7
+ AllCops:
8
+ Exclude:
9
+ - '*gemspec'
10
+ # NOTE: Excludes vendor from linting. Needed by GitHub Actions.
11
+ # - https://github.com/rubocop/rubocop/issues/9832#issuecomment-873398952
12
+ #
13
+ - 'vendor/bundle/**/*'
14
+
15
+ Lint/ConstantDefinitionInBlock:
16
+ Exclude:
17
+ - 'spec/**/*'
18
+
19
+ Layout/ArgumentAlignment:
20
+ EnforcedStyle: with_fixed_indentation
21
+
22
+ Layout/FirstHashElementIndentation:
23
+ EnforcedStyle: consistent
24
+
25
+ Metrics/ParameterLists:
26
+ CountKeywordArgs: false
27
+
4
28
  # TODO: add "EnforcedStyle: allow_single_line" once all rubys are > 3.0 to autocorrect all single-line methods to endless
29
+ # https://github.com/rubocop/rubocop/blob/20990ed3831589c0d9f202107b1b580ead8ef2c5/lib/rubocop/cop/style/single_line_methods.rb#L11
30
+ #
5
31
  Style/SingleLineMethods:
6
32
  Enabled: false
33
+
34
+ Style/MissingRespondToMissing:
35
+ Enabled: false
36
+
37
+ Style/FrozenStringLiteralComment:
38
+ Enabled: true
39
+
40
+ Style/StringLiterals:
41
+ Enabled: true
42
+ EnforcedStyle: single_quotes
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ # 2.4.0
2
+ * Add `#with_level` method support added to the stdlib's Logger in [#85](https://github.com/ruby/logger/issues/85)
3
+ * Support symbol log level setting
4
+
5
+ # 2.3.2
6
+ * Ensure additional fields are reset after logging
7
+ * Let Oj fallback to :object mode for non-representable data
8
+ * Fix SimpleLogger to handle non-String log messages
9
+ * Run RuboCop checks on build and fix RuboCop offenses
10
+
1
11
  # 2.3.1
2
12
  * Fix MultiLogger to not raise ArgumentError
3
13
 
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in lorekeeper.gemspec
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'benchmark'
2
4
  require 'tempfile'
3
5
  require 'securerandom'
@@ -5,7 +7,7 @@ require 'benchmark/ips'
5
7
  require 'byebug'
6
8
  require 'rbtrace'
7
9
 
8
- $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
10
+ $LOAD_PATH.unshift(File.expand_path('lib', __dir__))
9
11
  $LOAD_PATH.uniq!
10
12
 
11
13
  require 'lorekeeper'
@@ -26,7 +28,7 @@ end
26
28
 
27
29
  def create_simple_logger
28
30
  logfile = Tempfile.new('my_test_log.log')
29
- ::Logger.new(logfile.path)
31
+ Logger.new(logfile.path)
30
32
  end
31
33
 
32
34
  # This task is used to help development of Lorekeeper. Use together with rbtrace
data/bin/console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'lorekeeper'
data/bin/setup CHANGED
File without changes
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'logger'
4
+ require 'fiber'
4
5
 
5
6
  module Lorekeeper
6
7
  # Very simple, very fast logger
7
8
  class FastLogger
8
- include ::Logger::Severity # contains the levels constants: DEBUG, ERROR, etc.
9
- attr_accessor :level # Current level, default: DEBUG
10
- attr_accessor :formatter # Just for compatibility with Logger, not used
9
+ include ::Logger::Severity # contains the levels constants: DEBUG, ERROR, etc.
10
+ attr_accessor :formatter # Just for compatibility with Logger, not used
11
11
 
12
12
  def debug?; level <= DEBUG; end
13
13
  def info?; level <= INFO; end
@@ -19,14 +19,37 @@ module Lorekeeper
19
19
  @level = DEBUG
20
20
  @iodevice = LogDevice.new(file)
21
21
  @file = file # We only keep this so we can inspect where we are sending the logs
22
+ @level_override = {}
22
23
  end
23
24
 
24
- LOGGING_METHODS = [
25
- :debug,
26
- :info,
27
- :warn,
28
- :error,
29
- :fatal
25
+ def level
26
+ @level_override[Fiber.current] || @level
27
+ end
28
+
29
+ def level=(severity)
30
+ @level = coerce(severity)
31
+ end
32
+
33
+ def with_level(severity)
34
+ prev = level
35
+ @level_override[Fiber.current] = coerce(severity)
36
+ begin
37
+ yield
38
+ ensure
39
+ if prev
40
+ @level_override[Fiber.current] = prev
41
+ else
42
+ @level_override.delete(Fiber.current)
43
+ end
44
+ end
45
+ end
46
+
47
+ LOGGING_METHODS = %i[
48
+ debug
49
+ info
50
+ warn
51
+ error
52
+ fatal
30
53
  ].freeze
31
54
 
32
55
  METHOD_SEVERITY_MAP = {
@@ -55,8 +78,9 @@ module Lorekeeper
55
78
 
56
79
  # This is part of the standard Logger API, we need this to be compatible
57
80
  def add(severity, message_param = nil, progname = nil, &block)
58
- return true if severity < @level
59
- message = (block && block.call) || message_param || progname
81
+ return true if severity < level
82
+
83
+ message = block&.call || message_param || progname
60
84
  log_data(severity, message.freeze)
61
85
  end
62
86
 
@@ -65,12 +89,12 @@ module Lorekeeper
65
89
  # To avoid needing to monkey-patch Lorekeeper just to get this method, we are adding a simple
66
90
  # non-functional version here.
67
91
  def silence_logger(&block)
68
- yield if block_given?
92
+ yield if block
69
93
  end
70
94
 
71
95
  # activerecord-session_store v2 is now simply calling silence instead of silence_logger
72
96
  def silence(&block)
73
- yield if block_given?
97
+ yield if block
74
98
  end
75
99
 
76
100
  # inherited classes probably want to reimplement this
@@ -82,7 +106,11 @@ module Lorekeeper
82
106
  @iodevice.write(message)
83
107
  end
84
108
 
85
- private
109
+ def coerce(severity)
110
+ return severity if severity.is_a?(Integer)
111
+
112
+ METHOD_SEVERITY_MAP[severity] || raise(ArgumentError, "invalid log level: #{severity}")
113
+ end
86
114
 
87
115
  require 'monitor'
88
116
  # Mutex to avoid broken lines when multiple threads access the log file
@@ -110,11 +138,12 @@ module Lorekeeper
110
138
  def to_iodevice(file)
111
139
  return nil unless file
112
140
 
113
- iodevice = if file.respond_to?(:write) && file.respond_to?(:close)
114
- file
115
- else
116
- open_logfile(file)
117
- end
141
+ iodevice =
142
+ if file.respond_to?(:write) && file.respond_to?(:close)
143
+ file
144
+ else
145
+ open_logfile(file)
146
+ end
118
147
 
119
148
  iodevice.sync = true if iodevice.respond_to?(:sync=)
120
149
  iodevice
@@ -132,5 +161,7 @@ module Lorekeeper
132
161
  open_logfile(filename)
133
162
  end
134
163
  end
164
+
165
+ private_constant :LogDeviceMutex, :LogDevice
135
166
  end
136
167
  end
@@ -28,13 +28,14 @@ module Lorekeeper
28
28
  # Delegates methods to the existing Logger instance
29
29
  # We are extending the logger API with methods error_with_data, etc
30
30
  LOGGING_METHODS.each do |method_name|
31
- define_method "#{method_name}_with_data", ->(message_param = nil, data = {}, &block) do
31
+ define_method "#{method_name}_with_data", ->(message_param = nil, data = {}, &block) {
32
32
  return true if METHOD_SEVERITY_MAP[method_name] < @level
33
+
33
34
  extra_fields = { DATA => (data || {}) }
34
- with_extra_fields(extra_fields) { # Using do/end here only valid on Ruby>= 2.3
35
+ with_extra_fields(extra_fields) do
35
36
  add(METHOD_SEVERITY_MAP[method_name], message_param, nil, &block)
36
- }
37
- end
37
+ end
38
+ }
38
39
  end
39
40
 
40
41
  def add_thread_unsafe_fields(fields)
@@ -65,7 +66,7 @@ module Lorekeeper
65
66
  # By default message comes from exception.message
66
67
  # Optional and named parameters to overwrite message, level and add data
67
68
  def exception(exception, custom_message = nil, custom_data = nil, custom_level = :error,
68
- message: nil, data: nil, level: nil) # Backwards compatible named params
69
+ message: nil, data: nil, level: nil) # Backwards compatible named params
69
70
 
70
71
  param_level = level || custom_level
71
72
  param_data = data || custom_data
@@ -95,11 +96,21 @@ module Lorekeeper
95
96
  end
96
97
 
97
98
  def write(message)
98
- super(Oj.dump(message, mode: :compat, cache_keys: true, cache_str: 5) << "\n")
99
+ super(json_message(message) << "\n")
99
100
  end
100
101
 
101
102
  private
102
103
 
104
+ def json_message(message)
105
+ Oj.dump(message, mode: :compat, cache_keys: true, cache_str: 5)
106
+ rescue JSON::GeneratorError
107
+ begin
108
+ Oj.dump(message)
109
+ rescue => e
110
+ Oj.dump(MESSAGE => e.message)
111
+ end
112
+ end
113
+
103
114
  # Some instrumentation libraries pollute the stacktrace and create a large output which may
104
115
  # cause problems with certain logging backends.
105
116
  # Hardcording newrelic, active_support/callbacks and zipkin-tracer now here.
@@ -130,12 +141,13 @@ module Lorekeeper
130
141
  def with_extra_fields(fields)
131
142
  state[:extra_fields] = fields
132
143
  yield
144
+ ensure
133
145
  state[:extra_fields] = {}
134
146
  end
135
147
 
136
148
  def remove_invalid_fields(fields)
137
149
  fields.delete_if do |_, v|
138
- v.nil? || v.respond_to?(:empty?) && v.empty?
150
+ v.nil? || (v.respond_to?(:empty?) && v.empty?)
139
151
  end
140
152
  end
141
153
 
@@ -143,10 +155,10 @@ module Lorekeeper
143
155
  current_state = state # Accessing state is slow. Do it only once per call.
144
156
  # merging is slow, we do not want to merge with empty hash if possible
145
157
  fields_to_log = if current_state[:extra_fields].empty?
146
- current_state[:base_fields]
147
- else
148
- current_state[:base_fields].merge(current_state[:extra_fields])
149
- end
158
+ current_state[:base_fields]
159
+ else
160
+ current_state[:base_fields].merge(current_state[:extra_fields])
161
+ end
150
162
 
151
163
  fields_to_log[MESSAGE] = message
152
164
  fields_to_log[TIMESTAMP] = Time.now.utc.strftime(DATE_FORMAT)
@@ -28,6 +28,7 @@ module Lorekeeper
28
28
  # \e[colorm sets a color \e[0m resets all properties
29
29
  def log_data(severity, message)
30
30
  color = SEVERITY_TO_COLOR_MAP[severity]
31
+ message = message.to_s
31
32
  write("\e[#{color}m#{message.gsub('\n', "\n").gsub('\t', "\t")}\e[0m\n")
32
33
  end
33
34
 
@@ -37,22 +38,28 @@ module Lorekeeper
37
38
 
38
39
  # Extending the logger API with methods error_with_data, etc
39
40
  LOGGING_METHODS.each do |method_name|
40
- define_method "#{method_name}_with_data", ->(message_param = nil, data = {}, &block) do
41
+ define_method "#{method_name}_with_data", ->(message_param = nil, data = {}) {
41
42
  return true if METHOD_SEVERITY_MAP[method_name] < @level
43
+
42
44
  log_data(METHOD_SEVERITY_MAP[method_name], "#{message_param}, data: #{data}")
43
- end
45
+ }
44
46
  end
45
47
 
46
48
  # To not raise NoMethodError for the methods defined in JSONLogger
47
49
  def current_fields(*); end
50
+
48
51
  def state(*); end
52
+
49
53
  def add_thread_unsafe_fields(*); end
54
+
50
55
  def remove_thread_unsafe_fields(*); end
56
+
51
57
  def add_fields(*); end
58
+
52
59
  def remove_fields(*); end
53
60
 
54
61
  def exception(exception, custom_message = nil, custom_data = nil, custom_level = :error,
55
- message: nil, data: nil, level: nil)
62
+ message: nil, data: nil, level: nil)
56
63
 
57
64
  param_level = level || custom_level
58
65
  param_data = data || custom_data
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lorekeeper
4
- VERSION = '2.3.1'
4
+ VERSION = '2.4.0'
5
5
  end
data/lorekeeper.gemspec CHANGED
@@ -34,4 +34,6 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency 'rbtrace', '~> 0.4'
35
35
  spec.add_development_dependency 'simplecov', '~> 0.16'
36
36
  spec.add_development_dependency 'mutant-rspec', '~> 0.8'
37
+ spec.add_development_dependency 'rubocop-mdsol', '~> 0.3'
38
+ spec.add_development_dependency 'rubocop-performance', '~> 1.14'
37
39
  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: 2.3.1
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordi Polo
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-18 00:00:00.000000000 Z
11
+ date: 2023-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -176,6 +176,34 @@ dependencies:
176
176
  - - "~>"
177
177
  - !ruby/object:Gem::Version
178
178
  version: '0.8'
179
+ - !ruby/object:Gem::Dependency
180
+ name: rubocop-mdsol
181
+ requirement: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - "~>"
184
+ - !ruby/object:Gem::Version
185
+ version: '0.3'
186
+ type: :development
187
+ prerelease: false
188
+ version_requirements: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - "~>"
191
+ - !ruby/object:Gem::Version
192
+ version: '0.3'
193
+ - !ruby/object:Gem::Dependency
194
+ name: rubocop-performance
195
+ requirement: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - "~>"
198
+ - !ruby/object:Gem::Version
199
+ version: '1.14'
200
+ type: :development
201
+ prerelease: false
202
+ version_requirements: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - "~>"
205
+ - !ruby/object:Gem::Version
206
+ version: '1.14'
179
207
  description: Opinionated logger which outputs messages in JSON format
180
208
  email:
181
209
  - mumismo@gmail.com
@@ -205,7 +233,7 @@ homepage: https://github.com/JordiPolo/lorekeeper
205
233
  licenses:
206
234
  - MIT
207
235
  metadata: {}
208
- post_install_message:
236
+ post_install_message:
209
237
  rdoc_options: []
210
238
  require_paths:
211
239
  - lib
@@ -220,8 +248,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
248
  - !ruby/object:Gem::Version
221
249
  version: '0'
222
250
  requirements: []
223
- rubygems_version: 3.2.15
224
- signing_key:
251
+ rubygems_version: 3.0.3.1
252
+ signing_key:
225
253
  specification_version: 4
226
254
  summary: Very fast JSON logger
227
255
  test_files: []