lograge 0.7.1 → 0.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 794cb4f90104c70ec130d7e76616fd5f2f98d635
4
- data.tar.gz: 849237755782f80091e100da8980f2eba36e63d3
2
+ SHA256:
3
+ metadata.gz: a8dc3fd38bfe24b9f1816ac75fa2d600037fd308b1b355de309d81deae032cd9
4
+ data.tar.gz: f3627f7956278364545987b845a16011463592a78dbf9ae0a409b0c8640b63e4
5
5
  SHA512:
6
- metadata.gz: ae07fa3866c8deeb9887dee23f8be3b2d8908b55c4adfb1c33e514e49f182077517ea74fca08ecffdca8d133bfb96c68159407092e319a8685be42f31e6fd530
7
- data.tar.gz: d1df2bb0c4f4e6c5ae392022f43b11d58fcd70676f6842fd469e74329d2da40d4af68307df8d90699cccc91f29e8f3890f2efb5c04f7b1169bb01c8410bbdcae
6
+ metadata.gz: 5787201d587cee662987f2aef1db3b971a60b7feec4dc630d509520713e2c746aee9a1249817f0d1bb8752d22eadcf5e79259c73213e75ce7127e49115795b95
7
+ data.tar.gz: 055daf5493eb1a053a8b995d5037973587782c8edf9a48fd0d860f3d5e5c2bb419957c0df8610eda6e0cc26c54bdcf7bd900ba0113c780c4569fb22330e9b00e
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Mathias Meyer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lograge
2
4
  module Formatters
3
5
  class Cee
@@ -1,21 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lograge
2
4
  module Formatters
3
5
  class Graylog2
4
- def call(data)
5
- # Cloning because we don't want to mess with the original when mutating keys.
6
- data_clone = data.clone
7
-
8
- base = {
9
- short_message: short_message(data_clone)
10
- }
6
+ include Lograge::Formatters::Helpers::MethodAndPath
11
7
 
8
+ def call(data)
12
9
  # Add underscore to every key to follow GELF additional field syntax.
13
- data_clone.keys.each do |key|
14
- data_clone[underscore_prefix(key)] = data_clone[key]
15
- data_clone.delete(key)
16
- end
17
-
18
- data_clone.merge(base)
10
+ data.transform_keys { |k| underscore_prefix(k) }.merge(
11
+ short_message: short_message(data)
12
+ )
19
13
  end
20
14
 
21
15
  def underscore_prefix(key)
@@ -23,7 +17,7 @@ module Lograge
23
17
  end
24
18
 
25
19
  def short_message(data)
26
- "[#{data[:status]}] #{data[:method]} #{data[:path]} (#{data[:controller]}##{data[:action]})"
20
+ "[#{data[:status]}]#{method_and_path_string(data)}(#{data[:controller]}##{data[:action]})"
27
21
  end
28
22
  end
29
23
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lograge
4
+ module Formatters
5
+ module Helpers
6
+ module MethodAndPath
7
+ def method_and_path_string(data)
8
+ method_and_path = [data[:method], data[:path]].compact
9
+ method_and_path.any?(&:present?) ? " #{method_and_path.join(' ')} " : ' '
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  module Lograge
3
5
  module Formatters
@@ -1,28 +1,32 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lograge
2
4
  module Formatters
3
5
  class KeyValue
4
6
  def call(data)
5
- fields = fields_to_display(data)
6
-
7
- event = fields.map { |key| format(key, data[key]) }
8
- event.join(' ')
7
+ fields_to_display(data)
8
+ .map { |key| format(key, data[key]) }
9
+ .join(' ')
9
10
  end
10
11
 
12
+ protected
13
+
11
14
  def fields_to_display(data)
12
15
  data.keys
13
16
  end
14
17
 
15
18
  def format(key, value)
