lograge 0.10.0 → 0.11.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
- SHA256:
3
- metadata.gz: 90e32e509e2b788089246d22c8755d69d495d54f807a8e52e3e0fee3406a448c
4
- data.tar.gz: 1f969f77c0d5b3878e8a090be723888ba037f982d9688b12ace2f672ce450d9f
2
+ SHA1:
3
+ metadata.gz: e1eb9c940253292149764ed04a37b52b18932e37
4
+ data.tar.gz: 8f2e6d001d7665291e67f74b20f4d14624f66ce6
5
5
  SHA512:
6
- metadata.gz: b253f8a2a86557ed264df935b94379f61ef90c426d83d901672c4deef286e40a934c9e596f23ddf22195d8549207ce213ea67a35a039008ace6202c0b131f29b
7
- data.tar.gz: 0112025bfd732a2b41a52c8325e5cc090b94c2056f2d819d8afe9491f063d01c7be3950e25a2707de4955d15b5d8ca59368eab5236ef634f9ceb1c3ac301dafe
6
+ metadata.gz: 6b85d69b8fae8f7dc38526068f9bf7bcd3cc5ba4ca6439e99f0d89acfb3b6851676ac100d1c3d02863a189aa45378e497fe4015a873cecfb389e75d896adc9f0
7
+ data.tar.gz: dd9aa6804d6737c9e48794e5fc8947fc84884043810835dc29ba26a37b5d986e48251279f2e35e39ad0002a877d79ae106d1c3741142dc5fab770759d517023c
@@ -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,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,11 +9,19 @@ 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'
12
16
  require 'lograge/ordered_options'
13
17
  require 'active_support/core_ext/module/attribute_accessors'
14
18
  require 'active_support/core_ext/string/inflections'
15
19
 
20
+ if defined?(ActionCable)
21
+ require 'lograge/rails_ext/action_cable/channel/base'
22
+ require 'lograge/rails_ext/action_cable/connection/base'
23
+ end
24
+
16
25
  # rubocop:disable ModuleLength
17
26
  module Lograge
18
27
  module_function
@@ -63,10 +72,14 @@ module Lograge
63
72
  def ignore_actions(actions)
64
73
  ignore(lambda do |event|
65
74
  params = event.payload
66
- Array(actions).include?("#{params[:controller]}##{params[:action]}")
75
+ Array(actions).include?("#{controller_field(params)}##{params[:action]}")
67
76
  end)
68
77
  end
69
78
 
79
+ def controller_field(params)
80
+ params[:controller] || params[:channel_class] || params[:connection_class]
81
+ end
82
+
70
83
  def ignore_tests
71
84
  @ignore_tests ||= []
72
85
  end
@@ -122,6 +135,8 @@ module Lograge
122
135
  keep_original_rails_log
123
136
 
124
137
  attach_to_action_controller
138
+ attach_to_action_cable if defined?(ActionCable)
139
+
125
140
  set_lograge_log_options
126
141
  setup_custom_payload
127
142
  support_deprecated_config # TODO: Remove with version 1.0
@@ -139,24 +154,29 @@ module Lograge
139
154
  end
140
155
 
141
156
  def attach_to_action_controller
142
- Lograge::RequestLogSubscriber.attach_to :action_controller
157
+ Lograge::LogSubscribers::ActionController.attach_to :action_controller
158
+ end
159
+
160
+ def attach_to_action_cable
161
+ Lograge::LogSubscribers::ActionCable.attach_to :action_cable
143
162
  end
144
163
 
145
164
  def setup_custom_payload
146
165
  return unless lograge_config.custom_payload_method.respond_to?(:call)
147
166
 
148
- base_controller_classes = Array(lograge_config.base_controller_class)
149
- base_controller_classes.map! { |klass| klass.try(:constantize) }
150
- if base_controller_classes.empty?
151
- base_controller_classes << ActionController::Base
167
+ base_classes = Array(lograge_config.base_controller_class)
168
+ base_classes.map! { |klass| klass.try(:constantize) }
169
+ if base_classes.empty?
170
+ base_classes << ActionController::Base
171
+ base_classes << ActionCable::Channel::Base if defined?(ActionCable)
152
172
  end
153
173
 
154
- base_controller_classes.each do |base_controller_class|
155
- extend_base_controller_class(base_controller_class)
174
+ base_classes.each do |base_class|
175
+ extend_base_class(base_class)
156
176
  end
157
177
  end
158
178
 
