lograge 0.4.1 → 0.11.2

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
- SHA1:
3
- metadata.gz: 514cdd97c4576f95096747c26faf15588976f75c
4
- data.tar.gz: 6993df085818c95538cadbabe95a0022bd8f3e75
2
+ SHA256:
3
+ metadata.gz: 1b182acc461273304ebb8b5395f65c4eeec4a170639d0b52b0d608a1aa786c03
4
+ data.tar.gz: e558ad86b2ae007d24c18d3e15ca2262f61432058508c22feba1c0f63d5ec9be
5
5
  SHA512:
6
- metadata.gz: a42d13bca3efc4f152182ada6aae4b229ccd6e8cc15ef58a49348f1e56df8da064367c5fba3f229b67d2743e35df91f10b9d0b4c1f5659eebadd889664aa3840
7
- data.tar.gz: 06aae1adf15374d5deea2b89b9e264dbf1845914f2d8b6ff8ab72038db514f7aa6a0df46a98d5af7e8fb01a004334956dde676bc48c9f181487d9da31dde7d73
6
+ metadata.gz: d9bda7af87bbd4020194aae53d44f29585eadf590d03e490276f025dadbb5bc189d94e9e270437bbb857c0b3da91b9a91f1ba7c833d84d19f835bae7b1960c09
7
+ data.tar.gz: 125e9f98472208bc85f5fe2f810ccfae3b26c53511204fc96a808bfdf2fd1fa8046ada14a4c001abf7d59cf5c2b81eb3a5a5020eddc994fb22e8b68eb9b632af
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.
data/lib/lograge.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'lograge/version'
2
+ require 'lograge/formatters/helpers/method_and_path'
2
3
  require 'lograge/formatters/cee'
3
4
  require 'lograge/formatters/json'
4
5
  require 'lograge/formatters/graylog2'
@@ -8,10 +9,13 @@ require 'lograge/formatters/lines'
8
9
  require 'lograge/formatters/logstash'
9
10
  require 'lograge/formatters/ltsv'
10
11
  require 'lograge/formatters/raw'
11
- require 'lograge/log_subscriber'
12
+ require 'lograge/log_subscribers/base'
13
+ require 'lograge/log_subscribers/action_cable'
14
+ require 'lograge/log_subscribers/action_controller'
15
+ require 'lograge/silent_logger'
16
+ require 'lograge/ordered_options'
12
17
  require 'active_support/core_ext/module/attribute_accessors'
13
18
  require 'active_support/core_ext/string/inflections'
14
- require 'active_support/ordered_options'
15
19
 
16
20
  # rubocop:disable ModuleLength
17
21
  module Lograge
@@ -51,7 +55,7 @@ module Lograge
51
55
  # Set conditions for events that should be ignored
52
56
  #
53
57
  # Currently supported formats are:
54
- # - A single string representing a controller action, e.g. 'users#sign_in'
58
+ # - A single string representing a controller action, e.g. 'UsersController#sign_in'
55
59
  # - An array of strings representing controller actions
56
60
  # - An object that responds to call with an event argument and returns
57
61
  # true iff the event should be ignored.
@@ -63,10 +67,14 @@ module Lograge
63
67
  def ignore_actions(actions)
64
68
  ignore(lambda do |event|
65
69
  params = event.payload
66
- Array(actions).include?("#{params[:controller]}##{params[:action]}")
70
+ Array(actions).include?("#{controller_field(params)}##{params[:action]}")
67
71
  end)
68
72
  end
69
73
 
74
+ def controller_field(params)
75
+ params[:controller] || params[:channel_class] || params[:connection_class]
76
+ end
77
+
70
78
  def ignore_tests
71
79
  @ignore_tests ||= []
72
80
  end
@@ -122,7 +130,10 @@ module Lograge
122
130
  keep_original_rails_log
123
131
 
124
132
  attach_to_action_controller
