epilog 0.2.0 → 0.6.0

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: c73f8fcac8b47000824334dce31d8b781aa5e730201f2e67816c4c395cbe3966
4
- data.tar.gz: 7f45a7801cb9a815cb576c39de3fb49c09f6b928e7cc2f2b1b50435df548d0e1
3
+ metadata.gz: 26a731d5297bcf87056341855af05c6c57b18fbb29115a0dcc3d00b1c2a9086e
4
+ data.tar.gz: 032c613192e81a8c4b97993b1f42c7d100272c16b1a4457f1df9a9afb54a84b6
5
5
  SHA512:
6
- metadata.gz: ff73c27fe2100ffc880d689196fc4deed995c3e2978f4d01412bdd63ec7b73de3e11903af43570a0ca29a5040fec275d6a4fad0cbfdf2d0d41bd01da11469045
7
- data.tar.gz: 34bb7195d88534537637e43a729314ba6439f3e40a4c150c33c46c0bb0aa41e9bf544e0f0d47e10cff534c7e71877b53206b5f928c412e9337da471846a34b75
6
+ metadata.gz: 44373cd845a4114af0b41654265f697c0bc2ab9584342d1b5c40de4a539e1228608ac1d548bf14150c24ddaa6987c272601f402453dac1ff0356a23a65cd8bd8
7
+ data.tar.gz: e654189bc9d0431e165c0d948f234972171f16c016260ba287e05cf5f268f5802e30fedf02884d5699ff49241548eab5b3d46f7065e836988a37cace563c476e
@@ -2,24 +2,30 @@
2
2
  AllCops:
3
3
  TargetRubyVersion: 2.3
4
4
 
5
+ Layout/AlignArguments:
6
+ EnforcedStyle: with_fixed_indentation
7
+
5
8
  Layout/EndAlignment:
6
9
  EnforcedStyleAlignWith: variable
7
10
 
8
11
  Layout/AlignParameters:
9
12
  EnforcedStyle: with_fixed_indentation
10
13
 
11
- Layout/IndentArray:
14
+ Layout/IndentFirstArgument:
12
15
  EnforcedStyle: consistent
13
16
 
14
- Layout/IndentHash:
17
+ Layout/IndentFirstArrayElement:
15
18
  EnforcedStyle: consistent
16
19
 
17
- Style/Documentation:
18
- Enabled: false
20
+ Layout/IndentFirstHashElement:
21
+ EnforcedStyle: consistent
19
22
 
20
23
  Layout/MultilineMethodCallIndentation:
21
24
  EnforcedStyle: indented
22
25
 
26
+ Style/Documentation:
27
+ Enabled: false
28
+
23
29
  Style/FrozenStringLiteralComment:
24
30
  Enabled: true
