contextual_logger 1.2.0.colin.4 → 1.2.0.colin.5
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:
|
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
|