133
+ attach_to_action_cable if defined?(ActionCable)
134
+
125
135
  set_lograge_log_options
136
+ setup_custom_payload
126
137
  support_deprecated_config # TODO: Remove with version 1.0
127
138
  set_formatter
128
139
  set_ignores
@@ -138,7 +149,36 @@ module Lograge
138
149
  end
139
150
 
140
151
  def attach_to_action_controller
141
- Lograge::RequestLogSubscriber.attach_to :action_controller
152
+ Lograge::LogSubscribers::ActionController.attach_to :action_controller
153
+ end
154
+
155
+ def attach_to_action_cable
156
+ require 'lograge/rails_ext/action_cable/channel/base'
157
+ require 'lograge/rails_ext/action_cable/connection/base'
158
+
159
+ Lograge::LogSubscribers::ActionCable.attach_to :action_cable
160
+ end
161
+
162
+ def setup_custom_payload
163
+ return unless lograge_config.custom_payload_method.respond_to?(:call)
164
+
165
+ base_classes = Array(lograge_config.base_controller_class)
166
+ base_classes.map! { |klass| klass.try(:constantize) }
167
+ base_classes << ActionController::Base if base_classes.empty?
168
+
169
+ base_classes.each do |base_class|
170
+ extend_base_class(base_class)
171
+ end
172
+ end
173
+
174
+ def extend_base_class(klass)
175
+ append_payload_method = klass.instance_method(:append_info_to_payload)
176
+ custom_payload_method = lograge_config.custom_payload_method
177
+
178
+ klass.send(:define_method, :append_info_to_payload) do |payload|
179
+ append_payload_method.bind(self).call(payload)
180
+ payload[:custom_payload] = custom_payload_method.call(self)
181
+ end
142
182
  end
143
183
 
144
184
  def set_lograge_log_options
@@ -156,6 +196,9 @@ module Lograge
156
196
  return if lograge_config.keep_original_rails_log
157
197
 
158
198
  require 'lograge/rails_ext/rack/logger'
199
+
200
+ require 'lograge/rails_ext/action_cable/server/base' if defined?(ActionCable)
201
+
159
202
  Lograge.remove_existing_log_subscriptions
160
203
  end
161
204
 
@@ -1,6 +1,8 @@
1
1
  module Lograge
2
2
  module Formatters
3
3
  class Graylog2
4
+ include Lograge::Formatters::Helpers::MethodAndPath
5
+
4
6
  def call(data)
5
7
  # Cloning because we don't want to mess with the original when mutating keys.
6
8
  data_clone = data.clone
@@ -23,7 +25,7 @@ module Lograge
23
25
  end
24
26
 
25
27
  def short_message(data)
26
- "[#{data[:status]}] #{data[:method]} #{data[:path]} (#{data[:controller]}##{data[:action]})"
28
+ "[#{data[:status]}]#{method_and_path_string(data)}(#{data[:controller]}##{data[:action]})"
27
29
  end
28
30
  end
29
31
  end
@@ -0,0 +1,12 @@
1
+ module Lograge
2
+ module Formatters
3
+ module Helpers
4
+ module MethodAndPath
5
+ def method_and_path_string(data)
6
+ method_and_path = [data[:method], data[:path]].compact
7
+ method_and_path.any?(&:present?) ? " #{method_and_path.join(' ')} " : ' '
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -2,27 +2,29 @@ module Lograge
2
2
  module Formatters
3
3
  class KeyValue
4
4
  def call(data)
5
- fields = fields_to_display(data)
6
-
7
- event = fields.map { |key| format(key, data[key]) }
8
- event.join(' ')
5
+ fields_to_display(data)
6
+ .map { |key| format(key, data[key]) }
7
+ .join(' ')
9
8
  end
10
9
 
10
+ protected
11
+
11
12
  def fields_to_display(data)
12
13
  data.keys
13
14
  end
14
15
 
15
16
  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