159
- def extend_base_controller_class(klass)
179
+ def extend_base_class(klass)
160
180
  append_payload_method = klass.instance_method(:append_info_to_payload)
161
181
  custom_payload_method = lograge_config.custom_payload_method
162
182
 
@@ -181,6 +201,9 @@ module Lograge
181
201
  return if lograge_config.keep_original_rails_log
182
202
 
183
203
  require 'lograge/rails_ext/rack/logger'
204
+
205
+ require 'lograge/rails_ext/action_cable/server/base' if defined?(ActionCable)
206
+
184
207
  Lograge.remove_existing_log_subscriptions
185
208
  end
186
209
 
@@ -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
@@ -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,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
@@ -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.10.0'.freeze
2
+ VERSION = '0.11.0'.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.10.0
4
+ version: 0.11.0
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: 2018-03-29 00:00:00.000000000 Z
12
+ date: 2019-04-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -103,9 +103,11 @@ executables: []
103
103
  extensions: []
104
104
  extra_rdoc_files: []
105
105
  files:
106
+ - LICENSE.txt
106
107
  - lib/lograge.rb
107
108
  - lib/lograge/formatters/cee.rb
108
109
  - lib/lograge/formatters/graylog2.rb
110
+ - lib/lograge/formatters/helpers/method_and_path.rb
109
111
  - lib/lograge/formatters/json.rb
110
112
  - lib/lograge/formatters/key_value.rb
111
113
  - lib/lograge/formatters/l2met.rb
@@ -113,10 +115,16 @@ files:
113
115
  - lib/lograge/formatters/logstash.rb
114
116
  - lib/lograge/formatters/ltsv.rb
115
117
  - lib/lograge/formatters/raw.rb
116
- - 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
117
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
118
125
  - lib/lograge/rails_ext/rack/logger.rb
119
126
  - lib/lograge/railtie.rb
127
+ - lib/lograge/silent_logger.rb
120
128
  - lib/lograge/version.rb
121
129
  homepage: https://github.com/roidrage/lograge
122
130
  licenses:
@@ -138,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
146
  version: '0'
139
147
  requirements: []
140
148
  rubyforge_project:
141
- rubygems_version: 2.7.3
149
+ rubygems_version: 2.6.14
142
150
  signing_key:
143
151
  specification_version: 4
144
152
  summary: Tame Rails' multi-line logging into a single line per request
@@ -1,122 +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
- strip_query_string(path)
57
- end
58
-
59
- def strip_query_string(path)
60
- index = path.index('?')
61
- index ? path[0, index] : path
62
- end
63
-
64
- if ::ActionPack::VERSION::MAJOR == 3 && ::ActionPack::VERSION::MINOR.zero?
65
- def extract_format(payload)
66
- payload[:formats].first
67
- end
68
- else
69
- def extract_format(payload)
70
- payload[:format]
71
- end
72
- end
73
-
74
- def extract_status(payload)
75
- if (status = payload[:status])
76
- { status: status.to_i }
77
- elsif (error = payload[:exception])
78
- exception, message = error
79
- { status: get_error_status_code(exception), error: "#{exception}: #{message}" }
80
- else
81
- { status: 0 }
82
- end
83
- end
84
-
85
- def get_error_status_code(exception)
86
- status = ActionDispatch::ExceptionWrapper.rescue_responses[exception]
87
- Rack::Utils.status_code(status)
88
- end
89
-
90
- def custom_options(event)
91
- options = Lograge.custom_options(event) || {}
92
- options.merge event.payload[:custom_payload] || {}
93
- end
94
-
95
- def before_format(data, payload)
96
- Lograge.before_format(data, payload)
97
- end
98
-
99
- def extract_runtimes(event, payload)
100
- data = { duration: event.duration.to_f.round(2) }
101
- data[:view] = payload[:view_runtime].to_f.round(2) if payload.key?(:view_runtime)
102
- data[:db] = payload[:db_runtime].to_f.round(2) if payload.key?(:db_runtime)
103
- data
104
- end
105
-
106
- def extract_location
107
- location = RequestStore.store[:lograge_location]
108
- return {} unless location
109
-
110
- RequestStore.store[:lograge_location] = nil
111
- { location: strip_query_string(location) }
112
- end
113
-
114
- def extract_unpermitted_params
115
- unpermitted_params = RequestStore.store[:lograge_unpermitted_params]
116
- return {} unless unpermitted_params
117
-
118
- RequestStore.store[:lograge_unpermitted_params] = nil
119
- { unpermitted_params: unpermitted_params }
120
- end
121
- end
122
- end