dry-logger 1.2.0 → 1.2.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/CHANGELOG.md +22 -0
- data/LICENSE +1 -2
- data/dry-logger.gemspec +2 -0
- data/lib/dry/logger/backends/stream.rb +1 -1
- data/lib/dry/logger/dispatcher.rb +37 -28
- data/lib/dry/logger/entry.rb +0 -1
- data/lib/dry/logger/execution_context.rb +51 -0
- data/lib/dry/logger/formatters/template.rb +13 -2
- data/lib/dry/logger/version.rb +1 -1
- metadata +19 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d5b1c6d122b7cb90cf0e9d2a847056d8a610813e0c5dd6b4496deb1b172781be
|
|
4
|
+
data.tar.gz: 4642ad1fb26e02dd1fb660262819d576ab58c64eb376858ebf3f08fe39248d00
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30a77024ebe05dcfc86d6b44e5c3e0262f1a6d27ad8ad4e298e38d763366f8ed3a176014e37b0cc6904dfebee34a18f73a6a13fa61a03d788caf79501a0ddb38
|
|
7
|
+
data.tar.gz: 498b41ab0fd5cd03bf79b8a04ef7a528ba90294777b0f24e427933f77f75880a5297c1a0252a079156fafe274cb05a0528abafe997c08b318b0a2b6d88cd7b53
|
data/CHANGELOG.md
CHANGED
|
@@ -19,6 +19,28 @@ and this project adheres to [Break Versioning](https://www.taoensso.com/break-ve
|
|
|
19
19
|
|
|
20
20
|
### Security
|
|
21
21
|
|
|
22
|
+
[Unreleased]: https://github.com/dry-rb/dry-logger/compare/v1.2.2...main
|
|
23
|
+
|
|
24
|
+
## [1.2.2] - 2026-03-13
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Exception when message and metadata have different encodings (@katafrakt in #40)
|
|
29
|
+
|
|
30
|
+
[1.2.2]: https://github.com/dry-rb/dry-logger/compare/v1.2.1...v1.2.2
|
|
31
|
+
|
|
32
|
+
## [1.2.1] - 2025-12-16
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- Support Ruby 4.0 by adding the `"logger"` gem to the list of runtime dependencies. (@timriley in #39)
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- Ensure changes to `logger.context` and calls to `logger.tagged` are threadsafe. (@timriley in #38)
|
|
41
|
+
|
|
42
|
+
[1.2.1]: https://github.com/dry-rb/dry-logger/compare/v1.2.0...v1.2.1
|
|
43
|
+
|
|
22
44
|
## [1.2.0] - 2025-11-05
|
|
23
45
|
|
|
24
46
|
### Changed
|
data/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2015-
|
|
3
|
+
Copyright (c) 2015-2026 Hanakai team
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
6
|
this software and associated documentation files (the "Software"), to deal in
|
|
@@ -18,4 +18,3 @@ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
|
18
18
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
19
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
20
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
-
|
data/dry-logger.gemspec
CHANGED
|
@@ -6,6 +6,7 @@ require "pathname"
|
|
|
6
6
|
require "dry/logger/constants"
|
|
7
7
|
require "dry/logger/backends/proxy"
|
|
8
8
|
require "dry/logger/entry"
|
|
9
|
+
require "dry/logger/execution_context"
|
|
9
10
|
|
|
10
11
|
module Dry
|
|
11
12
|
module Logger
|
|
@@ -18,18 +19,6 @@ module Dry
|
|
|
18
19
|
# @api private
|
|
19
20
|
attr_reader :id
|
|
20
21
|
|
|
21
|
-
# (EXPERIMENTAL) Shared payload context
|
|
22
|
-
#
|
|
23
|
-
# @example
|
|
24
|
-
# logger.context[:component] = "test"
|
|
25
|
-
#
|
|
26
|
-
# logger.info "Hello World"
|
|
27
|
-
# # Hello World component=test
|
|
28
|
-
#
|
|
29
|
-
# @since 1.0.0
|
|
30
|
-
# @api public
|
|
31
|
-
attr_reader :context
|
|
32
|
-
|
|
33
22
|
# @since 1.0.0
|
|
34
23
|
# @api private
|
|
35
24
|
attr_reader :backends
|
|
@@ -64,7 +53,9 @@ module Dry
|
|
|
64
53
|
severity: "FATAL",
|
|
65
54
|
progname: progname,
|
|
66
55
|
time: Time.now,
|
|
67
|
-
log_entry: [message, payload].map
|
|
56
|
+
log_entry: [message, payload].map { |s|
|
|
57
|
+
s.to_s.encode("UTF-8", invalid: :replace, undef: :replace, replace: "?")
|
|
58
|
+
}.reject(&:empty?).join(SEPARATOR),
|
|
68
59
|
exception: exception.class,
|
|
69
60
|
message: exception.message,
|
|
70
61
|
backtrace: TAB + exception.backtrace.join(NEW_LINE + TAB)
|
|
@@ -86,21 +77,13 @@ module Dry
|
|
|
86
77
|
|
|
87
78
|
# @since 1.0.0
|
|
88
79
|
# @api private
|
|
89
|
-
def
|
|
90
|
-
Thread.current[:__dry_logger__] ||= {}
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# @since 1.0.0
|
|
94
|
-
# @api private
|
|
95
|
-
def initialize(
|
|
96
|
-
id, backends: [], tags: [], context: self.class.default_context, **options
|
|
97
|
-
)
|
|
80
|
+
def initialize(id, backends: [], tags: [], context: {}, **options)
|
|
98
81
|
@id = id
|
|
99
82
|
@backends = backends
|
|
100
83
|
@options = {**options, progname: id}
|
|
101
84
|
@mutex = Mutex.new
|
|
102
|
-
@
|
|
103
|
-
@
|
|
85
|
+
@default_tags = tags.freeze
|
|
86
|
+
@default_context = context.freeze
|
|
104
87
|
@clock = Clock.new(**(options[:clock] || EMPTY_HASH))
|
|
105
88
|
@on_crash = options[:on_crash] || ON_CRASH
|
|
106
89
|
end
|
|
@@ -226,7 +209,7 @@ module Dry
|
|
|
226
209
|
clock: clock,
|
|
227
210
|
progname: progname,
|
|
228
211
|
severity: severity,
|
|
229
|
-
tags:
|
|
212
|
+
tags: current_tags,
|
|
230
213
|
message: message,
|
|
231
214
|
payload: {**context, **payload}
|
|
232
215
|
)
|
|
@@ -244,7 +227,22 @@ module Dry
|
|
|
244
227
|
true
|
|
245
228
|
end
|
|
246
229
|
|
|
247
|
-
#
|
|
230
|
+
# Shared payload context
|
|
231
|
+
#
|
|
232
|
+
# @example
|
|
233
|
+
# logger.context[:component] = "test"
|
|
234
|
+
#
|
|
235
|
+
# logger.info "Hello World"
|
|
236
|
+
# # Hello World component=test
|
|
237
|
+
#
|
|
238
|
+
# @since 1.0.0
|
|
239
|
+
# @api public
|
|
240
|
+
def context
|
|
241
|
+
@context_key ||= :"context_#{object_id}"
|
|
242
|
+
ExecutionContext[@context_key] ||= @default_context.dup
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Tagged logging withing the provided block
|
|
248
246
|
#
|
|
249
247
|
# @example
|
|
250
248
|
# logger.tagged("red") do
|
|
@@ -258,10 +256,10 @@ module Dry
|
|
|
258
256
|
# @since 1.0.0
|
|
259
257
|
# @api public
|
|
260
258
|
def tagged(*tags)
|
|
261
|
-
|
|
259
|
+
tags_stack.push(tags)
|
|
262
260
|
yield
|
|
263
261
|
ensure
|
|
264
|
-
|
|
262
|
+
tags_stack.pop
|
|
265
263
|
end
|
|
266
264
|
|
|
267
265
|
# Add a new backend to an existing dispatcher
|
|
@@ -310,6 +308,17 @@ module Dry
|
|
|
310
308
|
each_backend { |backend| backend.public_send(meth, ...) }
|
|
311
309
|
true
|
|
312
310
|
end
|
|
311
|
+
|
|
312
|
+
private
|
|
313
|
+
|
|
314
|
+
def tags_stack
|
|
315
|
+
@tags_key ||= :"tags_#{object_id}"
|
|
316
|
+
ExecutionContext[@tags_key] ||= @default_tags.dup
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def current_tags
|
|
320
|
+
tags_stack.flatten
|
|
321
|
+
end
|
|
313
322
|
end
|
|
314
323
|
end
|
|
315
324
|
end
|
data/lib/dry/logger/entry.rb
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module Logger
|
|
5
|
+
# Provides isolated thread-local storage for logger values.
|
|
6
|
+
#
|
|
7
|
+
# @api private
|
|
8
|
+
module ExecutionContext
|
|
9
|
+
CONTEXT_KEY = :__dry_logger__
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
# Returns a value from the current execution context.
|
|
13
|
+
#
|
|
14
|
+
# @param key [Symbol] the key to retrieve
|
|
15
|
+
#
|
|
16
|
+
# @return [Object, nil] the stored value, or nil if no value has been stored
|
|
17
|
+
def [](key)
|
|
18
|
+
context[key]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Sets a value in the current execution context.
|
|
22
|
+
#
|
|
23
|
+
# @param key [Symbol] the key to store
|
|
24
|
+
# @param value [Object] the value to store
|
|
25
|
+
#
|
|
26
|
+
# @return [Object] the stored value
|
|
27
|
+
def []=(key, value)
|
|
28
|
+
context[key] = value
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Clears all values from the current execution context.
|
|
32
|
+
#
|
|
33
|
+
# @return [self]
|
|
34
|
+
def clear
|
|
35
|
+
current_store[CONTEXT_KEY] = {}
|
|
36
|
+
self
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def context
|
|
42
|
+
current_store[CONTEXT_KEY] ||= {}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def current_store
|
|
46
|
+
Thread.current
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -68,8 +68,19 @@ module Dry
|
|
|
68
68
|
|
|
69
69
|
# @since 1.0.0
|
|
70
70
|
# @api private
|
|
71
|
-
def %(
|
|
72
|
-
|
|
71
|
+
def %(other)
|
|
72
|
+
begin
|
|
73
|
+
output = value % other
|
|
74
|
+
rescue Encoding::CompatibilityError
|
|
75
|
+
sanitized_tokens = other.transform_values { |v|
|
|
76
|
+
if v.respond_to?(:encode)
|
|
77
|
+
v.encode("UTF-8", invalid: :replace, undef: :replace, replace: "?")
|
|
78
|
+
else
|
|
79
|
+
v
|
|
80
|
+
end
|
|
81
|
+
}
|
|
82
|
+
output = value % sanitized_tokens
|
|
83
|
+
end
|
|
73
84
|
output.strip!
|
|
74
85
|
output.split(NEW_LINE).map(&:rstrip).join(NEW_LINE)
|
|
75
86
|
end
|
data/lib/dry/logger/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dry-logger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hanakai team
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: logger
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
13
26
|
- !ruby/object:Gem::Dependency
|
|
14
27
|
name: bundler
|
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -58,9 +71,9 @@ email:
|
|
|
58
71
|
executables: []
|
|
59
72
|
extensions: []
|
|
60
73
|
extra_rdoc_files:
|
|
61
|
-
- README.md
|
|
62
74
|
- CHANGELOG.md
|
|
63
75
|
- LICENSE
|
|
76
|
+
- README.md
|
|
64
77
|
files:
|
|
65
78
|
- CHANGELOG.md
|
|
66
79
|
- LICENSE
|
|
@@ -76,6 +89,7 @@ files:
|
|
|
76
89
|
- lib/dry/logger/constants.rb
|
|
77
90
|
- lib/dry/logger/dispatcher.rb
|
|
78
91
|
- lib/dry/logger/entry.rb
|
|
92
|
+
- lib/dry/logger/execution_context.rb
|
|
79
93
|
- lib/dry/logger/filter.rb
|
|
80
94
|
- lib/dry/logger/formatters/colors.rb
|
|
81
95
|
- lib/dry/logger/formatters/json.rb
|
|
@@ -94,7 +108,6 @@ metadata:
|
|
|
94
108
|
source_code_uri: https://github.com/dry-rb/dry-logger
|
|
95
109
|
bug_tracker_uri: https://github.com/dry-rb/dry-logger/issues
|
|
96
110
|
funding_uri: https://github.com/sponsors/hanami
|
|
97
|
-
post_install_message:
|
|
98
111
|
rdoc_options: []
|
|
99
112
|
require_paths:
|
|
100
113
|
- lib
|
|
@@ -109,8 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
109
122
|
- !ruby/object:Gem::Version
|
|
110
123
|
version: '0'
|
|
111
124
|
requirements: []
|
|
112
|
-
rubygems_version: 3.
|
|
113
|
-
signing_key:
|
|
125
|
+
rubygems_version: 3.6.9
|
|
114
126
|
specification_version: 4
|
|
115
127
|
summary: Lightweight structured logging for Ruby applications
|
|
116
128
|
test_files: []
|