17
+ "#{key}=#{parse_value(key, value)}"
18
+ end
19
+
20
+ def parse_value(key, value)
21
+ # Exactly preserve the previous output
22
+ # Parsing this can be ambigious if the error messages contains
23
+ # a single quote
24
+ return "'#{value}'" if key == :error
25
+ return Kernel.format('%.2f', value) if value.is_a? Float
24
26
 
25
- "#{key}=#{value}"
27
+ value
26
28
  end
27
29
  end
28
30
  end
@@ -16,20 +16,31 @@ module Lograge
16
16
  :location
17
17
  ].freeze
18
18
 
19
+ UNWANTED_FIELDS = [
20
+ :controller,
21
+ :action
22
+ ].freeze
23
+
19
24
  def call(data)
20
25
  super(modify_payload(data))
21
26
  end
22
27
 
28
+ protected
29
+
30
+ def fields_to_display(data)
31
+ L2MET_FIELDS + additional_fields(data)
32
+ end
33
+
34
+ def additional_fields(data)
35
+ (data.keys - L2MET_FIELDS) - UNWANTED_FIELDS
36
+ end
37
+
23
38
  def format(key, value)
24
39
  key = "measure#page.#{key}" if value.is_a?(Float)
25
40
 
26
41
  super(key, value)
27
42
  end
28
43
 
29
- def fields_to_display(data)
30
- L2MET_FIELDS + (data.keys - L2MET_FIELDS) - [:controller, :action]
31
- end
32
-
33
44
  def modify_payload(data)
34
45
  data[:source] = source_field(data) if data[:controller] && data[:action]
35
46
 
@@ -1,11 +1,13 @@
1
1
  module Lograge
2
2
  module Formatters
3
3
  class Logstash
4
+ include Lograge::Formatters::Helpers::MethodAndPath
5
+
4
6
  def call(data)
5
7
  load_dependencies
6
8
  event = LogStash::Event.new(data)
7
9
 
8
- event['message'] = "[#{data[:status]}] #{data[:method]} #{data[:path]} (#{data[:controller]}##{data[:action]})"
10
+ event['message'] = "[#{data[:status]}]#{method_and_path_string(data)}(#{data[:controller]}##{data[:action]})"
9
11
  event.to_json
10
12
  end
11
13
 