25
31
  EnforcedStyle: always
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ ## 0.6.0
4
+
5
+ - Add support for Rails 5 API-only controllers [#17](https://github.com/machinima/epilog/pull/17)
6
+
7
+ ## 0.5.0
8
+
9
+ - Add options to enable/disable start and end logs [#15](https://github.com/machinima/epilog/pull/15)
10
+ - Fix with_context to use ensure [#16](https://github.com/machinima/epilog/pull/16)
11
+
12
+ ## 0.4.0
13
+
14
+ - Add context support to Logger [#12](https://github.com/machinima/epilog/pull/12)
15
+
16
+ ## 0.3.1
17
+
18
+ - Add context to request log [#10](https://github.com/machinima/epilog/pull/10)
19
+
20
+ ## 0.3
21
+
22
+ - Update development dependencies [#1](https://github.com/machinima/epilog/pull/1)
23
+ - Allow controllers to add context to logs [#2](https://github.com/machinima/epilog/pull/2)
24
+ - Fix removing Rails default parameters when filter_parameters are set [#4](https://github.com/machinima/epilog/pull/4)
25
+ - Add a filter using Rails filter_parameters [#3](https://github.com/machinima/epilog/pull/3)
26
+ - Change action view logs to DEBUG [#5](https://github.com/machinima/epilog/pull/5)
27
+ - Filter all request data using filter_parameters [#6](https://github.com/machinima/epilog/pull/6)
28
+
29
+ ## 0.2
30
+
31
+ Initial public release
@@ -19,16 +19,17 @@ Gem::Specification.new do |spec|
19
19
  .reject { |f| f.match(%r{^spec/}) }
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_development_dependency 'bundler', '~> 1.12'
23
- spec.add_development_dependency 'byebug', '~> 9.0'
24
- spec.add_development_dependency 'combustion', '~> 1.0.0'
22
+ spec.add_development_dependency 'bundler', '>= 1.12'
23
+ spec.add_development_dependency 'byebug', '~> 11.0'
24
+ spec.add_development_dependency 'combustion', '~> 1.1.0'
25
+ spec.add_development_dependency 'irb'
25
26
  spec.add_development_dependency 'rails', '>= 4.2', '< 6'
26
- spec.add_development_dependency 'rake', '~> 10.0'
27
- spec.add_development_dependency 'redcarpet', '~> 3.4'
27
+ spec.add_development_dependency 'rake', '~> 13.0'
28
+ spec.add_development_dependency 'redcarpet', '~> 3.5'
28
29
  spec.add_development_dependency 'rspec', '~> 3.4'
29
30
  spec.add_development_dependency 'rspec-rails', '~> 3.8.1'
30
- spec.add_development_dependency 'rubocop', '~> 0.61'
31
- spec.add_development_dependency 'simplecov', '~> 0.12'
32
- spec.add_development_dependency 'sqlite3', '~> 1.3'
31
+ spec.add_development_dependency 'rubocop', '0.75'
32
+ spec.add_development_dependency 'simplecov', '~> 0.17'
33
+ spec.add_development_dependency 'sqlite3', '~> 1.3', '< 1.4'
33
34
  spec.add_development_dependency 'yard', '~> 0.9.11'
34
35
  end
@@ -3,6 +3,7 @@
3
3
  require 'logger'
4
4
 
5
5
  require 'epilog/version'
6
+ require 'epilog/context_logging'
6
7
  require 'epilog/logger'
7
8
  require 'epilog/mock_logger'
8
9
  require 'epilog/log_formatter'
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Epilog
4
+ module ContextLogger
5
+ def with_context(context)
6
+ push_context(context)
7
+ yield
8
+ ensure
9
+ pop_context
10
+ end
11
+
12
+ def push_context(context)
13
+ formatter.push_context(context)
14
+ end
15
+
16
+ def pop_context
17
+ formatter.pop_context
18
+ end
19
+ end
20
+
21
+ module ContextFormatter
22
+ def context
23
+ Thread.current[current_context_key] ||= begin
24
+ result = {}
25
+ context_stack.each { |frame| result.merge!(frame) }
26
+ result
27
+ end.freeze
28
+ end
29
+
30
+ def push_context(frame)
31
+ clear_context
32
+ context_stack.push(frame)
33
+ end
34
+
35
+ def pop_context
36
+ clear_context
37
+ context_stack.pop
38
+ end
39
+
40
+ private
41
+
42
+ def clear_context
43
+ Thread.current[current_context_key] = nil
44
+ end
45
+
46
+ def context_stack
47
+ Thread.current[stack_key] ||= []
48
+ end
49
+
50
+ def stack_key
51
+ @stack_key ||= "epilog_context_stack:#{object_id}"
52
+ end
53
+
54
+ def current_context_key
55
+ @current_context_key ||= "epilog_context_current:#{object_id}"
56
+ end
57
+ end
58
+ end
@@ -2,3 +2,4 @@
2
2
 
3
3
  require 'epilog/filter/hash_key'
4
4
  require 'epilog/filter/blacklist'
5
+ require 'epilog/filter/filter_parameters'
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Epilog
4
+ module Filter
5
+ class FilterParameters < Blacklist
6
+ private
7
+
8
+ def filter_parameters
9
+ return @filter_parameters if @filter_parameters
10
+
11
+ filtered = Hash[
12
+ ::Rails.application.config.filter_parameters.map do |p|
13
+ [p.to_s.downcase, true]
14
+ end
15
+ ]
16
+
17
+ @filter_parameters = filtered if ::Rails.initialized?
18
+ filtered
19
+ end
20
+
21
+ def key?(key)
22
+ filter_parameters.key?(key.to_s.downcase)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Epilog
4
4
  class Formatter
5
+ include ContextFormatter
6
+
5
7
  SEVERITY_MAP = {
6
8
  'FATAL' => 'ALERT',
7
9
  'WARN' => 'WARNING'
@@ -18,6 +20,7 @@ module Epilog
18
20
 
19
21
  def call(severity, time, progname, msg)
20
22
  log = base_log(severity, time, progname)
23
+ log.merge!(context)
21
24
  log.merge!(message(msg))
22
25
 
23
26
  if log[:exception].is_a?(Exception)
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Epilog
4
4
  class Logger < ::Logger
5
+ include ContextLogger
6
+
5
7
  def initialize(*args, **options)
6
8
  super
7
9
  self.formatter = Formatter.new
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Epilog
4
4
  class MockLogger < ::Logger
5
- def initialize
6
- super(nil)
5
+ def initialize(**options)
6
+ super(nil, **options)
7
7
  reset
8
8
  end
9
9
 
@@ -44,6 +44,21 @@ module Epilog
44
44
 
45
45
  def reset
46
46
  @logs = []
47
+ @context = []
48
+ end
49
+
50
+ def with_context(context)
51
+ push_context(context)
52
+ yield
53
+ pop_context
54
+ end
55
+
56
+ def push_context(context)
57
+ @context << context
58
+ end
59
+
60
+ def pop_context
61
+ @context.pop
47
62
  end
48
63
 
49
64
  private
@@ -53,7 +68,7 @@ module Epilog
53
68
  end
54
69
 
55
70
  def write(severity, time, prog, message)
56
- @logs << [severity, time, prog, message]
71
+ @logs << [severity, time, prog, message, @context.dup]
57
72
  end
58
73
  end
59
74
  end
@@ -7,24 +7,17 @@ module Epilog
7
7
  RAILS_PARAMS = %i[controller action format _method only_path].freeze
8
8
 
9
9
  def request_received(event)
10
- info do
11
- {
12
- message: "#{request_string(event)} started",
13
- request: request_hash(event)
14
- }
15
- end
10
+ push_context(
11
+ { request: short_request_hash(event) }
12
+ .merge(event.payload[:context])
13
+ )
14
+
15
+ log_start(event) if config.double_request_logs
16
16
  end
17
17
 
18
18
  def process_request(event)
19
- info do
20
- {
21
- message: response_string(event),
22
- request: short_request_hash(event),
23
- response: response_hash(event),
24
- metrics: process_metrics(event.payload[:metrics]
25
- .merge(request_runtime: event.duration.round(2)))
26
- }
27
- end
19
+ log_end(event)
20
+ pop_context
28
21
  end
29
22
 
30
23
  def start_processing(*)
@@ -77,8 +70,37 @@ module Epilog
77
70
 
78
71
  private
79
72
 
73
+ def log_start(event)
74
+ info do
75
+ {
76
+ message: "#{request_string(event)} started",
77
+ request: request_hash(event)
78
+ }
79
+ end
80
+ end
81
+
82
+ def log_end(event) # rubocop:disable MethodLength
83
+ request = if config.double_request_logs
84
+ short_request_hash(event)
85
+ else
86
+ request_hash(event)
87
+ end
88
+
89
+ info do
90
+ {
91
+ message: response_string(event),
92
+ request: request,
93
+ response: response_hash(event),
94
+ metrics: process_metrics(event.payload[:metrics]
95
+ .merge(request_runtime: event.duration.round(2)))
96
+ }
97
+ end
98
+ end
99
+
80
100
  def request_hash(event) # rubocop:disable AbcSize, MethodLength
81
101
  request = event.payload[:request]
102
+ param_filter = request.send(:parameter_filter)
103
+
82
104
  {
83
105
  id: request.uuid,
84
106
  ip: request.remote_ip,
@@ -86,13 +108,15 @@ module Epilog
86
108
  protocol: request.protocol.to_s.gsub('://', ''),
87
109
  method: request.request_method,
88
110
  port: request.port,
89
- path: request.fullpath,
90
- query: request.query_parameters,
91
- cookies: request.cookies,
92
- headers: request.headers.to_h.keep_if do |key, _value|
93
- key =~ ActionDispatch::Http::Headers::HTTP_HEADER
94
- end,
95
- params: request.filtered_parameters.except(*RAILS_PARAMS),
111
+ path: request.path,
112
+ query: param_filter.filter(request.query_parameters),
113
+ cookies: param_filter.filter(request.cookies),
114
+ headers: param_filter.filter(
115
+ request.headers.to_h.keep_if do |key, _value|
116
+ key =~ ActionDispatch::Http::Headers::HTTP_HEADER
117
+ end
118
+ ),
119
+ params: request.filtered_parameters.except(*rails_params),
96
120
  format: request.format.try(:ref),
97
121
  controller: event.payload[:controller],
98
122
  action: event.payload[:action]
@@ -104,13 +128,13 @@ module Epilog
104
128
  {
105
129
  id: request.uuid,
106
130
  method: request.method,
107
- path: request.fullpath
131
+ path: request.path
108
132
  }
109
133
  end
110
134
 
111
135
  def request_string(event)
112
136
  request = event.payload[:request]
113
- "#{request.request_method} #{request.fullpath}"
137
+ "#{request.request_method} #{request.path}"
114
138
  end
115
139
 
116
140
  def response_hash(event)
@@ -147,6 +171,10 @@ module Epilog
147
171
  obj[key] = value.round(2) if value.is_a?(Numeric)
148
172
  end
149
173
  end
174
+
175
+ def rails_params
176
+ @rails_params ||= RAILS_PARAMS + RAILS_PARAMS.map(&:to_s)
177
+ end
150
178
  end
151
179
  end
152
180
  end
@@ -4,15 +4,15 @@ module Epilog
4
4
  module Rails
5
5
  class ActionViewSubscriber < LogSubscriber
6
6
  def render_template(event)
7
- info { hash(event, 'Rendered template') }
7
+ debug { hash(event, 'Rendered template') }
8
8
  end
9
9
 
10
10
  def render_partial(event)
11
- info { hash(event, 'Rendered partial') }
11
+ debug { hash(event, 'Rendered partial') }
12
12
  end
13
13
 
14
14
  def render_collection(event)
15
- info { hash(event, 'Rendered collection') }
15
+ debug { hash(event, 'Rendered collection') }
16
16
  end
17
17
 
18
18
  private
@@ -12,6 +12,9 @@ module Epilog
12
12
  end
13
13
 
14
14
  def perform_start(event)
15
+ push_context(job: short_job_hash(event.payload[:job]))
16
+ return unless config.double_job_logs
17
+
15
18
  info { event_hash('Performing job', event) }
16
19
  end
17
20
 
@@ -23,6 +26,7 @@ module Epilog
23
26
  }
24
27
  )
25
28
  end
29
+ pop_context
26
30
  end
27
31
 
28
32
  private
@@ -45,6 +49,13 @@ module Epilog
45
49
  }
46
50
  end
47
51
 
52
+ def short_job_hash(job)
53
+ {
54
+ class: job.class.name,
55
+ id: job.job_id
56
+ }
57
+ end
58
+
48
59
  def format_time(time)
49
60
  Time.at(time).utc.strftime(Epilog::Formatter::DEFAULT_TIME_FORMAT)
50
61
  end
@@ -29,7 +29,8 @@ module Epilog
29
29
  request: request,
30
30
  response: response,
31
31
  controller: self.class.name,
32
- action: action_name
32
+ action: action_name,
33
+ context: epilog_context
33
34
  }
34
35
  end
35
36
 
@@ -39,7 +40,14 @@ module Epilog
39
40
  view_runtime: view_runtime
40
41
  }
41
42
  end
43
+
44
+ def epilog_context
45
+ {}
46
+ end
42
47
  end
43
48
  end
44
49
 
45
50
  ActionController::Base.prepend(Epilog::ActionControllerExt)
51
+ if defined? ActionController::API
52
+ ActionController::API.prepend(Epilog::ActionControllerExt)
53
+ end
@@ -9,6 +9,18 @@ module Epilog
9
9
  super()
10
10
  @logger = logger
11
11
  end
12
+
13
+ def push_context(context)
14
+ @logger.try(:push_context, context)
15
+ end
16
+
17
+ def pop_context
18
+ @logger.try(:pop_context)
19
+ end
20
+
21
+ def config
22
+ ::Rails.application.config.epilog
23
+ end
12
24
  end
13
25
  end
14
26
  end
@@ -20,6 +20,8 @@ module Epilog
20
20
  ].freeze
21
21
 
22
22
  config.epilog = ActiveSupport::OrderedOptions.new
23
+ config.epilog.double_request_logs = true
24
+ config.epilog.double_job_logs = true
23
25
  config.epilog.subscriptions = %i[
24
26
  action_controller
25
27
  action_mailer
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Epilog
4
- VERSION = '0.2.0'
4
+ VERSION = '0.6.0'
5
5
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epilog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Howard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-18 00:00:00.000000000 Z
11
+ date: 2020-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.12'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.12'
27
27
  - !ruby/object:Gem::Dependency
@@ -30,28 +30,42 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '9.0'
33
+ version: '11.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '9.0'
40
+ version: '11.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: combustion
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.0.0
47
+ version: 1.1.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.0.0
54
+ version: 1.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: irb
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rails
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -78,28 +92,28 @@ dependencies:
78
92
  requirements:
79
93
  - - "~>"
80
94
  - !ruby/object:Gem::Version
81
- version: '10.0'
95
+ version: '13.0'
82
96
  type: :development
83
97
  prerelease: false
84
98
  version_requirements: !ruby/object:Gem::Requirement
85
99
  requirements:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
- version: '10.0'
102
+ version: '13.0'
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: redcarpet
91
105
  requirement: !ruby/object:Gem::Requirement
92
106
  requirements:
93
107
  - - "~>"
94
108
  - !ruby/object:Gem::Version
95
- version: '3.4'
109
+ version: '3.5'
96
110
  type: :development
97
111
  prerelease: false
98
112
  version_requirements: !ruby/object:Gem::Requirement
99
113
  requirements:
100
114
  - - "~>"
101
115
  - !ruby/object:Gem::Version
102
- version: '3.4'
116
+ version: '3.5'
103
117
  - !ruby/object:Gem::Dependency
104
118
  name: rspec
105
119
  requirement: !ruby/object:Gem::Requirement
@@ -132,30 +146,30 @@ dependencies:
132
146
  name: rubocop
133
147
  requirement: !ruby/object:Gem::Requirement
134
148
  requirements:
135
- - - "~>"
149
+ - - '='
136
150
  - !ruby/object:Gem::Version
137
- version: '0.61'
151
+ version: '0.75'
138
152
  type: :development
139
153
  prerelease: false
140
154
  version_requirements: !ruby/object:Gem::Requirement
141
155
  requirements:
142
- - - "~>"
156
+ - - '='
143
157
  - !ruby/object:Gem::Version
144
- version: '0.61'
158
+ version: '0.75'
145
159
  - !ruby/object:Gem::Dependency
146
160
  name: simplecov
147
161
  requirement: !ruby/object:Gem::Requirement
148
162
  requirements:
149
163
  - - "~>"
150
164
  - !ruby/object:Gem::Version
151
- version: '0.12'
165
+ version: '0.17'
152
166
  type: :development
153
167
  prerelease: false
154
168
  version_requirements: !ruby/object:Gem::Requirement
155
169
  requirements:
156
170
  - - "~>"
157
171
  - !ruby/object:Gem::Version
158
- version: '0.12'
172
+ version: '0.17'
159
173
  - !ruby/object:Gem::Dependency
160
174
  name: sqlite3
161
175
  requirement: !ruby/object:Gem::Requirement
@@ -163,6 +177,9 @@ dependencies:
163
177
  - - "~>"
164
178
  - !ruby/object:Gem::Version
165
179
  version: '1.3'
180
+ - - "<"
181
+ - !ruby/object:Gem::Version
182
+ version: '1.4'
166
183
  type: :development
167
184
  prerelease: false
168
185
  version_requirements: !ruby/object:Gem::Requirement
@@ -170,6 +187,9 @@ dependencies:
170
187
  - - "~>"
171
188
  - !ruby/object:Gem::Version
172
189
  version: '1.3'
190
+ - - "<"
191
+ - !ruby/object:Gem::Version
192
+ version: '1.4'
173
193
  - !ruby/object:Gem::Dependency
174
194
  name: yard
175
195
  requirement: !ruby/object:Gem::Requirement
@@ -196,6 +216,7 @@ files:
196
216
  - ".rubocop.yml"
197
217
  - ".travis.yml"
198
218
  - ".yardopts"
219
+ - CHANGELOG.md
199
220
  - Gemfile
200
221
  - LICENSE.txt
201
222
  - README.md
@@ -210,8 +231,10 @@ files:
210
231
  - bin/yri
211
232
  - epilog.gemspec
212
233
  - lib/epilog.rb
234
+ - lib/epilog/context_logging.rb
213
235
  - lib/epilog/filter.rb
214
236
  - lib/epilog/filter/blacklist.rb
237
+ - lib/epilog/filter/filter_parameters.rb
215
238
  - lib/epilog/filter/hash_key.rb
216
239
  - lib/epilog/log_formatter.rb
217
240
  - lib/epilog/logger.rb
@@ -251,7 +274,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
251
274
  version: '0'
252
275
  requirements: []
253
276
  rubyforge_project:
254
- rubygems_version: 2.7.8
277
+ rubygems_version: 2.7.7
255
278
  signing_key:
256
279
  specification_version: 4
257
280
  summary: A JSON logger with Rails support