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 +5 -5
- data/LICENSE.txt +21 -0
- data/lib/lograge/formatters/cee.rb +2 -0
- data/lib/lograge/formatters/graylog2.rb +8 -14
- data/lib/lograge/formatters/helpers/method_and_path.rb +14 -0
- data/lib/lograge/formatters/json.rb +2 -0
- data/lib/lograge/formatters/key_value.rb +17 -13
- data/lib/lograge/formatters/l2met.rb +28 -15
- data/lib/lograge/formatters/lines.rb +2 -0
- data/lib/lograge/formatters/logstash.rb +5 -1
- data/lib/lograge/formatters/ltsv.rb +2 -0
- data/lib/lograge/formatters/raw.rb +2 -0
- data/lib/lograge/log_subscribers/action_cable.rb +34 -0
- data/lib/lograge/log_subscribers/action_controller.rb +75 -0
- data/lib/lograge/log_subscribers/base.rb +72 -0
- data/lib/lograge/ordered_options.rb +3 -0
- data/lib/lograge/rails_ext/action_cable/channel/base.rb +25 -0
- data/lib/lograge/rails_ext/action_cable/connection/base.rb +21 -0
- data/lib/lograge/rails_ext/action_cable/server/base.rb +10 -0
- data/lib/lograge/rails_ext/rack/logger.rb +9 -4
- data/lib/lograge/railtie.rb +2 -0
- data/lib/lograge/silent_logger.rb +13 -0
- data/lib/lograge/version.rb +3 -1
- data/lib/lograge.rb +43 -11
- metadata +54 -48
- data/lib/lograge/log_subscriber.rb +0 -118
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a8dc3fd38bfe24b9f1816ac75fa2d600037fd308b1b355de309d81deae032cd9
|
4
|
+
data.tar.gz: f3627f7956278364545987b845a16011463592a78dbf9ae0a409b0c8640b63e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,21 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Lograge
|
2
4
|
module Formatters
|
3
5
|
class Graylog2
|
4
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
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]}]
|
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,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
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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,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]}]
|
12
|
+
event['message'] = "[#{data[:status]}]#{method_and_path_string(data)}(#{data[:controller]}##{data[:action]})"
|
9
13
|
event.to_json
|
10
14
|
end
|
11
15
|
|
@@ -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
|
@@ -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)
|
@@ -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
|
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
|
data/lib/lograge/railtie.rb
CHANGED
@@ -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
|
data/lib/lograge/version.rb
CHANGED
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/
|
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
|
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::
|
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
|
-
|
148
|
-
|
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
|
-
|
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
|
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.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mathias Meyer
|
8
8
|
- Ben Lovell
|
9
|
-
|
9
|
+
- Michael Bianco
|
10
|
+
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date:
|
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: '
|
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: '
|
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:
|
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:
|
42
|
+
version: '1.23'
|
42
43
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
44
|
+
name: simplecov
|
44
45
|
requirement: !ruby/object:Gem::Requirement
|
45
46
|
requirements:
|
46
|
-
- -
|
47
|
+
- - "~>"
|
47
48
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
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: '
|
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:
|
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/
|
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
|
-
|
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: '
|
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
|
-
|
159
|
-
|
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
|