@@ -0,0 +1,32 @@
1
+ module Lograge
2
+ module LogSubscribers
3
+ class ActionCable < Base
4
+ %i(perform_action subscribe unsubscribe connect disconnect).each do |method_name|
5
+ define_method(method_name) do |event|
6
+ process_main_event(event)
7
+ end
8
+ end
9
+
10
+ private
11
+
12
+ def initial_data(payload)
13
+ {
14
+ method: {},
15
+ path: {},
16
+ format: {},
17
+ params: payload[:data],
18
+ controller: payload[:channel_class] || payload[:connection_class],
19
+ action: payload[:action]
20
+ }
21
+ end
22
+
23
+ def default_status
24
+ 200
25
+ end
26
+
27
+ def extract_runtimes(event, _payload)
28
+ { duration: event.duration.to_f.round(2) }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,73 @@
1
+ module Lograge
2
+ module LogSubscribers
3
+ class ActionController < Base
4
+ def process_action(event)
5
+ process_main_event(event)
6
+ end
7
+
8
+ def redirect_to(event)
9
+ RequestStore.store[:lograge_location] = event.payload[:location]
10
+ end
11
+
12
+ def unpermitted_parameters(event)
13
+ RequestStore.store[:lograge_unpermitted_params] ||= []
14
+ RequestStore.store[:lograge_unpermitted_params].concat(event.payload[:keys])
15
+ end
16
+
17
+ private
18
+
19
+ def initial_data(payload)
20
+ {
21
+ method: payload[:method],
22
+ path: extract_path(payload),
23
+ format: extract_format(payload),
24
+ controller: payload[:controller],
25
+ action: payload[:action]
26
+ }
27
+ end
28
+
29
+ def extract_path(payload)
30
+ path = payload[:path]
31
+ strip_query_string(path)
32
+ end
33
+
34
+ def strip_query_string(path)
35
+ index = path.index('?')
36
+ index ? path[0, index] : path
37
+ end
38
+
39
+ if ::ActionPack::VERSION::MAJOR == 3 && ::ActionPack::VERSION::MINOR.zero?
40
+ def extract_format(payload)
41
+ payload[:formats].first
42
+ end
43
+ else
44
+ def extract_format(payload)
45
+ payload[:format]
46
+ end
47
+ end
48
+
49
+ def extract_runtimes(event, payload)
50
+ data = { duration: event.duration.to_f.round(2) }
51
+ data[:view] = payload[:view_runtime].to_f.round(2) if payload.key?(:view_runtime)
52
+ data[:db] = payload[:db_runtime].to_f.round(2) if payload.key?(:db_runtime)
53
+ data
54
+ end
55
+
56
+ def extract_location
57
+ location = RequestStore.store[:lograge_location]
58
+ return {} unless location
59
+
60
+ RequestStore.store[:lograge_location] = nil
61
+ { location: strip_query_string(location) }
62
+ end
63
+
64
+ def extract_unpermitted_params
65
+ unpermitted_params = RequestStore.store[:lograge_unpermitted_params]
66
+ return {} unless unpermitted_params
67
+
68
+ RequestStore.store[:lograge_unpermitted_params] = nil
69
+ { unpermitted_params: unpermitted_params }
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,70 @@
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
+ module LogSubscribers
9
+ class Base < ActiveSupport::LogSubscriber
10
+ def logger
11
+ Lograge.logger.presence || super
12
+ end
13
+
14
+ private
15
+
16
+ def process_main_event(event)
17
+ return if Lograge.ignore?(event)
18
+
19
+ payload = event.payload
20
+ data = extract_request(event, payload)
21
+ data = before_format(data, payload)
22
+ formatted_message = Lograge.formatter.call(data)
23
+ logger.send(Lograge.log_level, formatted_message)
24
+ end
25
+
26
+ def extract_request(event, payload)
27
+ data = initial_data(payload)
28
+ data.merge!(extract_status(payload))
29
+ data.merge!(extract_runtimes(event, payload))
30
+ data.merge!(extract_location)
31
+ data.merge!(extract_unpermitted_params)
32
+ data.merge!(custom_options(event))
33
+ end
34
+
35
+ %i(initial_data extract_status extract_runtimes
36
+ extract_location extract_unpermitted_params).each do |method_name|
37
+ define_method(method_name) { |*_arg| {} }
38
+ end
39
+
40
+ def extract_status(payload)
41
+ if (status = payload[:status])
42
+ { status: status.to_i }
43
+ elsif (error = payload[:exception])
44
+ exception, message = error
45
+ { status: get_error_status_code(exception), error: "#{exception}: #{message}" }
46
+ else
47
+ { status: default_status }
48
+ end
49
+ end
50
+
51
+ def default_status
52
+ 0
53
+ end
54
+
55
+ def get_error_status_code(exception)
56
+ status = ActionDispatch::ExceptionWrapper.rescue_responses[exception]
57
+ Rack::Utils.status_code(status)
58
+ end
59
+
60
+ def custom_options(event)
61
+ options = Lograge.custom_options(event) || {}
62
+ options.merge event.payload[:custom_payload] || {}
63
+ end
64
+
65
+ def before_format(data, payload)
66
+ Lograge.before_format(data, payload)
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,9 @@
1
+ require 'active_support/ordered_options'
2
+
3
+ module Lograge
4
+ class OrderedOptions < ActiveSupport::OrderedOptions
5
+ def custom_payload(&block)
6
+ self.custom_payload_method = block
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ module ActionCable
2
+ module Channel
3
+ class Base
4
+ def subscribe_to_channel
5
+ ActiveSupport::Notifications.instrument('subscribe.action_cable', notification_payload('subscribe')) do
6
+ run_callbacks :subscribe do
7
+ subscribed
8
+ end
9
+
10
+ reject_subscription if subscription_rejected?
11
+ ensure_confirmation_sent
12
+ end
13
+ end
14
+
15
+ def unsubscribe_from_channel
16
+ ActiveSupport::Notifications.instrument('unsubscribe.action_cable', notification_payload('unsubscribe')) do
17
+ run_callbacks :unsubscribe do
18
+ unsubscribed
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def notification_payload(method_name)
26
+ { channel_class: self.class.name, action: method_name }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ module ActionCable
2
+ module Connection
3
+ class Base
4
+ # rubocop:disable Metrics/MethodLength
5
+ def handle_open
6
+ ActiveSupport::Notifications.instrument('connect.action_cable', notification_payload('connect')) do
7
+ begin
8
+ @protocol = websocket.protocol
9
+ connect if respond_to?(:connect)
10
+ subscribe_to_internal_channel
11
+ send_welcome_message
12
+
13
+ message_buffer.process!
14
+ server.add_connection(self)
15
+ rescue ActionCable::Connection::Authorization::UnauthorizedError
16
+ respond_to_invalid_request
17
+ end
18
+ end
19
+ end
20
+ # rubocop:enable Metrics/MethodLength
21
+
22
+ def handle_close
23
+ ActiveSupport::Notifications.instrument('disconnect.action_cable', notification_payload('disconnect')) do
24
+ logger.info finished_request_message if Lograge.lograge_config.keep_original_rails_log
25
+
26
+ server.remove_connection(self)
27
+
28
+ subscriptions.unsubscribe_from_all
29
+ unsubscribe_from_internal_channel
30
+
31
+ disconnect if respond_to?(:disconnect)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def notification_payload(method_name)
38
+ { connection_class: self.class.name, action: method_name, data: request.params }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,8 @@
1
+ module ActionCable
2
+ module Server
3
+ class Base
4
+ mattr_accessor :logger
5
+ self.logger = Lograge::SilentLogger.new(config.logger)
6
+ end
7
+ end
8
+ end
@@ -4,7 +4,7 @@ require 'action_controller/log_subscriber'
4
4
 
