lograge 0.15.1 → 0.16.0
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/lib/lograge/formatters/cee.rb +1 -1
- data/lib/lograge/formatters/helpers/safe_json.rb +87 -0
- data/lib/lograge/formatters/json.rb +1 -1
- data/lib/lograge/formatters/ltsv.rb +4 -4
- data/lib/lograge/log_subscribers/base.rb +22 -2
- data/lib/lograge/version.rb +1 -1
- data/lib/lograge.rb +21 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7417503c9af3927cc3291f8030b9cc506d42d8756538dc656218d5a2249f977d
|
|
4
|
+
data.tar.gz: a09ba47fcf99837649481b588b7eb1d90714a7ef3e454d18e09b1b3d894bbfb4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b171ecf0bba8e016a819606cfd579cf96b4e790b95ff0a6aba75d1ba3e1a3b180f12ef279bade671d09e1f0aca9090d61ef8bb051674ec60255f58c95492ca7e
|
|
7
|
+
data.tar.gz: 7e537bde3728955c50e6a142c43d126fafeb69ded6d7a8b9ce18410e311be49a166924ba5090f5a7279b156b0b028e9f113616d39c953fc0f39c2cfd9180dd4a
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Lograge
|
|
6
|
+
module Formatters
|
|
7
|
+
module Helpers
|
|
8
|
+
# Serializes log data to JSON without dropping the whole log event when
|
|
9
|
+
# the data cannot be generated as-is. Newer versions of the json gem are
|
|
10
|
+
# stricter about their input:
|
|
11
|
+
#
|
|
12
|
+
# * json 3.1 rejects non-ASCII ASCII-8BIT (binary) strings, which are
|
|
13
|
+
# common in exception messages and HTTP response bodies.
|
|
14
|
+
# * json 3.0 rejects hashes with keys that serialize to the same name,
|
|
15
|
+
# such as +:status+ and <tt>"status"</tt>.
|
|
16
|
+
#
|
|
17
|
+
# Strings that are invalid UTF-8 have always been rejected.
|
|
18
|
+
#
|
|
19
|
+
# The data is only normalized after the first attempt fails, so well
|
|
20
|
+
# formed events are serialized exactly as before and pay no extra cost.
|
|
21
|
+
module SafeJson
|
|
22
|
+
# ArgumentError is included because, on TruffleRuby, json 3's pure-Ruby
|
|
23
|
+
# generator serializes objects such as Symbols and Times through
|
|
24
|
+
# ActiveSupport's encoder, which before Rails 8.1 passes the
|
|
25
|
+
# +quirks_mode+ option that json 3 no longer accepts. Normalizing turns
|
|
26
|
+
# those objects into plain strings, which avoids that code path.
|
|
27
|
+
GENERATION_ERRORS = [::JSON::GeneratorError, ::EncodingError, ::ArgumentError].freeze
|
|
28
|
+
|
|
29
|
+
module_function
|
|
30
|
+
|
|
31
|
+
def dump(data)
|
|
32
|
+
::JSON.dump(data)
|
|
33
|
+
rescue *GENERATION_ERRORS
|
|
34
|
+
::JSON.dump(normalize(data))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns a copy of +value+ that the json gem can always generate:
|
|
38
|
+
#
|
|
39
|
+
# * every hash key is a UTF-8 string. When two keys serialize to the same
|
|
40
|
+
# name, the first key keeps its position and the later value wins,
|
|
41
|
+
# which matches how the log subscriber merges custom options.
|
|
42
|
+
# * every string and symbol becomes a valid UTF-8 string. Bytes that
|
|
43
|
+
# cannot be converted are replaced with U+FFFD.
|
|
44
|
+
# * other objects are kept if they can be generated on their own, and
|
|
45
|
+
# are otherwise replaced by their normalized +to_s+ (for example an
|
|
46
|
+
# exception whose message holds binary bytes).
|
|
47
|
+
def normalize(value)
|
|
48
|
+
case value
|
|
49
|
+
when Hash then normalize_hash(value)
|
|
50
|
+
when Array then value.map { |element| normalize(element) }
|
|
51
|
+
when String then to_utf8(value)
|
|
52
|
+
when Symbol then to_utf8(value.to_s)
|
|
53
|
+
when Numeric, true, false, nil then value
|
|
54
|
+
else normalize_object(value)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def normalize_hash(hash)
|
|
59
|
+
hash.each_with_object({}) do |(key, value), normalized|
|
|
60
|
+
normalized[to_utf8(key.to_s)] = normalize(value)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def normalize_object(object)
|
|
65
|
+
::JSON.dump(object)
|
|
66
|
+
object
|
|
67
|
+
rescue *GENERATION_ERRORS
|
|
68
|
+
to_utf8(object.to_s)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def to_utf8(string)
|
|
72
|
+
encoding = string.encoding
|
|
73
|
+
if encoding == Encoding::UTF_8
|
|
74
|
+
string.valid_encoding? ? string : string.scrub
|
|
75
|
+
elsif encoding == Encoding::BINARY || encoding.dummy?
|
|
76
|
+
# Binary strings carry no encoding information, and dummy encodings
|
|
77
|
+
# (such as UTF-7) have no converter. Treat them as UTF-8 on a
|
|
78
|
+
# best-effort basis so valid multibyte sequences survive.
|
|
79
|
+
string.dup.force_encoding(Encoding::UTF_8).scrub
|
|
80
|
+
else
|
|
81
|
+
string.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -32,10 +32,10 @@ module Lograge
|
|
|
32
32
|
def escape(string)
|
|
33
33
|
value = string.is_a?(String) ? string.dup : string.to_s
|
|
34
34
|
|
|
35
|
-
value.gsub!('\\'
|
|
36
|
-
value.gsub!(
|
|
37
|
-
value.gsub!(
|
|
38
|
-
value.gsub!(
|
|
35
|
+
value.gsub!('\\') { '\\\\' }
|
|
36
|
+
value.gsub!("\n", '\\n')
|
|
37
|
+
value.gsub!("\r", '\\r')
|
|
38
|
+
value.gsub!("\t", '\\t')
|
|
39
39
|
|
|
40
40
|
value
|
|
41
41
|
end
|
|
@@ -33,7 +33,7 @@ module Lograge
|
|
|
33
33
|
data.merge!(extract_runtimes(event, payload))
|
|
34
34
|
data.merge!(extract_location)
|
|
35
35
|
data.merge!(extract_unpermitted_params)
|
|
36
|
-
data
|
|
36
|
+
merge_options(data, custom_options(event))
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
%i[initial_data extract_status extract_runtimes
|
|
@@ -70,7 +70,27 @@ module Lograge
|
|
|
70
70
|
|
|
71
71
|
def custom_options(event)
|
|
72
72
|
options = Lograge.custom_options(event) || {}
|
|
73
|
-
options.
|
|
73
|
+
merge_options(options.dup, event.payload[:custom_payload] || {})
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Merges +options+ into +data+. A String key overrides an existing Symbol
|
|
77
|
+
# key of the same name (and vice versa) instead of being added alongside
|
|
78
|
+
# it, so the two never end up serialized as duplicate keys.
|
|
79
|
+
def merge_options(data, options)
|
|
80
|
+
options.each do |key, value|
|
|
81
|
+
data[existing_key(data, key)] = value
|
|
82
|
+
end
|
|
83
|
+
data
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def existing_key(data, key)
|
|
87
|
+
return key if data.key?(key)
|
|
88
|
+
|
|
89
|
+
counterpart = case key
|
|
90
|
+
when Symbol then key.to_s
|
|
91
|
+
when String then key.to_sym
|
|
92
|
+
end
|
|
93
|
+
counterpart && data.key?(counterpart) ? counterpart : key
|
|
74
94
|
end
|
|
75
95
|
|
|
76
96
|
def before_format(data, payload)
|
data/lib/lograge/version.rb
CHANGED
data/lib/lograge.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require 'logger'
|
|
4
4
|
require 'lograge/version'
|
|
5
5
|
require 'lograge/formatters/helpers/method_and_path'
|
|
6
|
+
require 'lograge/formatters/helpers/safe_json'
|
|
6
7
|
require 'lograge/formatters/cee'
|
|
7
8
|
require 'lograge/formatters/json'
|
|
8
9
|
require 'lograge/formatters/graylog2'
|
|
@@ -115,7 +116,27 @@ module Lograge
|
|
|
115
116
|
unsubscribe(:action_controller, subscriber)
|
|
116
117
|
end
|
|
117
118
|
end
|
|
119
|
+
|
|
120
|
+
remove_event_reporter_log_subscriptions
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Rails 8.2+ framework log subscribers inherit from
|
|
124
|
+
# ActiveSupport::EventReporter::LogSubscriber and are subscribed to
|
|
125
|
+
# ActiveSupport.event_reporter instead of ActiveSupport::Notifications.
|
|
126
|
+
def remove_event_reporter_log_subscriptions
|
|
127
|
+
rails_event_reporter_log_subscriber_classes.each do |klass|
|
|
128
|
+
ActiveSupport.event_reporter.unsubscribe(klass)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def rails_event_reporter_log_subscriber_classes
|
|
133
|
+
return [] unless defined?(ActiveSupport::EventReporter::LogSubscriber)
|
|
134
|
+
|
|
135
|
+
[ActionController::LogSubscriber, ActionView::LogSubscriber].select do |klass|
|
|
136
|
+
klass < ActiveSupport::EventReporter::LogSubscriber
|
|
137
|
+
end
|
|
118
138
|
end
|
|
139
|
+
private_class_method :remove_event_reporter_log_subscriptions, :rails_event_reporter_log_subscriber_classes
|
|
119
140
|
|
|
120
141
|
def unsubscribe(component, subscriber)
|
|
121
142
|
events = subscriber.public_methods(false).reject { |method| method.to_s == 'call' }
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lograge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mathias Meyer
|
|
@@ -207,6 +207,7 @@ files:
|
|
|
207
207
|
- lib/lograge/formatters/cee.rb
|
|
208
208
|
- lib/lograge/formatters/graylog2.rb
|
|
209
209
|
- lib/lograge/formatters/helpers/method_and_path.rb
|
|
210
|
+
- lib/lograge/formatters/helpers/safe_json.rb
|
|
210
211
|
- lib/lograge/formatters/json.rb
|
|
211
212
|
- lib/lograge/formatters/key_value.rb
|
|
212
213
|
- lib/lograge/formatters/key_value_deep.rb
|
|
@@ -246,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
246
247
|
- !ruby/object:Gem::Version
|
|
247
248
|
version: '0'
|
|
248
249
|
requirements: []
|
|
249
|
-
rubygems_version:
|
|
250
|
+
rubygems_version: 3.6.9
|
|
250
251
|
specification_version: 4
|
|
251
252
|
summary: Tame Rails' multi-line logging into a single line per request
|
|
252
253
|
test_files: []
|