lorekeeper 2.3.1 → 2.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.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +3 -1
- data/.rubocop.yml +39 -3
- data/CHANGELOG.md +10 -0
- data/Gemfile +2 -0
- data/Rakefile +4 -2
- data/bin/console +1 -0
- data/bin/setup +0 -0
- data/lib/lorekeeper/fast_logger.rb +50 -19
- data/lib/lorekeeper/json_logger.rb +23 -11
- data/lib/lorekeeper/simple_logger.rb +10 -3
- data/lib/lorekeeper/version.rb +1 -1
- data/lorekeeper.gemspec +2 -0
- metadata +34 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8099634bb3a3f3d4d348737b0c9634a3a70743c1d868ebec42c194865df7a13c
|
4
|
+
data.tar.gz: c216efb9f7f6c2e06c357aee59d1f0ad8299445c5becc0d8fc4f2d444e5193ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93af9f7d3142bdc8166a14e2324b71fe3e51c3f150ea2fccee8557fc2d17b92517b3d6214e8021ed86bdbf632bed836b12027bf438f4bba0099ef1bbaed32e63
|
7
|
+
data.tar.gz: d81128b6905c1f70e7946bf7be63bf35923d40056d9c9ab7274397b7ff8726da582109f83c0c2905768c0c694ac48c2fa8574dd894f10a0b60d6c3b0ac28dfbb
|
data/.github/workflows/build.yml
CHANGED
@@ -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
|
-
|
2
|
-
|
3
|
-
|
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
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('
|
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
|
-
|
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
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
|
9
|
-
attr_accessor :
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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 <
|
59
|
-
|
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
|
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
|
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
|
-
|
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 =
|
114
|
-
file
|
115
|
-
|
116
|
-
|
117
|
-
|
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)
|
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)
|
35
|
+
with_extra_fields(extra_fields) do
|
35
36
|
add(METHOD_SEVERITY_MAP[method_name], message_param, nil, &block)
|
36
|
-
|
37
|
-
|
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
|
-
|
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(
|
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
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
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 = {}
|
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
|
-
|
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
|
-
|
62
|
+
message: nil, data: nil, level: nil)
|
56
63
|
|
57
64
|
param_level = level || custom_level
|
58
65
|
param_data = data || custom_data
|
data/lib/lorekeeper/version.rb
CHANGED
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.
|
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:
|
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.
|
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: []
|