5
5
  module Lograge
6
6
  class Railtie < Rails::Railtie
7
- config.lograge = ActiveSupport::OrderedOptions.new
7
+ config.lograge = Lograge::OrderedOptions.new
8
8
  config.lograge.enabled = false
9
9
 
10
10
  config.after_initialize do |app|
@@ -0,0 +1,11 @@
1
+ module Lograge
2
+ class SilentLogger < SimpleDelegator
3
+ def initialize(logger)
4
+ super
5
+ end
6
+
7
+ %i(debug info warn error fatal unknown).each do |method_name|
8
+ define_method(method_name) { |*_args| }
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module Lograge
2
- VERSION = '0.4.1'.freeze
2
+ VERSION = '0.11.2'.freeze
3
3
  end
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.1
4
+ version: 0.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathias Meyer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-07-05 00:00:00.000000000 Z
12
+ date: 2019-06-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - '='
33
33
  - !ruby/object:Gem::Version
34
- version: 0.37.2
34
+ version: 0.46.0
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - '='
40
40
  - !ruby/object:Gem::Version
41
- version: 0.37.2
41
+ version: 0.46.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: activesupport
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -46,9 +46,6 @@ dependencies:
46
46
  - - ">="
47
47
  - !ruby/object:Gem::Version
48
48
  version: '4'
49
- - - "<"
50
- - !ruby/object:Gem::Version
51
- version: '5.1'
52
49
  type: :runtime
53
50
  prerelease: false
54
51
  version_requirements: !ruby/object:Gem::Requirement
