activesupport-json_logging 1.3.0 → 1.3.1
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 +15 -0
- data/README.md +4 -4
- data/lib/json_logging/event_subscriber.rb +6 -2
- data/lib/json_logging/line_encoder.rb +0 -8
- data/lib/json_logging/message_parser.rb +2 -0
- data/lib/json_logging/sanitizer.rb +27 -36
- data/lib/json_logging/sanitizer_hash_limit.rb +42 -0
- data/lib/json_logging/structured_hash_json_encoder.rb +1 -36
- data/lib/json_logging/structured_hash_sanitizer.rb +3 -12
- data/lib/json_logging/version.rb +1 -1
- metadata +16 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8860a79aadc768a5173400d8c56041edde0fcd66b9e3f2f50e4918956c31b451
|
|
4
|
+
data.tar.gz: 07420fcc1f8aa91271ebf0484a338b921dba8fd41c16e2e50adf789a9eaaed33
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: df9baad44f3b33dce3e18b795691fd6e7d8d620930826d2d9e423808b266b294b6ab3355619df9a2a406d51c7c0d3338be984599871579fbc67b69c5fc198a42
|
|
7
|
+
data.tar.gz: c93486338ce6906fb91bd96b55732a67525883971d7b7551690b34a4280337482160c096459b63623f0c2e629cb41b6af028fa008b274fc756137e5f21fc9958
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 1.3.1 (2026-09-04)
|
|
6
|
+
|
|
7
|
+
- Copy large structured hashes before Rails parameter filtering so caller fields stay intact
|
|
8
|
+
- Keep original key names on the large-hash encoder path when a Rails parameter filter is present
|
|
9
|
+
- Isolate nested hashes in `with_context` from later caller mutations
|
|
10
|
+
- Match fallback sensitive-key detection to Rails default filter substrings including email, otp, ssn, token, and credentials
|
|
11
|
+
- Rebuild the compiled Rails parameter filter after in-place `filter_parameters` changes
|
|
12
|
+
- Treat JSON object and array strings longer than 10,000 characters as truncated text
|
|
13
|
+
- Replace home-directory prefixes in log strings and backtraces with a tilde
|
|
14
|
+
- Skip EventSubscriber writes when the logger has INFO disabled; keep the Rails event timestamp as an integer
|
|
15
|
+
- Keep overflow sensitive keys as filtered after the 50-key hash cap without copying their values
|
|
16
|
+
- Require json 2.21.2 or newer
|
|
17
|
+
|
|
3
18
|
## 1.3.0 (2026-07-25)
|
|
4
19
|
|
|
5
20
|
- BREAKING: Require Ruby 3.2+ and Rails 7+ (drop Ruby 2.7–3.1 and Rails 6 support)
|
data/README.md
CHANGED
|
@@ -148,7 +148,7 @@ Or enable the Railtie opt-in (off by default):
|
|
|
148
148
|
config.json_logging.subscribe_event_reporter = true
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
The subscriber writes one JSON line per event and keeps the Rails event shape (`name`, `payload`, `tags`, `context`, `timestamp`, `source_location`). It writes through `Logger#<<` so the logger formatter does not wrap the event again. Payload and tag objects that implement `#serialize` are encoded via that method. Encode and write failures never raise from `#emit`.
|
|
151
|
+
The subscriber writes one JSON line per event and keeps the Rails event shape (`name`, `payload`, `tags`, `context`, `timestamp`, `source_location`). It writes through `Logger#<<` so the logger formatter does not wrap the event again. It skips that write when the logger reports that INFO is disabled (`logger.level` above INFO). An IO destination always writes. `timestamp` stays the Rails event integer (nanoseconds), not the ISO8601 string used by `JsonLoggerExtension`. Payload and tag objects that implement `#serialize` are encoded via that method. Encode and write failures never raise from `#emit`.
|
|
152
152
|
|
|
153
153
|
```ruby
|
|
154
154
|
Rails.event.set_context(request_id: "abc123")
|
|
@@ -616,9 +616,9 @@ logger.reopen # Reopen the logger (if supported by logdev)
|
|
|
616
616
|
## Security & privacy
|
|
617
617
|
|
|
618
618
|
- **Rails ParameterFilter integration**: Automatically uses `Rails.application.config.filter_parameters` to filter sensitive data (passwords, tokens, etc.). This includes encrypted attributes automatically. See [Rails parameter filtering guide](https://thoughtbot.com/blog/parameter-filtering).
|
|
619
|
-
- **Input sanitization**: Removes control characters, truncates long strings, and limits structure depth/size:
|
|
619
|
+
- **Input sanitization**: Removes control characters, truncates long strings, redacts home-directory prefixes to `~`, and limits structure depth/size:
|
|
620
620
|
- Maximum string length: 10,000 characters (truncated with `...[truncated]` suffix)
|
|
621
|
-
- Maximum context hash size: 50 keys (additional keys are truncated)
|
|
621
|
+
- Maximum context hash size: 50 keys (additional keys are truncated; overflow keys that match sensitive patterns or `filter_parameters` still appear as `[FILTERED]`)
|
|
622
622
|
- Maximum nesting depth: 10 levels (deeper structures return `{"error" => "max_depth_exceeded"}`)
|
|
623
623
|
- Maximum backtrace lines: 20 lines per exception
|
|
624
624
|
- **Single-line JSON**: Emits single-line JSON to avoid log injection via newlines
|
|
@@ -632,7 +632,7 @@ This gem automatically uses Rails' `config.filter_parameters` when available. Co
|
|
|
632
632
|
|
|
633
633
|
```ruby
|
|
634
634
|
Rails.application.config.filter_parameters += [
|
|
635
|
-
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
|
|
635
|
+
:passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
|
|
636
636
|
]
|
|
637
637
|
```
|
|
638
638
|
|
|
@@ -121,9 +121,13 @@ module JsonLogging
|
|
|
121
121
|
def write_line(line)
|
|
122
122
|
if @io
|
|
123
123
|
@io.write(line)
|
|
124
|
-
|
|
125
|
-
resolve_logger << line
|
|
124
|
+
return
|
|
126
125
|
end
|
|
126
|
+
|
|
127
|
+
logger = resolve_logger
|
|
128
|
+
return if logger.respond_to?(:info?) && !logger.info?
|
|
129
|
+
|
|
130
|
+
logger << line
|
|
127
131
|
end
|
|
128
132
|
|
|
129
133
|
def resolve_logger
|
|
@@ -223,14 +223,6 @@ module JsonLogging
|
|
|
223
223
|
"#{JSON.generate(payload)}\n"
|
|
224
224
|
end
|
|
225
225
|
|
|
226
|
-
def build_sanitized_hash_payload(message:, severity:, timestamp:)
|
|
227
|
-
hash = message.is_a?(Hash) ? message : message.to_hash
|
|
228
|
-
payload = Sanitizer.sanitize_hash(hash)
|
|
229
|
-
payload["severity"] = severity
|
|
230
|
-
payload["timestamp"] = timestamp
|
|
231
|
-
payload
|
|
232
|
-
end
|
|
233
|
-
|
|
234
226
|
def deep_stringify_structure(obj)
|
|
235
227
|
case obj
|
|
236
228
|
when Hash
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require_relative "structured_hash_sanitizer"
|
|
2
|
+
require_relative "sanitizer_hash_limit"
|
|
2
3
|
|
|
3
4
|
module JsonLogging
|
|
4
5
|
module Sanitizer
|
|
@@ -18,7 +19,7 @@ module JsonLogging
|
|
|
18
19
|
MAX_BACKTRACE_LINES = 20
|
|
19
20
|
|
|
20
21
|
# Common sensitive key patterns (case insensitive) - fallback when Rails ParameterFilter not available
|
|
21
|
-
SENSITIVE_KEY_PATTERNS =
|
|
22
|
+
SENSITIVE_KEY_PATTERNS = /(passw|pwd|email|secret|token|_key|crypt|salt|certificate|otp|ssn|cvv|cvc|credential)/i
|
|
22
23
|
|
|
23
24
|
@parameter_filter = nil
|
|
24
25
|
@parameter_filter_config = nil
|
|
@@ -38,7 +39,7 @@ module JsonLogging
|
|
|
38
39
|
return @parameter_filter
|
|
39
40
|
end
|
|
40
41
|
|
|
41
|
-
@parameter_filter_config = filter_params
|
|
42
|
+
@parameter_filter_config = filter_params.dup.freeze
|
|
42
43
|
@parameter_filter_requires_full_tree_walk = parameter_filter_requires_full_tree_walk?(filter_params)
|
|
43
44
|
@parameter_filter = ActiveSupport::ParameterFilter.new(filter_params)
|
|
44
45
|
rescue
|
|
@@ -76,12 +77,14 @@ module JsonLogging
|
|
|
76
77
|
# Sanitize a string by removing/escaping control characters and truncating
|
|
77
78
|
def sanitize_string(str)
|
|
78
79
|
return str unless str.is_a?(String)
|
|
79
|
-
return str if str.length <= MAX_STRING_LENGTH && !str.match?(CONTROL_CHARS)
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
home_prefix = home_directory_prefix
|
|
82
|
+
has_home_directory = home_prefix && str.include?(home_prefix)
|
|
83
|
+
return str if str.length <= MAX_STRING_LENGTH && !str.match?(CONTROL_CHARS) && !has_home_directory
|
|
84
|
+
|
|
82
85
|
sanitized = str.gsub(CONTROL_CHARS, "")
|
|
86
|
+
sanitized = redact_home_directory(sanitized, home_prefix) if has_home_directory
|
|
83
87
|
|
|
84
|
-
# Truncate if too long
|
|
85
88
|
if sanitized.length > MAX_STRING_LENGTH
|
|
86
89
|
sanitized = sanitized[0, MAX_STRING_LENGTH] + "...[truncated]"
|
|
87
90
|
end
|
|
@@ -91,12 +94,8 @@ module JsonLogging
|
|
|
91
94
|
"<sanitization_error>"
|
|
92
95
|
end
|
|
93
96
|
|
|
94
|
-
# Sanitize a hash, removing sensitive keys and limiting size/depth
|
|
95
|
-
# Uses Rails ParameterFilter when available, falls back to pattern matching
|
|
96
97
|
def sanitize_hash(hash, depth: 0)
|
|
97
98
|
return hash unless hash.is_a?(Hash)
|
|
98
|
-
|
|
99
|
-
# Prevent excessive nesting
|
|
100
99
|
return {"error" => "max_depth_exceeded"} if depth > MAX_DEPTH
|
|
101
100
|
|
|
102
101
|
limited_hash = limited_hash_for_sanitization(hash)
|
|
@@ -109,13 +108,7 @@ module JsonLogging
|
|
|
109
108
|
end
|
|
110
109
|
|
|
111
110
|
def limited_hash_for_sanitization(hash)
|
|
112
|
-
|
|
113
|
-
truncated = hash.first(MAX_CONTEXT_SIZE).to_h
|
|
114
|
-
truncated["_truncated"] = true
|
|
115
|
-
truncated
|
|
116
|
-
else
|
|
117
|
-
hash
|
|
118
|
-
end
|
|
111
|
+
SanitizerHashLimit.apply(hash, filter_config: rails_parameter_filter && @parameter_filter_config)
|
|
119
112
|
end
|
|
120
113
|
|
|
121
114
|
def fast_path_sanitized_hash(hash, depth: 0)
|
|
@@ -126,38 +119,26 @@ module JsonLogging
|
|
|
126
119
|
end
|
|
127
120
|
|
|
128
121
|
def sanitize_hash_with_filtering(limited_hash, depth: 0)
|
|
129
|
-
# Use Rails ParameterFilter if available (handles encrypted attributes automatically)
|
|
130
122
|
filter = rails_parameter_filter
|
|
131
123
|
if filter
|
|
132
|
-
# ParameterFilter
|
|
133
|
-
# This includes encrypted attributes automatically
|
|
134
|
-
# Create a deep copy since filter modifies in place
|
|
124
|
+
# ParameterFilter mutates in place; copy first
|
|
135
125
|
filtered = limited_hash.respond_to?(:deep_dup) ? limited_hash.deep_dup : limited_hash.dup
|
|
136
126
|
filtered = filter.filter(filtered)
|
|
137
|
-
|
|
138
|
-
# Then sanitize values (strings, control chars, etc.) preserving filtered structure
|
|
139
127
|
filtered.each_with_object({}) do |(key, value), result|
|
|
140
128
|
result[key.to_s] = sanitize_value(value, depth: depth + 1)
|
|
141
129
|
end
|
|
142
|
-
|
|
143
130
|
else
|
|
144
|
-
# Fallback: use pattern matching for sensitive keys
|
|
145
131
|
limited_hash.each_with_object({}) do |(key, value), result|
|
|
146
132
|
key_string = key.to_s
|
|
147
|
-
|
|
148
|
-
# Skip sensitive keys
|
|
149
133
|
if SENSITIVE_KEY_PATTERNS.match?(key_string)
|
|
150
134
|
result[sensitive_filtered_key_name(key_string)] = "[FILTERED]"
|
|
151
135
|
next
|
|
152
136
|
end
|
|
153
|
-
|
|
154
137
|
result[key_string] = sanitize_value(value, depth: depth + 1)
|
|
155
138
|
end
|
|
156
139
|
end
|
|
157
140
|
end
|
|
158
141
|
|
|
159
|
-
# Sanitize a value (handles strings, hashes, arrays, etc.)
|
|
160
|
-
# Preserves numeric, boolean, and nil types
|
|
161
142
|
def sanitize_value(value, depth: 0)
|
|
162
143
|
case value
|
|
163
144
|
when String
|
|
@@ -165,24 +146,20 @@ module JsonLogging
|
|
|
165
146
|
when Hash
|
|
166
147
|
sanitize_hash(value, depth: depth)
|
|
167
148
|
when Array
|
|
168
|
-
# Limit array size
|
|
169
149
|
sanitized = value.first(MAX_CONTEXT_SIZE).map { |v| sanitize_value(v, depth: depth + 1) }
|
|
170
150
|
sanitized << "[truncated]" if value.size > MAX_CONTEXT_SIZE
|
|
171
151
|
sanitized
|
|
172
152
|
when Exception
|
|
173
153
|
sanitize_exception(value)
|
|
174
154
|
when Numeric, TrueClass, FalseClass, NilClass
|
|
175
|
-
# Preserve numeric, boolean, and nil types
|
|
176
155
|
value
|
|
177
156
|
else
|
|
178
|
-
# For other types, convert to string and sanitize
|
|
179
157
|
sanitize_string(value.to_s)
|
|
180
158
|
end
|
|
181
159
|
rescue
|
|
182
160
|
"<unprintable>"
|
|
183
161
|
end
|
|
184
162
|
|
|
185
|
-
# Sanitize exception, including backtrace
|
|
186
163
|
def sanitize_exception(ex)
|
|
187
164
|
{
|
|
188
165
|
"error" => {
|
|
@@ -195,11 +172,9 @@ module JsonLogging
|
|
|
195
172
|
{"error" => {"class" => "Exception", "message" => "<sanitization_failed>"}}
|
|
196
173
|
end
|
|
197
174
|
|
|
198
|
-
# Sanitize backtrace - truncate and remove sensitive paths
|
|
199
175
|
def sanitize_backtrace(backtrace)
|
|
200
176
|
return [] unless backtrace.is_a?(Array)
|
|
201
177
|
|
|
202
|
-
# Take first MAX_BACKTRACE_LINES, sanitize each
|
|
203
178
|
backtrace.first(MAX_BACKTRACE_LINES).map do |line|
|
|
204
179
|
sanitize_string(line.to_s)
|
|
205
180
|
end
|
|
@@ -207,7 +182,6 @@ module JsonLogging
|
|
|
207
182
|
[]
|
|
208
183
|
end
|
|
209
184
|
|
|
210
|
-
# Check if a key looks sensitive
|
|
211
185
|
def sensitive_key?(key)
|
|
212
186
|
SENSITIVE_KEY_PATTERNS.match?(key.to_s)
|
|
213
187
|
end
|
|
@@ -255,5 +229,22 @@ module JsonLogging
|
|
|
255
229
|
def sensitive_filtered_key_name(key_string)
|
|
256
230
|
key_string.gsub(/(?<!^)(?=[A-Z])/, "_").downcase + "_filtered"
|
|
257
231
|
end
|
|
232
|
+
|
|
233
|
+
def home_directory_prefix
|
|
234
|
+
prefix = ENV["HOME"]
|
|
235
|
+
prefix = Dir.home if prefix.blank?
|
|
236
|
+
prefix = prefix.to_s.chomp("/").chomp("\\")
|
|
237
|
+
return if prefix.empty?
|
|
238
|
+
|
|
239
|
+
prefix
|
|
240
|
+
rescue ArgumentError, RuntimeError
|
|
241
|
+
nil
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def redact_home_directory(str, prefix)
|
|
245
|
+
return str unless prefix
|
|
246
|
+
|
|
247
|
+
str.gsub(/#{Regexp.escape(prefix)}(?=\/|\\|\z)/, "~")
|
|
248
|
+
end
|
|
258
249
|
end
|
|
259
250
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module JsonLogging
|
|
2
|
+
module SanitizerHashLimit
|
|
3
|
+
FILTERED = "[FILTERED]"
|
|
4
|
+
|
|
5
|
+
module_function
|
|
6
|
+
|
|
7
|
+
def apply(hash, filter_config:)
|
|
8
|
+
return hash if hash.size <= Sanitizer::MAX_CONTEXT_SIZE
|
|
9
|
+
|
|
10
|
+
truncated = {}
|
|
11
|
+
kept = 0
|
|
12
|
+
extra_filtered = 0
|
|
13
|
+
hash.each do |key, value|
|
|
14
|
+
if kept < Sanitizer::MAX_CONTEXT_SIZE
|
|
15
|
+
truncated[key] = value
|
|
16
|
+
kept += 1
|
|
17
|
+
elsif extra_filtered < Sanitizer::MAX_CONTEXT_SIZE && key_requires_filtering?(key, filter_config)
|
|
18
|
+
truncated[key] = FILTERED
|
|
19
|
+
extra_filtered += 1
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
truncated["_truncated"] = true
|
|
23
|
+
truncated
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def key_requires_filtering?(key, filter_config)
|
|
27
|
+
return true if Sanitizer.sensitive_key?(key)
|
|
28
|
+
|
|
29
|
+
Array(filter_config).any? do |filter|
|
|
30
|
+
next false if filter.is_a?(Proc)
|
|
31
|
+
|
|
32
|
+
key_string = key.to_s
|
|
33
|
+
if filter.is_a?(Regexp)
|
|
34
|
+
filter.match?(key_string)
|
|
35
|
+
else
|
|
36
|
+
token = filter.to_s
|
|
37
|
+
!token.empty? && !token.include?(".") && key_string.match?(/#{Regexp.escape(token)}/i)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -6,35 +6,6 @@ module JsonLogging
|
|
|
6
6
|
|
|
7
7
|
module_function
|
|
8
8
|
|
|
9
|
-
def eligible?(hash)
|
|
10
|
-
return false if Sanitizer.primitive_log_hash?(hash)
|
|
11
|
-
return false unless Sanitizer::StructuredHash.structured_log_hash?(hash)
|
|
12
|
-
return false unless large_structured_hash?(hash)
|
|
13
|
-
|
|
14
|
-
filter = Sanitizer.rails_parameter_filter
|
|
15
|
-
return true unless filter
|
|
16
|
-
|
|
17
|
-
!Sanitizer.rails_parameter_filter_requires_full_tree_walk?
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def large_structured_hash?(hash, leaf_threshold: LEAF_THRESHOLD)
|
|
21
|
-
leaf_count = 0
|
|
22
|
-
walker = lambda do |value|
|
|
23
|
-
case value
|
|
24
|
-
when Hash
|
|
25
|
-
value.each_value { |entry| walker.call(entry) }
|
|
26
|
-
when Array
|
|
27
|
-
value.each { |entry| walker.call(entry) }
|
|
28
|
-
else
|
|
29
|
-
leaf_count += 1
|
|
30
|
-
throw(:enough, true) if leaf_count > leaf_threshold
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
catch(:enough) { walker.call(hash) }
|
|
35
|
-
leaf_count > leaf_threshold
|
|
36
|
-
end
|
|
37
|
-
|
|
38
9
|
def try_encode_line(hash, severity:, timestamp:, field_overrides: {})
|
|
39
10
|
tree = prepared_tree(hash, field_overrides: field_overrides)
|
|
40
11
|
return nil unless tree
|
|
@@ -88,13 +59,7 @@ module JsonLogging
|
|
|
88
59
|
return jsonable.tree unless filter
|
|
89
60
|
return jsonable.tree if Sanitizer.rails_parameter_filter_requires_full_tree_walk?
|
|
90
61
|
|
|
91
|
-
|
|
92
|
-
jsonable.tree
|
|
93
|
-
else
|
|
94
|
-
Sanitizer::StructuredHash.stringify_keys_copy(jsonable.tree)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
filter.filter(tree)
|
|
62
|
+
filter.filter(Sanitizer::StructuredHash.stringify(jsonable.tree))
|
|
98
63
|
end
|
|
99
64
|
|
|
100
65
|
def append_json_line(tree, severity:, timestamp:, field_overrides:)
|
|
@@ -44,11 +44,7 @@ module JsonLogging
|
|
|
44
44
|
|
|
45
45
|
def sanitize_without_filter(hash, depth: 0)
|
|
46
46
|
jsonable = jsonable_tree(hash, depth: depth)
|
|
47
|
-
|
|
48
|
-
stringify(jsonable.tree)
|
|
49
|
-
else
|
|
50
|
-
jsonable.tree.dup
|
|
51
|
-
end
|
|
47
|
+
stringify(jsonable.tree)
|
|
52
48
|
end
|
|
53
49
|
|
|
54
50
|
def jsonable_tree(hash, depth: 0, seen: nil, parent_key: nil, omit_keys: nil, count_leaves: false, leaf_counter: nil)
|
|
@@ -133,7 +129,8 @@ module JsonLogging
|
|
|
133
129
|
return
|
|
134
130
|
end
|
|
135
131
|
|
|
136
|
-
|
|
132
|
+
# ParameterFilter keeps original key names; fallback rename would hide them from it.
|
|
133
|
+
if Sanitizer.rails_parameter_filter.nil? && Sanitizer::SENSITIVE_KEY_PATTERNS.match?(key_string)
|
|
137
134
|
return [Sanitizer.sensitive_filtered_key_name(key_string), "[FILTERED]", true]
|
|
138
135
|
end
|
|
139
136
|
|
|
@@ -195,12 +192,6 @@ module JsonLogging
|
|
|
195
192
|
value
|
|
196
193
|
end
|
|
197
194
|
end
|
|
198
|
-
|
|
199
|
-
def stringify_keys_copy(hash)
|
|
200
|
-
return hash if hash.keys.all? { |key| key.is_a?(String) }
|
|
201
|
-
|
|
202
|
-
hash.transform_keys(&:to_s)
|
|
203
|
-
end
|
|
204
195
|
end
|
|
205
196
|
end
|
|
206
197
|
end
|
data/lib/json_logging/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activesupport-json_logging
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
@@ -49,6 +49,20 @@ dependencies:
|
|
|
49
49
|
- - "<"
|
|
50
50
|
- !ruby/object:Gem::Version
|
|
51
51
|
version: '9.0'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: json
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: 2.21.2
|
|
59
|
+
type: :runtime
|
|
60
|
+
prerelease: false
|
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: 2.21.2
|
|
52
66
|
- !ruby/object:Gem::Dependency
|
|
53
67
|
name: rspec
|
|
54
68
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -77,20 +91,6 @@ dependencies:
|
|
|
77
91
|
- - ">="
|
|
78
92
|
- !ruby/object:Gem::Version
|
|
79
93
|
version: 2.2.0
|
|
80
|
-
- !ruby/object:Gem::Dependency
|
|
81
|
-
name: webmock
|
|
82
|
-
requirement: !ruby/object:Gem::Requirement
|
|
83
|
-
requirements:
|
|
84
|
-
- - "~>"
|
|
85
|
-
- !ruby/object:Gem::Version
|
|
86
|
-
version: '3'
|
|
87
|
-
type: :development
|
|
88
|
-
prerelease: false
|
|
89
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
90
|
-
requirements:
|
|
91
|
-
- - "~>"
|
|
92
|
-
- !ruby/object:Gem::Version
|
|
93
|
-
version: '3'
|
|
94
94
|
- !ruby/object:Gem::Dependency
|
|
95
95
|
name: rake
|
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -339,6 +339,7 @@ files:
|
|
|
339
339
|
- lib/json_logging/message_parser.rb
|
|
340
340
|
- lib/json_logging/payload_builder.rb
|
|
341
341
|
- lib/json_logging/sanitizer.rb
|
|
342
|
+
- lib/json_logging/sanitizer_hash_limit.rb
|
|
342
343
|
- lib/json_logging/severity.rb
|
|
343
344
|
- lib/json_logging/structured_hash_json_encoder.rb
|
|
344
345
|
- lib/json_logging/structured_hash_sanitizer.rb
|