16
- if key == :error
17
- # Exactly preserve the previous output
18
- # Parsing this can be ambigious if the error messages contains
19
- # a single quote
20
- value = "'#{value}'"
21
- elsif value.is_a? Float
22
- value = Kernel.format('%.2f', value)
23
- end
19
+ "#{key}=#{parse_value(key, value)}"
20
+ end
21
+
22
+ def parse_value(key, value)
23
+ # Exactly preserve the previous output
24
+ # Parsing this can be ambigious if the error messages contains
25
+ # a single quote
26
+ return "'#{value}'" if key == :error
27
+ return Kernel.format('%.2f', value) if value.is_a? Float
24
28
 
25
- "#{key}=#{value}"
29
+ value
26
30
  end
27
31
  end
28
32
  end
@@ -1,35 +1,48 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'lograge/formatters/key_value'
2
4
 
3
5
  module Lograge
4
6
  module Formatters
5
7
  class L2met < KeyValue
6
- L2MET_FIELDS = [
7
- :method,
8
- :path,
9
- :format,
10
- :source,
11
- :status,
12
- :error,
13
- :duration,
14
- :view,
15
- :db,
16
- :location
8
+ L2MET_FIELDS = %i[
9
+ method
10
+ path
11
+ format
12
+ source
13
+ status
14
+ error
15
+ duration
16
+ view
17
+ db
18
+ location
19
+ ].freeze
20
+
21
+ UNWANTED_FIELDS = %i[
22
+ controller
23
+ action
17
24
  ].freeze
18
25
 
19
26
  def call(data)
20
27
  super(modify_payload(data))
21
28
  end
22
29
 
30
+ protected
31
+
32
+ def fields_to_display(data)
33
+ L2MET_FIELDS + additional_fields(data)
34
+ end
35
+
36
+ def additional_fields(data)
37
+ (data.keys - L2MET_FIELDS) - UNWANTED_FIELDS
38
+ end
39
+
23
40
  def format(key, value)
24
41
  key = "measure#page.#{key}" if value.is_a?(Float)
25
42
 
26
43
  super(key, value)
27
44
  end
28
45
 
29
- def fields_to_display(data)
30
- L2MET_FIELDS + (data.keys - L2MET_FIELDS) - [:controller, :action]
31
- end
32
-
33
46
  def modify_payload(data)
34
47
  data[:source] = source_field(data) if data[:controller] && data[:action]
35
48
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lograge
2
4
  module Formatters
3
5
  class Lines
@@ -1,11 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lograge
2
4
  module Formatters
3
5
  class Logstash
6
+ include Lograge::Formatters::Helpers::MethodAndPath
7
+
4
8
  def call(data)
5
9
  load_dependencies
6
10
  event = LogStash::Event.new(data)
7
11
 
8
- event['message'] = "[#{data[:status]}] #{data[:method]} #{data[:path]} (#{data[:controller]}##{data[:action]})"
12
+ event['message'] = "[#{data[:status]}]#{method_and_path_string(data)}(#{data[:controller]}##{data[:action]})"
9
13
  event.to_json
10
14
  end
11
15
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lograge
2
4
  module Formatters
3
5
  class LTSV
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lograge
2
4
  module Formatters
3
5
  class Raw
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lograge
4
+ module LogSubscribers
5
+ class ActionCable < Base
6
+ %i[perform_action subscribe unsubscribe connect disconnect].each do |method_name|
7
+ define_method(method_name) do |event|
8
+ process_main_event(event)
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def initial_data(payload)
15
+ {
16
+ method: nil,
17
+ path: nil,
18
+ format: nil,
19
+ params: payload[:data],
20
+ controller: payload[:channel_class] || payload[:connection_class],
21
+ action: payload[:action]
22
+ }
23
+ end
24
+
25
+ def default_status
26
+ 200
27
+ end
28
+
29
+ def extract_runtimes(event, _payload)
30
+ { duration: event.duration.to_f.round(2) }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lograge
4
+ module LogSubscribers
5
+ class ActionController < Base
6
+ def process_action(event)
7
+ process_main_event(event)
8
+ end
9
+
10
+ def redirect_to(event)
11
+ RequestStore.store[:lograge_location] = event.payload[:location]
12
+ end
13
+
14
+ def unpermitted_parameters(event)
15
+ RequestStore.store[:lograge_unpermitted_params] ||= []
16
+ RequestStore.store[:lograge_unpermitted_params].concat(event.payload[:keys])
17
+ end
18
+
19
+ private
20
+
21
+ def initial_data(payload)
22
+ {
23
+ method: payload[:method],
24
+ path: extract_path(payload),
25
+ format: extract_format(payload),
26
+ controller: payload[:controller],
27
+ action: payload[:action]
28
+ }
29
+ end
30
+
31
+ def extract_path(payload)
32
+ path = payload[:path]
33
+ strip_query_string(path)
34
+ end
35
+
36
+ def strip_query_string(path)
37
+ index = path.index('?')
38
+ index ? path[0, index] : path
39
+ end
40
+
41
+ if ::ActionPack::VERSION::MAJOR == 3 && ::ActionPack::VERSION::MINOR.zero?
42
+ def extract_format(payload)
43
+ payload[:formats].first
44
+ end
45
+ else
46
+ def extract_format(payload)
47
+ payload[:format]
48
+ end
49
+ end
50
+
51
+ def extract_runtimes(event, payload)
52
+ data = { duration: event.duration.to_f.round(2) }
53
+ data[:view] = payload[:view_runtime].to_f.round(2) if payload.key?(:view_runtime)
54
+ data[:db] = payload[:db_runtime].to_f.round(2) if payload.key?(:db_runtime)
55
+ data
56
+ end
57
+
58
+ def extract_location
59
+ location = RequestStore.store[:lograge_location]
60
+ return {} unless location
61
+
62
+ RequestStore.store[:lograge_location] = nil
63
+ { location: strip_query_string(location) }
64
+ end
65
+
66
+ def extract_unpermitted_params
67
+ unpermitted_params = RequestStore.store[:lograge_unpermitted_params]
68
+ return {} unless unpermitted_params
69
+
70
+ RequestStore.store[:lograge_unpermitted_params] = nil
71
+ { unpermitted_params: unpermitted_params }
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'action_pack'
5
+ require 'active_support'
6
+ require 'active_support/core_ext/class/attribute'
7
+ require 'active_support/log_subscriber'
8
+ require 'request_store'
9
+
10
+ module Lograge
11
+ module LogSubscribers
12
+ class Base < ActiveSupport::LogSubscriber
13
+ def logger
14
+ Lograge.logger.presence || super
15
+ end
16
+
17
+ private
18
+
19
+ def process_main_event(event)
20
+ return if Lograge.ignore?(event)
21
+
22
+ payload = event.payload
23
+ data = extract_request(event, payload)
24
+ data = before_format(data, payload)
25
+ formatted_message = Lograge.formatter.call(data)
26
+ logger.send(Lograge.log_level, formatted_message)
27
+ end
28
+
29
+ def extract_request(event, payload)
30
+ data = initial_data(payload)
31
+ data.merge!(extract_status(payload))
32
+ data.merge!(extract_runtimes(event, payload))
33
+ data.merge!(extract_location)
34
+ data.merge!(extract_unpermitted_params)
35
+ data.merge!(custom_options(event))
36
+ end
37
+
38
+ %i[initial_data extract_status extract_runtimes
39
+ extract_location extract_unpermitted_params].each do |method_name|
40
+ define_method(method_name) { |*_arg| {} }
41
+ end
42
+
43
+ def extract_status(payload)
44
+ if (status = payload[:status])
45
+ { status: status.to_i }
46
+ elsif (error = payload[:exception])
47
+ exception, message = error
48
+ { status: get_error_status_code(exception), error: "#{exception}: #{message}" }
49
+ else
50
+ { status: default_status }
51
+ end
52
+ end
53
+
54
+ def default_status
55
+ 0
56
+ end
57
+
58
+ def get_error_status_code(exception_class_name)
59
+ ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
60
+ end
61
+
62
+ def custom_options(event)
63
+ options = Lograge.custom_options(event) || {}
64
+ options.merge event.payload[:custom_payload] || {}
65
+ end
66
+
67
+ def before_format(data, payload)
68
+ Lograge.before_format(data, payload)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
1
4
  require 'active_support/ordered_options'
2
5
 
3
6
  module Lograge
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lograge
4
+ module ActionCable
5
+ module ChannelInstrumentation
6
+ def subscribe_to_channel
7
+ ActiveSupport::Notifications.instrument('subscribe.action_cable', notification_payload('subscribe')) { super }
8
+ end
9
+
10
+ def unsubscribe_from_channel
11
+ ActiveSupport::Notifications.instrument('unsubscribe.action_cable', notification_payload('unsubscribe')) do
12
+ super
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def notification_payload(method_name)
19
+ { channel_class: self.class.name, action: method_name }
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ ActionCable::Channel::Base.prepend(Lograge::ActionCable::ChannelInstrumentation)
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lograge
4
+ module ActionCable
5
+ module ConnectionInstrumentation
6
+ def handle_open
7
+ ActiveSupport::Notifications.instrument('connect.action_cable', notification_payload('connect')) { super }
8
+ end
9
+
10
+ def handle_close
11
+ ActiveSupport::Notifications.instrument('disconnect.action_cable', notification_payload('disconnect')) { super }
12
+ end
13
+
14
+ def notification_payload(method_name)
15
+ { connection_class: self.class.name, action: method_name, data: request.params }
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ ActionCable::Connection::Base.prepend(Lograge::ActionCable::ConnectionInstrumentation)
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionCable
4
+ module Server
5
+ class Base
6
+ mattr_accessor :logger
7
+ self.logger = Lograge::SilentLogger.new(config.logger)
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
1
4
  require 'active_support/concern'
2
5
  require 'rails/rack/logger'
3
6
 
@@ -9,17 +12,19 @@ module Rails
9
12
  # that say:
10
13
  # Started GET / for 192.168.2.1...
11
14
  class Logger
12
- # Overwrites Rails 3.2 code that logs new requests
15
+ # Overwrites Rails code that logs new requests
13
16
  def call_app(*args)
14
17
  env = args.last
15
- @app.call(env)
18
+ status, headers, body = @app.call(env)
19
+ # needs to have same return type as the Rails builtins being overridden, see https://github.com/roidrage/lograge/pull/333
20
+ # https://github.com/rails/rails/blob/be9d34b9bcb448b265114ebc28bef1a5b5e4c272/railties/lib/rails/rack/logger.rb#L37
21
+ [status, headers, ::Rack::BodyProxy.new(body) {}] # rubocop:disable Lint/EmptyBlock
16
22
  ensure
17
23
  ActiveSupport::LogSubscriber.flush_all!
18
24
  end
19
25
 
20
26
  # Overwrites Rails 3.0/3.1 code that logs new requests
21
- def before_dispatch(_env)
22
- end
27
+ def before_dispatch(_env); end
23
28
  end
24
29
  end
25
30
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/railtie'
2
4
  require 'action_view/log_subscriber'
3
5
  require 'action_controller/log_subscriber'
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+
5
+ module Lograge
6
+ class SilentLogger < SimpleDelegator
7
+ %i[debug info warn error fatal unknown].each do |method_name|
8
+ # rubocop:disable Lint/EmptyBlock
9
+ define_method(method_name) { |*_args| }
10
+ # rubocop:enable Lint/EmptyBlock
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lograge
2
- VERSION = '0.7.1'.freeze
4
+ VERSION = '0.12.0'
3
5
  end
data/lib/lograge.rb CHANGED
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'lograge/version'
4
+ require 'lograge/formatters/helpers/method_and_path'
2
5
  require 'lograge/formatters/cee'
3
6
  require 'lograge/formatters/json'
4
7
  require 'lograge/formatters/graylog2'
@@ -8,12 +11,16 @@ require 'lograge/formatters/lines'
8
11
  require 'lograge/formatters/logstash'
9
12
  require 'lograge/formatters/ltsv'
10
13
  require 'lograge/formatters/raw'
11
- require 'lograge/log_subscriber'
14
+ require 'lograge/log_subscribers/base'
15
+ require 'lograge/log_subscribers/action_cable'
16
+ require 'lograge/log_subscribers/action_controller'
17
+ require 'lograge/silent_logger'
12
18
  require 'lograge/ordered_options'
19
+ require 'active_support'
13
20
  require 'active_support/core_ext/module/attribute_accessors'
14
21
  require 'active_support/core_ext/string/inflections'
15
22
 
16
- # rubocop:disable ModuleLength
23
+ # rubocop:disable Metrics/ModuleLength
17
24
  module Lograge
18
25
  module_function
19
26
 
@@ -63,10 +70,14 @@ module Lograge
63
70
  def ignore_actions(actions)
64
71
  ignore(lambda do |event|
65
72
  params = event.payload
66
- Array(actions).include?("#{params[:controller]}##{params[:action]}")
73
+ Array(actions).include?("#{controller_field(params)}##{params[:action]}")
67
74
  end)
68
75
  end
69
76
 
77
+ def controller_field(params)
78
+ params[:controller] || params[:channel_class] || params[:connection_class]
79
+ end
80
+
70
81
  def ignore_tests
71
82
  @ignore_tests ||= []
72
83
  end
@@ -109,9 +120,7 @@ module Lograge
109
120
  events = subscriber.public_methods(false).reject { |method| method.to_s == 'call' }
110
121
  events.each do |event|
111
122
  ActiveSupport::Notifications.notifier.listeners_for("#{event}.#{component}").each do |listener|
112
- if listener.instance_variable_get('@delegate') == subscriber
113
- ActiveSupport::Notifications.unsubscribe listener
114
- end
123
+ ActiveSupport::Notifications.unsubscribe listener if listener.instance_variable_get('@delegate') == subscriber
115
124
  end
116
125
  end
117
126
  end
@@ -122,6 +131,8 @@ module Lograge
122
131
  keep_original_rails_log
123
132
 
124
133
  attach_to_action_controller
134
+ attach_to_action_cable if defined?(ActionCable)
135
+
125
136
  set_lograge_log_options
126
137
  setup_custom_payload
127
138
  support_deprecated_config # TODO: Remove with version 1.0
@@ -139,16 +150,33 @@ module Lograge
139
150
  end
140
151
 
141
152
  def attach_to_action_controller
142
- Lograge::RequestLogSubscriber.attach_to :action_controller
153
+ Lograge::LogSubscribers::ActionController.attach_to :action_controller
154
+ end
155
+
156
+ def attach_to_action_cable
157
+ require 'lograge/rails_ext/action_cable/channel/base'
158
+ require 'lograge/rails_ext/action_cable/connection/base'
159
+
160
+ Lograge::LogSubscribers::ActionCable.attach_to :action_cable
143
161
  end
144
162
 
145
163
  def setup_custom_payload
146
164
  return unless lograge_config.custom_payload_method.respond_to?(:call)
147
- base_controller_class = lograge_config.base_controller_class.try(:constantize) || ActionController::Base
148
- append_payload_method = base_controller_class.instance_method(:append_info_to_payload)
165
+
166
+ base_classes = Array(lograge_config.base_controller_class)
167
+ base_classes.map! { |klass| klass.try(:constantize) }
168
+ base_classes << ActionController::Base if base_classes.empty?
169
+
170
+ base_classes.each do |base_class|
171
+ extend_base_class(base_class)
172
+ end
173
+ end
174
+
175
+ def extend_base_class(klass)
176
+ append_payload_method = klass.instance_method(:append_info_to_payload)
149
177
  custom_payload_method = lograge_config.custom_payload_method
150
178
 
151
- base_controller_class.send(:define_method, :append_info_to_payload) do |payload|
179
+ klass.send(:define_method, :append_info_to_payload) do |payload|
152
180
  append_payload_method.bind(self).call(payload)
153
181
  payload[:custom_payload] = custom_payload_method.call(self)
154
182
  end
@@ -169,11 +197,14 @@ module Lograge
169
197
  return if lograge_config.keep_original_rails_log
170
198
 
171
199
  require 'lograge/rails_ext/rack/logger'
200
+
201
+ require 'lograge/rails_ext/action_cable/server/base' if defined?(ActionCable)
202
+
172
203
  Lograge.remove_existing_log_subscriptions
173
204
  end
174
205
 
175
206
  def rack_cache_hashlike?(app)
176
- app.config.action_dispatch.rack_cache && app.config.action_dispatch.rack_cache.respond_to?(:[]=)
207
+ app.config.action_dispatch.rack_cache&.respond_to?(:[]=)
177
208
  end
178
209
  private_class_method :rack_cache_hashlike?
179
210
 
@@ -193,5 +224,6 @@ module Lograge
193
224
  application.config.lograge
194
225
  end
195
226
  end
227
+ # rubocop:enable Metrics/ModuleLength
196
228
 
197
229
  require 'lograge/railtie' if defined?(Rails)
metadata CHANGED
@@ -1,129 +1,129 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lograge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathias Meyer
8
8
  - Ben Lovell
9
- autorequire:
9
+ - Michael Bianco
10
+ autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2017-09-19 00:00:00.000000000 Z
13
+ date: 2022-03-30 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rspec
16
17
  requirement: !ruby/object:Gem::Requirement
17
18
  requirements:
18
- - - '>='
19
+ - - "~>"
19
20
  - !ruby/object:Gem::Version
20
- version: '0'
21
+ version: '3.1'
21
22
  type: :development
22
23
  prerelease: false
23
24
  version_requirements: !ruby/object:Gem::Requirement
24
25
  requirements:
25
- - - '>='
26
+ - - "~>"
26
27
  - !ruby/object:Gem::Version
27
- version: '0'
28
+ version: '3.1'
28
29
  - !ruby/object:Gem::Dependency
29
30
  name: rubocop
30
31
  requirement: !ruby/object:Gem::Requirement
31
32
  requirements:
32
- - - '='
33
+ - - "~>"
33
34
  - !ruby/object:Gem::Version
34
- version: 0.46.0
35
+ version: '1.23'
35
36
  type: :development
36
37
  prerelease: false
37
38
  version_requirements: !ruby/object:Gem::Requirement
38
39
  requirements:
39
- - - '='
40
+ - - "~>"
40
41
  - !ruby/object:Gem::Version
41
- version: 0.46.0
42
+ version: '1.23'
42
43
  - !ruby/object:Gem::Dependency
43
- name: activesupport
44
+ name: simplecov
44
45
  requirement: !ruby/object:Gem::Requirement
45
46
  requirements:
46
- - - '>='
47
+ - - "~>"
47
48
  - !ruby/object:Gem::Version
48
- version: '4'
49
- - - <
49
+ version: '0.21'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '0.21'
57
+ - !ruby/object:Gem::Dependency
58
+ name: actionpack
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
50
62
  - !ruby/object:Gem::Version
51
- version: '5.2'
63
+ version: '4'
52
64
  type: :runtime
53
65
  prerelease: false
54
66
  version_requirements: !ruby/object:Gem::Requirement
55
67
  requirements:
56
- - - '>='
68
+ - - ">="
57
69
  - !ruby/object:Gem::Version
58
70
  version: '4'
59
- - - <
60
- - !ruby/object:Gem::Version
61
- version: '5.2'
62
71
  - !ruby/object:Gem::Dependency
63
- name: actionpack
72
+ name: activesupport
64
73
  requirement: !ruby/object:Gem::Requirement
65
74
  requirements:
66
- - - '>='
75
+ - - ">="
67
76
  - !ruby/object:Gem::Version
68
77
  version: '4'
69
- - - <
70
- - !ruby/object:Gem::Version
71
- version: '5.2'
72
78
  type: :runtime
73
79
  prerelease: false
74
80
  version_requirements: !ruby/object:Gem::Requirement
75
81
  requirements:
76
- - - '>='
82
+ - - ">="
77
83
  - !ruby/object:Gem::Version
78
84
  version: '4'
79
- - - <
80
- - !ruby/object:Gem::Version
81
- version: '5.2'
82
85
  - !ruby/object:Gem::Dependency
83
86
  name: railties
84
87
  requirement: !ruby/object:Gem::Requirement
85
88
  requirements:
86
- - - '>='
89
+ - - ">="
87
90
  - !ruby/object:Gem::Version
88
91
  version: '4'
89
- - - <
90
- - !ruby/object:Gem::Version
91
- version: '5.2'
92
92
  type: :runtime
93
93
  prerelease: false
94
94
  version_requirements: !ruby/object:Gem::Requirement
95
95
  requirements:
96
- - - '>='
96
+ - - ">="
97
97
  - !ruby/object:Gem::Version
98
98
  version: '4'
99
- - - <
100
- - !ruby/object:Gem::Version
101
- version: '5.2'
102
99
  - !ruby/object:Gem::Dependency
103
100
  name: request_store
104
101
  requirement: !ruby/object:Gem::Requirement
105
102
  requirements:
106
- - - ~>
103
+ - - "~>"
107
104
  - !ruby/object:Gem::Version
108
105
  version: '1.0'
109
106
  type: :runtime
110
107
  prerelease: false
111
108
  version_requirements: !ruby/object:Gem::Requirement
112
109
  requirements:
113
- - - ~>
110
+ - - "~>"
114
111
  - !ruby/object:Gem::Version
115
112
  version: '1.0'
116
113
  description: Tame Rails' multi-line logging into a single line per request
117
114
  email:
118
115
  - meyer@paperplanes.de
119
116
  - benjamin.lovell@gmail.com
117
+ - mike@mikebian.co
120
118
  executables: []
121
119
  extensions: []
122
120
  extra_rdoc_files: []
123
121
  files:
122
+ - LICENSE.txt
124
123
  - lib/lograge.rb
125
124
  - lib/lograge/formatters/cee.rb
126
125
  - lib/lograge/formatters/graylog2.rb
126
+ - lib/lograge/formatters/helpers/method_and_path.rb
127
127
  - lib/lograge/formatters/json.rb
128
128
  - lib/lograge/formatters/key_value.rb
129
129
  - lib/lograge/formatters/l2met.rb
@@ -131,33 +131,39 @@ files:
131
131
  - lib/lograge/formatters/logstash.rb
132
132
  - lib/lograge/formatters/ltsv.rb
133
133
  - lib/lograge/formatters/raw.rb
134
- - lib/lograge/log_subscriber.rb
134
+ - lib/lograge/log_subscribers/action_cable.rb
135
+ - lib/lograge/log_subscribers/action_controller.rb
136
+ - lib/lograge/log_subscribers/base.rb
135
137
  - lib/lograge/ordered_options.rb
138
+ - lib/lograge/rails_ext/action_cable/channel/base.rb
139
+ - lib/lograge/rails_ext/action_cable/connection/base.rb
140
+ - lib/lograge/rails_ext/action_cable/server/base.rb
136
141
  - lib/lograge/rails_ext/rack/logger.rb
137
142
  - lib/lograge/railtie.rb
143
+ - lib/lograge/silent_logger.rb
138
144
  - lib/lograge/version.rb
139
145
  homepage: https://github.com/roidrage/lograge
140
146
  licenses:
141
147
  - MIT
142
- metadata: {}
143
- post_install_message:
148
+ metadata:
149
+ rubygems_mfa_required: 'true'
150
+ post_install_message:
144
151
  rdoc_options: []
145
152
  require_paths:
146
153
  - lib
147
154
  required_ruby_version: !ruby/object:Gem::Requirement
148
155
  requirements:
149
- - - '>='
156
+ - - ">="
150
157
  - !ruby/object:Gem::Version
151
- version: '0'
158
+ version: '2.5'
152
159
  required_rubygems_version: !ruby/object:Gem::Requirement
153
160
  requirements:
154
- - - '>='
161
+ - - ">="
155
162
  - !ruby/object:Gem::Version
156
163
  version: '0'
157
164
  requirements: []
158
- rubyforge_project:
159
- rubygems_version: 2.0.14.1
160
- signing_key:
165
+ rubygems_version: 3.1.6
166
+ signing_key:
161
167
  specification_version: 4
162
168
  summary: Tame Rails' multi-line logging into a single line per request
163
169
  test_files: []
@@ -1,118 +0,0 @@
1
- require 'json'
2
- require 'action_pack'
3
- require 'active_support/core_ext/class/attribute'
4
- require 'active_support/log_subscriber'
5
- require 'request_store'
6
-
7
- module Lograge
8
- class RequestLogSubscriber < ActiveSupport::LogSubscriber
9
- def process_action(event)
10
- return if Lograge.ignore?(event)
11
-
12
- payload = event.payload
13
- data = extract_request(event, payload)
14
- data = before_format(data, payload)
15
- formatted_message = Lograge.formatter.call(data)
16
- logger.send(Lograge.log_level, formatted_message)
17
- end
18
-
19
- def redirect_to(event)
20
- RequestStore.store[:lograge_location] = event.payload[:location]
21
- end
22
-
23
- def unpermitted_parameters(event)
24
- RequestStore.store[:lograge_unpermitted_params] ||= []
25
- RequestStore.store[:lograge_unpermitted_params].concat(event.payload[:keys])
26
- end
27
-
28
- def logger
29
- Lograge.logger.presence || super
30
- end
31
-
32
- private
33
-
34
- def extract_request(event, payload)
35
- payload = event.payload
36
- data = initial_data(payload)
37
- data.merge!(extract_status(payload))
38
- data.merge!(extract_runtimes(event, payload))
39
- data.merge!(extract_location)
40
- data.merge!(extract_unpermitted_params)
41
- data.merge!(custom_options(event))
42
- end
43
-
44
- def initial_data(payload)
45
- {
46
- method: payload[:method],
47
- path: extract_path(payload),
48
- format: extract_format(payload),
49
- controller: payload[:controller],
50
- action: payload[:action]
51
- }
52
- end
53
-
54
- def extract_path(payload)
55
- path = payload[:path]
56
- index = path.index('?')
57
- index ? path[0, index] : path
58
- end
59
-
60
- if ::ActionPack::VERSION::MAJOR == 3 && ::ActionPack::VERSION::MINOR.zero?
61
- def extract_format(payload)
62
- payload[:formats].first
63
- end
64
- else
65
- def extract_format(payload)
66
- payload[:format]
67
- end
68
- end
69
-
70
- def extract_status(payload)
71
- if (status = payload[:status])
72
- { status: status.to_i }
73
- elsif (error = payload[:exception])
74
- exception, message = error
75
- { status: get_error_status_code(exception), error: "#{exception}: #{message}" }
76
- else
77
- { status: 0 }
78
- end
79
- end
80
-
81
- def get_error_status_code(exception)
82
- status = ActionDispatch::ExceptionWrapper.rescue_responses[exception]
83
- Rack::Utils.status_code(status)
84
- end
85
-
86
- def custom_options(event)
87
- options = Lograge.custom_options(event) || {}
88
- options.merge event.payload[:custom_payload] || {}
89
- end
90
-
91
- def before_format(data, payload)
92
- Lograge.before_format(data, payload)
93
- end
94
-
95
- def extract_runtimes(event, payload)
96
- data = { duration: event.duration.to_f.round(2) }
97
- data[:view] = payload[:view_runtime].to_f.round(2) if payload.key?(:view_runtime)
98
- data[:db] = payload[:db_runtime].to_f.round(2) if payload.key?(:db_runtime)
99
- data
100
- end
101
-
102
- def extract_location
103
- location = RequestStore.store[:lograge_location]
104
- return {} unless location
105
-
106
- RequestStore.store[:lograge_location] = nil
107
- { location: location }
108
- end
109
-
110
- def extract_unpermitted_params
111
- unpermitted_params = RequestStore.store[:lograge_unpermitted_params]
112
- return {} unless unpermitted_params
113
-
114
- RequestStore.store[:lograge_unpermitted_params] = nil
115
- { unpermitted_params: unpermitted_params }
116
- end
117
- end
118
- end