@@ -56,9 +53,6 @@ dependencies:
56
53
  - - ">="
57
54
  - !ruby/object:Gem::Version
58
55
  version: '4'
59
- - - "<"
60
- - !ruby/object:Gem::Version
61
- version: '5.1'
62
56
  - !ruby/object:Gem::Dependency
63
57
  name: actionpack
64
58
  requirement: !ruby/object:Gem::Requirement
@@ -66,9 +60,6 @@ dependencies:
66
60
  - - ">="
67
61
  - !ruby/object:Gem::Version
68
62
  version: '4'
69
- - - "<"
70
- - !ruby/object:Gem::Version
71
- version: '5.1'
72
63
  type: :runtime
73
64
  prerelease: false
74
65
  version_requirements: !ruby/object:Gem::Requirement
@@ -76,9 +67,6 @@ dependencies:
76
67
  - - ">="
77
68
  - !ruby/object:Gem::Version
78
69
  version: '4'
79
- - - "<"
80
- - !ruby/object:Gem::Version
81
- version: '5.1'
82
70
  - !ruby/object:Gem::Dependency
83
71
  name: railties
84
72
  requirement: !ruby/object:Gem::Requirement
@@ -86,9 +74,6 @@ dependencies:
86
74
  - - ">="
87
75
  - !ruby/object:Gem::Version
88
76
  version: '4'
89
- - - "<"
90
- - !ruby/object:Gem::Version
91
- version: '5.1'
92
77
  type: :runtime
93
78
  prerelease: false
94
79
  version_requirements: !ruby/object:Gem::Requirement
@@ -96,9 +81,20 @@ dependencies:
96
81
  - - ">="
97
82
  - !ruby/object:Gem::Version
98
83
  version: '4'
99
- - - "<"
84
+ - !ruby/object:Gem::Dependency
85
+ name: request_store
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '1.0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
100
96
  - !ruby/object:Gem::Version
101
- version: '5.1'
97
+ version: '1.0'
102
98
  description: Tame Rails' multi-line logging into a single line per request
103
99
  email:
104
100
  - meyer@paperplanes.de
@@ -107,9 +103,11 @@ executables: []
107
103
  extensions: []
108
104
  extra_rdoc_files: []
109
105
  files:
106
+ - LICENSE.txt
110
107
  - lib/lograge.rb
111
108
  - lib/lograge/formatters/cee.rb
112
109
  - lib/lograge/formatters/graylog2.rb
110
+ - lib/lograge/formatters/helpers/method_and_path.rb
113
111
  - lib/lograge/formatters/json.rb
114
112
  - lib/lograge/formatters/key_value.rb
115
113
  - lib/lograge/formatters/l2met.rb
@@ -117,9 +115,16 @@ files:
117
115
  - lib/lograge/formatters/logstash.rb
118
116
  - lib/lograge/formatters/ltsv.rb
119
117
  - lib/lograge/formatters/raw.rb
120
- - lib/lograge/log_subscriber.rb
118
+ - lib/lograge/log_subscribers/action_cable.rb
119
+ - lib/lograge/log_subscribers/action_controller.rb
120
+ - lib/lograge/log_subscribers/base.rb
121
+ - lib/lograge/ordered_options.rb
122
+ - lib/lograge/rails_ext/action_cable/channel/base.rb
123
+ - lib/lograge/rails_ext/action_cable/connection/base.rb
124
+ - lib/lograge/rails_ext/action_cable/server/base.rb
121
125
  - lib/lograge/rails_ext/rack/logger.rb
122
126
  - lib/lograge/railtie.rb
127
+ - lib/lograge/silent_logger.rb
123
128
  - lib/lograge/version.rb
124
129
  homepage: https://github.com/roidrage/lograge
125
130
  licenses:
@@ -141,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
146
  version: '0'
142
147
  requirements: []
143
148
  rubyforge_project:
144
- rubygems_version: 2.6.4
149
+ rubygems_version: 2.7.6
145
150
  signing_key:
