contextual_logger 1.2.0.colin.4 → 1.2.0.colin.5
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
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4b2dc21d1f78b3b6a4a70a782e717eb607ace39fbb085f68fe5c5fee1086e9e
|
4
|
+
data.tar.gz: 17422f6d289ab064d5b212b057870da7c6e283cf24fcf3d419874caf2621b923
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15ff319daf3bcd7c4fd6a9c815cdfc394af288749c52c583fb522d571915fb1fe4bc888a9db8ff0040e4d509a37c9027610aa41a3fa59bcec46dfb551045bd81
|
7
|
+
data.tar.gz: 4a7ebd9b1b4f37a950d8cbea6b87ad797264701b87e349246c1bce4edfb0743ed3557c827545665a8c84a37c43c4062aeefced0b76880e558084278093bc26fb
|
@@ -2,17 +2,20 @@
|
|
2
2
|
|
3
3
|
module ContextualLogger
|
4
4
|
module Context
|
5
|
-
|
5
|
+
EMPTY_CONTEXT = {}.freeze
|
6
|
+
|
7
|
+
def thread_context_key_for_logger_instance
|
6
8
|
# We include the object_id here to make these thread/fiber locals unique per logger instance.
|
7
|
-
@
|
9
|
+
@thread_context_key_for_logger_instance ||= "ContextualLogger::Context.context_for_#{object_id}".to_sym
|
8
10
|
end
|
9
11
|
|
10
12
|
def current_context_override
|
11
|
-
|
13
|
+
ContextualLogger.global_context_lock_message ||= "ContextualLogger::Context.current_context_override set for #{self.class.name} #{object_id}"
|
14
|
+
Thread.current[thread_context_key_for_logger_instance]
|
12
15
|
end
|
13
16
|
|
14
17
|
def current_context_override=(context_override)
|
15
|
-
Thread.current[
|
18
|
+
Thread.current[thread_context_key_for_logger_instance] = context_override.freeze
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
@@ -6,6 +6,13 @@ module ContextualLogger
|
|
6
6
|
# A logger that deep_merges additional context and then delegates to the given logger.
|
7
7
|
# Keeps it own log level (called override_level) that may be set independently of the logger it delegates to.
|
8
8
|
# If override_level is non-nil, it takes precedence; if it is nil (the default), then it delegates to the logger.
|
9
|
+
#
|
10
|
+
# Context Precedence:
|
11
|
+
# 1. inline **context passed to the logger method
|
12
|
+
# 2. `with_context` overrides on this LoggerWithContext object
|
13
|
+
# 3. context passed to this LoggerWithContext constructor
|
14
|
+
# 4. `with_context` overrides on the logger passed to this constructor
|
15
|
+
# 5. `global_context` set on the logger passed to this constructor
|
9
16
|
class LoggerWithContext
|
10
17
|
include LoggerMixin
|
11
18
|
|
@@ -16,11 +23,13 @@ module ContextualLogger
|
|
16
23
|
@logger = logger
|
17
24
|
self.level = level
|
18
25
|
@context = normalize_context(context)
|
19
|
-
@merged_context_cache = {} # so we don't have to merge every time
|
20
26
|
end
|
21
27
|
|
28
|
+
# TODO: It's a (small) bug that the global_context is memoized at this point. There's a chance that the @logger.current_context
|
29
|
+
# changes after this because of an enclosing @logger.with_context block. If that happens, we'll miss that extra context.
|
30
|
+
# The tradeoff is that we don't want to keep calling deep_merge.
|
22
31
|
def global_context
|
23
|
-
@logger.
|
32
|
+
@global_context ||= @logger.current_context.deep_merge(@context) # this will include any with_context overrides on the `logger`
|
24
33
|
end
|
25
34
|
|
26
35
|
def level
|
@@ -33,10 +42,10 @@ module ContextualLogger
|
|
33
42
|
|
34
43
|
def write_entry_to_log(severity, timestamp, progname, message, context:)
|
35
44
|
merged_context =
|
36
|
-
if
|
37
|
-
|
45
|
+
if context.any?
|
46
|
+
current_context.deep_merge(context)
|
38
47
|
else
|
39
|
-
|
48
|
+
current_context
|
40
49
|
end
|
41
50
|
|
42
51
|
@logger.write_entry_to_log(severity, timestamp, progname, message, context: merged_context)
|
data/lib/contextual_logger.rb
CHANGED
@@ -6,6 +6,7 @@ require 'json'
|
|
6
6
|
require_relative './contextual_logger/redactor'
|
7
7
|
require_relative './contextual_logger/context'
|
8
8
|
require_relative './contextual_logger/context_handler'
|
9
|
+
require_relative './contextual_logger/global_context_lock_message'
|
9
10
|
|
10
11
|
module ContextualLogger
|
11
12
|
LOG_LEVEL_NAMES_TO_SEVERITY =
|
@@ -43,16 +44,23 @@ module ContextualLogger
|
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
47
|
+
# Context Precedence when this is mixed into a logger:
|
48
|
+
# 1. inline **context passed to the logger method
|
49
|
+
# 2. `with_context` overrides on the logger object
|
50
|
+
# 3. `global_context` set on the logger passed to this constructor
|
46
51
|
module LoggerMixin
|
47
52
|
include Context
|
48
53
|
|
49
54
|
delegate :register_secret, :register_secret_regex, to: :redactor
|
50
55
|
|
51
56
|
def global_context
|
52
|
-
@global_context ||=
|
57
|
+
@global_context ||= Context::EMPTY_CONTEXT
|
53
58
|
end
|
54
59
|
|
55
60
|
def global_context=(context)
|
61
|
+
if (global_context_lock_message = ::ContextualLogger.global_context_lock_message)
|
62
|
+
raise ::ContextualLogger::GlobalContextIsLocked, global_context_lock_message
|
63
|
+
end
|
56
64
|
@global_context = context.freeze
|
57
65
|
end
|
58
66
|
|
@@ -63,18 +71,19 @@ module ContextualLogger
|
|
63
71
|
# TODO: Deprecate current_context_for_thread in v2.0.
|
64
72
|
alias current_context_for_thread current_context
|
65
73
|
|
66
|
-
def with_context(
|
67
|
-
|
68
|
-
self.current_context_override =
|
74
|
+
def with_context(stacked_context)
|
75
|
+
context_handler = ContextHandler.new(self, self.current_context_override)
|
76
|
+
self.current_context_override = deep_merge_with_current_context(stacked_context)
|
77
|
+
|
69
78
|
if block_given?
|
70
79
|
begin
|
71
80
|
yield
|
72
81
|
ensure
|
73
|
-
|
82
|
+
context_handler.reset!
|
74
83
|
end
|
75
84
|
else
|
76
85
|
# If no block given, return context handler to the caller so they can call reset! themselves.
|
77
|
-
|
86
|
+
context_handler
|
78
87
|
end
|
79
88
|
end
|
80
89
|
|
@@ -112,7 +121,7 @@ module ContextualLogger
|
|
112
121
|
|
113
122
|
# Note that this interface needs to stay compatible with the underlying ::Logger#add interface,
|
114
123
|
# which is: def add(severity, message = nil, progname = nil)
|
115
|
-
def add(arg_severity, arg1 = nil, arg2 = nil, **context) # Ruby will prefer to match hashes
|
124
|
+
def add(arg_severity, arg1 = nil, arg2 = nil, **context) # Ruby will prefer to match hashes to last argument because of **
|
116
125
|
severity = arg_severity || UNKNOWN
|
117
126
|
if log_level_enabled?(severity)
|
118
127
|
if arg1.nil?
|
@@ -127,7 +136,7 @@ module ContextualLogger
|
|
127
136
|
message = arg1
|
128
137
|
progname = arg2 || @progname
|
129
138
|
end
|
130
|
-
write_entry_to_log(severity, Time.now, progname, message, context:
|
139
|
+
write_entry_to_log(severity, Time.now, progname, message, context: deep_merge_with_current_context(context))
|
131
140
|
end
|
132
141
|
|
133
142
|
true
|
@@ -151,7 +160,7 @@ module ContextualLogger
|
|
151
160
|
normalized_message = ContextualLogger.normalize_message(message)
|
152
161
|
normalized_progname = ContextualLogger.normalize_message(progname) unless progname.nil?
|
153
162
|
if @formatter
|
154
|
-
@formatter.call(severity, timestamp, normalized_progname, { message: normalized_message }
|
163
|
+
@formatter.call(severity, timestamp, normalized_progname, { message: normalized_message, **context })
|
155
164
|
else
|
156
165
|
"#{basic_json_log_entry(severity, timestamp, normalized_progname, normalized_message, context: context)}\n"
|
157
166
|
end
|
@@ -161,12 +170,20 @@ module ContextualLogger
|
|
161
170
|
message_hash = {
|
162
171
|
message: normalized_progname ? "#{normalized_progname}: #{normalized_message}" : normalized_message,
|
163
172
|
severity: severity,
|
164
|
-
timestamp: timestamp
|
173
|
+
timestamp: timestamp,
|
174
|
+
**context
|
165
175
|
}
|
166
176
|
message_hash[:progname] = normalized_progname if normalized_progname
|
167
177
|
|
168
|
-
|
169
|
-
|
178
|
+
message_hash.to_json
|
179
|
+
end
|
180
|
+
|
181
|
+
def deep_merge_with_current_context(stacked_context)
|
182
|
+
if stacked_context.any?
|
183
|
+
current_context.deep_merge(stacked_context)
|
184
|
+
else
|
185
|
+
current_context
|
186
|
+
end
|
170
187
|
end
|
171
188
|
end
|
172
189
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contextual_logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.0.colin.
|
4
|
+
version: 1.2.0.colin.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Ebentier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -47,6 +47,7 @@ files:
|
|
47
47
|
- lib/contextual_logger.rb
|
48
48
|
- lib/contextual_logger/context.rb
|
49
49
|
- lib/contextual_logger/context_handler.rb
|
50
|
+
- lib/contextual_logger/global_context_lock_message.rb
|
50
51
|
- lib/contextual_logger/logger_with_context.rb
|
51
52
|
- lib/contextual_logger/overrides/active_support/tagged_logging/formatter.rb
|
52
53
|
- lib/contextual_logger/redactor.rb
|