lorekeeper 2.2.1 → 2.3.2
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 +2 -0
- data/.rubocop.yml +39 -3
- data/CHANGELOG.md +12 -0
- data/Gemfile +2 -0
- data/Rakefile +3 -1
- data/bin/console +1 -0
- data/lib/lorekeeper/fast_logger.rb +25 -19
- data/lib/lorekeeper/json_logger.rb +27 -11
- data/lib/lorekeeper/multi_logger.rb +0 -10
- data/lib/lorekeeper/simple_logger.rb +11 -4
- data/lib/lorekeeper/version.rb +1 -1
- data/lorekeeper.gemspec +2 -0
- metadata +30 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 53332589726c07831fc34d3d63b7517de62fd1a75c11d1cbf772b6088d125eed
|
|
4
|
+
data.tar.gz: 797d799f0268b110fe584ead9bdb9f9c3f779bca7d1e8d0fb75c796409a340c5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c773417845d13a54058bd01b1541a64fa9564bce845fec21efcd69fa23916a323da0c679d86e8950c7c7dea1fa7c4a18e02429f21b4d896c670d4bb952ade48e
|
|
7
|
+
data.tar.gz: f95030ee5fe64f4cecd0cd9b15217897324bf2ac6aca1daed1a20a8daea233c029412a6a021dddd8bcd7d75d94aee673aa531f35bc8a214b6c07a0e666fca377
|
data/.github/workflows/build.yml
CHANGED
|
@@ -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,15 @@
|
|
|
1
|
+
# 2.3.2
|
|
2
|
+
* Ensure additional fields are reset after logging
|
|
3
|
+
* Let Oj fallback to :object mode for non-representable data
|
|
4
|
+
* Fix SimpleLogger to handle non-String log messages
|
|
5
|
+
* Run RuboCop checks on build and fix RuboCop offenses
|
|
6
|
+
|
|
7
|
+
# 2.3.1
|
|
8
|
+
* Fix MultiLogger to not raise ArgumentError
|
|
9
|
+
|
|
10
|
+
# 2.3.0
|
|
11
|
+
* Add `#write` method support to all loggers
|
|
12
|
+
|
|
1
13
|
# 2.2.1
|
|
2
14
|
* Fix MultiLogger to not raise NoMethodError
|
|
3
15
|
|
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'
|
data/bin/console
CHANGED
|
@@ -5,9 +5,9 @@ require 'logger'
|
|
|
5
5
|
module Lorekeeper
|
|
6
6
|
# Very simple, very fast logger
|
|
7
7
|
class FastLogger
|
|
8
|
-
include ::Logger::Severity
|
|
9
|
-
attr_accessor :level
|
|
10
|
-
|
|
8
|
+
include ::Logger::Severity # contains the levels constants: DEBUG, ERROR, etc.
|
|
9
|
+
attr_accessor :level, # Current level, default: DEBUG
|
|
10
|
+
:formatter # Just for compatibility with Logger, not used
|
|
11
11
|
|
|
12
12
|
def debug?; level <= DEBUG; end
|
|
13
13
|
def info?; level <= INFO; end
|
|
@@ -21,12 +21,12 @@ module Lorekeeper
|
|
|
21
21
|
@file = file # We only keep this so we can inspect where we are sending the logs
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
LOGGING_METHODS = [
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
LOGGING_METHODS = %i[
|
|
25
|
+
debug
|
|
26
|
+
info
|
|
27
|
+
warn
|
|
28
|
+
error
|
|
29
|
+
fatal
|
|
30
30
|
].freeze
|
|
31
31
|
|
|
32
32
|
METHOD_SEVERITY_MAP = {
|
|
@@ -56,7 +56,8 @@ module Lorekeeper
|
|
|
56
56
|
# This is part of the standard Logger API, we need this to be compatible
|
|
57
57
|
def add(severity, message_param = nil, progname = nil, &block)
|
|
58
58
|
return true if severity < @level
|
|
59
|
-
|
|
59
|
+
|
|
60
|
+
message = block&.call || message_param || progname
|
|
60
61
|
log_data(severity, message.freeze)
|
|
61
62
|
end
|
|
62
63
|
|
|
@@ -65,20 +66,22 @@ module Lorekeeper
|
|
|
65
66
|
# To avoid needing to monkey-patch Lorekeeper just to get this method, we are adding a simple
|
|
66
67
|
# non-functional version here.
|
|
67
68
|
def silence_logger(&block)
|
|
68
|
-
yield if
|
|
69
|
+
yield if block
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
# activerecord-session_store v2 is now simply calling silence instead of silence_logger
|
|
72
73
|
def silence(&block)
|
|
73
|
-
yield if
|
|
74
|
+
yield if block
|
|
74
75
|
end
|
|
75
76
|
|
|
76
77
|
# inherited classes probably want to reimplement this
|
|
77
78
|
def log_data(_severity, message)
|
|
78
|
-
|
|
79
|
+
write(message)
|
|
79
80
|
end
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
def write(message)
|
|
83
|
+
@iodevice.write(message)
|
|
84
|
+
end
|
|
82
85
|
|
|
83
86
|
require 'monitor'
|
|
84
87
|
# Mutex to avoid broken lines when multiple threads access the log file
|
|
@@ -106,11 +109,12 @@ module Lorekeeper
|
|
|
106
109
|
def to_iodevice(file)
|
|
107
110
|
return nil unless file
|
|
108
111
|
|
|
109
|
-
iodevice =
|
|
110
|
-
file
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
iodevice =
|
|
113
|
+
if file.respond_to?(:write) && file.respond_to?(:close)
|
|
114
|
+
file
|
|
115
|
+
else
|
|
116
|
+
open_logfile(file)
|
|
117
|
+
end
|
|
114
118
|
|
|
115
119
|
iodevice.sync = true if iodevice.respond_to?(:sync=)
|
|
116
120
|
iodevice
|
|
@@ -128,5 +132,7 @@ module Lorekeeper
|
|
|
128
132
|
open_logfile(filename)
|
|
129
133
|
end
|
|
130
134
|
end
|
|
135
|
+
|
|
136
|
+
private_constant :LogDeviceMutex, :LogDevice
|
|
131
137
|
end
|
|
132
138
|
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
|
|
@@ -94,8 +95,22 @@ module Lorekeeper
|
|
|
94
95
|
"Lorekeeper JSON logger. IO: #{@file.inspect}"
|
|
95
96
|
end
|
|
96
97
|
|
|
98
|
+
def write(message)
|
|
99
|
+
super(json_message(message) << "\n")
|
|
100
|
+
end
|
|
101
|
+
|
|
97
102
|
private
|
|
98
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
|
+
|
|
99
114
|
# Some instrumentation libraries pollute the stacktrace and create a large output which may
|
|
100
115
|
# cause problems with certain logging backends.
|
|
101
116
|
# Hardcording newrelic, active_support/callbacks and zipkin-tracer now here.
|
|
@@ -126,12 +141,13 @@ module Lorekeeper
|
|
|
126
141
|
def with_extra_fields(fields)
|
|
127
142
|
state[:extra_fields] = fields
|
|
128
143
|
yield
|
|
144
|
+
ensure
|
|
129
145
|
state[:extra_fields] = {}
|
|
130
146
|
end
|
|
131
147
|
|
|
132
148
|
def remove_invalid_fields(fields)
|
|
133
149
|
fields.delete_if do |_, v|
|
|
134
|
-
v.nil? || v.respond_to?(:empty?) && v.empty?
|
|
150
|
+
v.nil? || (v.respond_to?(:empty?) && v.empty?)
|
|
135
151
|
end
|
|
136
152
|
end
|
|
137
153
|
|
|
@@ -139,16 +155,16 @@ module Lorekeeper
|
|
|
139
155
|
current_state = state # Accessing state is slow. Do it only once per call.
|
|
140
156
|
# merging is slow, we do not want to merge with empty hash if possible
|
|
141
157
|
fields_to_log = if current_state[:extra_fields].empty?
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
158
|
+
current_state[:base_fields]
|
|
159
|
+
else
|
|
160
|
+
current_state[:base_fields].merge(current_state[:extra_fields])
|
|
161
|
+
end
|
|
146
162
|
|
|
147
163
|
fields_to_log[MESSAGE] = message
|
|
148
164
|
fields_to_log[TIMESTAMP] = Time.now.utc.strftime(DATE_FORMAT)
|
|
149
165
|
fields_to_log[LEVEL] = SEVERITY_NAMES_MAP[severity]
|
|
150
166
|
|
|
151
|
-
|
|
167
|
+
write(fields_to_log)
|
|
152
168
|
end
|
|
153
169
|
end
|
|
154
170
|
end
|
|
@@ -19,24 +19,14 @@ module Lorekeeper
|
|
|
19
19
|
# Define all common logging methods within Multilogger to avoid NoMethodError
|
|
20
20
|
def debug(*args, &block); call_loggers(:debug, *args, &block); end
|
|
21
21
|
|
|
22
|
-
def debug_with_data(*args, &block); call_loggers(:debug, *args, &block); end
|
|
23
|
-
|
|
24
22
|
def info(*args, &block); call_loggers(:info, *args, &block); end
|
|
25
23
|
|
|
26
|
-
def info_with_data(*args, &block); call_loggers(:info, *args, &block); end
|
|
27
|
-
|
|
28
24
|
def warn(*args, &block); call_loggers(:warn, *args, &block); end
|
|
29
25
|
|
|
30
|
-
def warn_with_data(*args, &block); call_loggers(:warn, *args, &block); end
|
|
31
|
-
|
|
32
26
|
def error(*args, &block); call_loggers(:error, *args, &block); end
|
|
33
27
|
|
|
34
|
-
def error_with_data(*args, &block); call_loggers(:error, *args, &block); end
|
|
35
|
-
|
|
36
28
|
def fatal(*args, &block); call_loggers(:fatal, *args, &block); end
|
|
37
29
|
|
|
38
|
-
def fatal_with_data(*args, &block); call_loggers(:fatal, *args, &block); end
|
|
39
|
-
|
|
40
30
|
def write(*args); call_loggers(:write, *args); end
|
|
41
31
|
|
|
42
32
|
def respond_to?(method, all_included: false)
|
|
@@ -28,7 +28,8 @@ 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
|
-
|
|
31
|
+
message = message.to_s
|
|
32
|
+
write("\e[#{color}m#{message.gsub('\n', "\n").gsub('\t', "\t")}\e[0m\n")
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
def inspect
|
|
@@ -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.2
|
|
4
|
+
version: 2.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jordi Polo
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-08-
|
|
11
|
+
date: 2022-08-23 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
|