146
151
  specification_version: 4
147
152
  summary: Tame Rails' multi-line logging into a single line per request
@@ -1,116 +0,0 @@
1
- require 'json'
2
- require 'action_pack'
3
- require 'active_support/core_ext/class/attribute'
4
- require 'active_support/log_subscriber'
5
-
6
- module Lograge
7
- class RequestLogSubscriber < ActiveSupport::LogSubscriber
8
- def process_action(event)
9
- return if Lograge.ignore?(event)
10
-
11
- payload = event.payload
12
- data = extract_request(event, payload)
13
- data = before_format(data, payload)
14
- formatted_message = Lograge.formatter.call(data)
15
- logger.send(Lograge.log_level, formatted_message)
16
- end
17
-
18
- def redirect_to(event)
19
- Thread.current[:lograge_location] = event.payload[:location]
20
- end
21
-
22
- def unpermitted_parameters(event)
23
- Thread.current[:lograge_unpermitted_params] ||= []
24
- Thread.current[:lograge_unpermitted_params].concat(event.payload[:keys])
25
- end
26
-
27
- def logger
28
- Lograge.logger.presence || super
29
- end
30
-
31
- private
32
-
33
- def extract_request(event, payload)
34
- payload = event.payload
35
- data = initial_data(payload)
36
- data.merge!(extract_status(payload))
37
- data.merge!(extract_runtimes(event, payload))
38
- data.merge!(extract_location)
39
- data.merge!(extract_unpermitted_params)
40
- data.merge!(custom_options(event))
41
- end
42
-
43
- def initial_data(payload)
44
- {
45
- method: payload[:method],
46
- path: extract_path(payload),
47
- format: extract_format(payload),
48
- controller: payload[:controller],
49
- action: payload[:action]
50
- }
51
- end
52
-
53
- def extract_path(payload)
54
- path = payload[:path]
55
- index = path.index('?')
56
- index ? path[0, index] : path
57
- end
58
-
59
- if ::ActionPack::VERSION::MAJOR == 3 && ::ActionPack::VERSION::MINOR == 0
60
- def extract_format(payload)
61
- payload[:formats].first
62
- end
63
- else
64
- def extract_format(payload)
65
- payload[:format]
66
- end
67
- end
68
-
69
- def extract_status(payload)
70
- if (status = payload[:status])
71
- { status: status.to_i }
72
- elsif (error = payload[:exception])
73
- exception, message = error
74
- { status: get_error_status_code(exception), error: "#{exception}: #{message}" }
75
- else
76
- { status: 0 }
77
- end
78
- end
79
-
80
- def get_error_status_code(exception)
81
- status = ActionDispatch::ExceptionWrapper.rescue_responses[exception]
82
- Rack::Utils.status_code(status)
83
- end
84
-
85
- def custom_options(event)
86
- Lograge.custom_options(event) || {}
87
- end
88
-
89
- def before_format(data, payload)
90
- Lograge.before_format(data, payload)
91
- end
92
-
93
- def extract_runtimes(event, payload)
94
- data = { duration: event.duration.to_f.round(2) }
95
- data[:view] = payload[:view_runtime].to_f.round(2) if payload.key?(:view_runtime)
96
- data[:db] = payload[:db_runtime].to_f.round(2) if payload.key?(:db_runtime)
97
- data
98
- end
99
-
100
- def extract_location
101
- location = Thread.current[:lograge_location]
102
- return {} unless location
103
-
104
- Thread.current[:lograge_location] = nil
105
- { location: location }
106
- end
107
-
108
- def extract_unpermitted_params
109
- unpermitted_params = Thread.current[:lograge_unpermitted_params]
110
- return {} unless unpermitted_params
111
-
112
- Thread.current[:lograge_unpermitted_params] = nil
113
- { unpermitted_params: unpermitted_params }
114
- end
115
- end
116
- end