lograge 0.3.1 → 0.14.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 -14
- data/lib/lograge/formatters/key_value_deep.rb +42 -0
- data/lib/lograge/formatters/l2met.rb +30 -9
- data/lib/lograge/formatters/lines.rb +2 -0
- data/lib/lograge/formatters/logstash.rb +5 -1
- data/lib/lograge/formatters/ltsv.rb +44 -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 +81 -0
- data/lib/lograge/ordered_options.rb +12 -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 +8 -2
- data/lib/lograge/silent_logger.rb +13 -0
- data/lib/lograge/version.rb +3 -1
- data/lib/lograge.rb +118 -28
- metadata +69 -27
- data/lib/lograge/log_subscriber.rb +0 -96
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0d989dce1202da74220c6ac7926c3ef413502644e6f456589a334278ea357a4d
|
4
|
+
data.tar.gz: be68c46645948d5cc157a475b8820f50453fecaf9cc5e0f23bc842ec432eaa48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 273878d74ebdf36f2e703f6c4f0c70e6e17633f13dfc82bc7297ee5b209bb640a09da601768d16d4ca839bb22dfad7f0b8ee832676e4d94d4a96a90b1b5bfadc
|
7
|
+
data.tar.gz: c8503e3b547652a44076a858d0d566b1c75a273ef3efc6357398f7d5c41be7b656cf09687f96c1fe2437d16e4d8c8a657bfb7665055dab16e3a05230adf80e40
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 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,29 +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
|
-
|
24
|
-
|
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
|
25
28
|
|
26
|
-
|
29
|
+
value
|
27
30
|
end
|
28
31
|
end
|
29
32
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lograge
|
4
|
+
module Formatters
|
5
|
+
class KeyValueDeep < KeyValue
|
6
|
+
def call(data)
|
7
|
+
super flatten_keys(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def flatten_keys(data, prefix = '')
|
13
|
+
return flatten_object(data, prefix) if [Hash, Array].include? data.class
|
14
|
+
|
15
|
+
data
|
16
|
+
end
|
17
|
+
|
18
|
+
def flatten_object(data, prefix)
|
19
|
+
result = {}
|
20
|
+
loop_on_object(data) do |key, value|
|
21
|
+
key = "#{prefix}_#{key}" unless prefix.empty?
|
22
|
+
if [Hash, Array].include? value.class
|
23
|
+
result.merge!(flatten_keys(value, key))
|
24
|
+
else
|
25
|
+
result[key] = value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
def loop_on_object(data, &block)
|
32
|
+
if data.instance_of? Array
|
33
|
+
data.each_with_index do |value, index|
|
34
|
+
yield index, value
|
35
|
+
end
|
36
|
+
return
|
37
|
+
end
|
38
|
+
data.each(&block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,27 +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
|
-
|
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
|
24
|
+
].freeze
|
10
25
|
|
11
26
|
def call(data)
|
12
27
|
super(modify_payload(data))
|
13
28
|
end
|
14
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
|
+
|
15
40
|
def format(key, value)
|
16
41
|
key = "measure#page.#{key}" if value.is_a?(Float)
|
17
42
|
|
18
43
|
super(key, value)
|
19
44
|
end
|
20
45
|
|
21
|
-
def fields_to_display(data)
|
22
|
-
L2MET_FIELDS + (data.keys - L2MET_FIELDS) - [:controller, :action]
|
23
|
-
end
|
24
|
-
|
25
46
|
def modify_payload(data)
|
26
47
|
data[:source] = source_field(data) if data[:controller] && data[:action]
|
27
48
|
|
@@ -29,7 +50,7 @@ module Lograge
|
|
29
50
|
end
|
30
51
|
|
31
52
|
def source_field(data)
|
32
|
-
"#{data[:controller].to_s.
|
53
|
+
"#{data[:controller].to_s.tr('/', '-')}:#{data[:action]}"
|
33
54
|
end
|
34
55
|
end
|
35
56
|
end
|
@@ -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
|
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,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lograge
|
4
|
+
module Formatters
|
5
|
+
class LTSV
|
6
|
+
def call(data)
|
7
|
+
fields = fields_to_display(data)
|
8
|
+
|
9
|
+
event = fields.map { |key| format(key, data[key]) }
|
10
|
+
event.join("\t")
|
11
|
+
end
|
12
|
+
|
13
|
+
def fields_to_display(data)
|
14
|
+
data.keys
|
15
|
+
end
|
16
|
+
|
17
|
+
def format(key, value)
|
18
|
+
if key == :error
|
19
|
+
# Exactly preserve the previous output
|
20
|
+
# Parsing this can be ambigious if the error messages contains
|
21
|
+
# a single quote
|
22
|
+
value = "'#{escape value}'"
|
23
|
+
elsif value.is_a? Float
|
24
|
+
value = Kernel.format('%.2f', value)
|
25
|
+
end
|
26
|
+
|
27
|
+
"#{key}:#{value}"
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def escape(string)
|
33
|
+
value = string.is_a?(String) ? string.dup : string.to_s
|
34
|
+
|
35
|
+
value.gsub!('\\', '\\\\')
|
36
|
+
value.gsub!('\n', '\\n')
|
37
|
+
value.gsub!('\r', '\\r')
|
38
|
+
value.gsub!('\t', '\\t')
|
39
|
+
|
40
|
+
value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -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,81 @@
|
|
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_allocations(event))
|
33
|
+
data.merge!(extract_runtimes(event, payload))
|
34
|
+
data.merge!(extract_location)
|
35
|
+
data.merge!(extract_unpermitted_params)
|
36
|
+
data.merge!(custom_options(event))
|
37
|
+
end
|
38
|
+
|
39
|
+
%i[initial_data extract_status extract_runtimes
|
40
|
+
extract_location extract_unpermitted_params].each do |method_name|
|
41
|
+
define_method(method_name) { |*_arg| {} }
|
42
|
+
end
|
43
|
+
|
44
|
+
def extract_status(payload)
|
45
|
+
if (status = payload[:status])
|
46
|
+
{ status: status.to_i }
|
47
|
+
elsif (error = payload[:exception])
|
48
|
+
exception, message = error
|
49
|
+
{ status: get_error_status_code(exception), error: "#{exception}: #{message}" }
|
50
|
+
else
|
51
|
+
{ status: default_status }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def default_status
|
56
|
+
0
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_error_status_code(exception_class_name)
|
60
|
+
ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def extract_allocations(event)
|
64
|
+
if (allocations = (event.respond_to?(:allocations) && event.allocations))
|
65
|
+
{ allocations: allocations }
|
66
|
+
else
|
67
|
+
{}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def custom_options(event)
|
72
|
+
options = Lograge.custom_options(event) || {}
|
73
|
+
options.merge event.payload[:custom_payload] || {}
|
74
|
+
end
|
75
|
+
|
76
|
+
def before_format(data, payload)
|
77
|
+
Lograge.before_format(data, payload)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/ordered_options'
|
5
|
+
|
6
|
+
module Lograge
|
7
|
+
class OrderedOptions < ActiveSupport::OrderedOptions
|
8
|
+
def custom_payload(&block)
|
9
|
+
self.custom_payload_method = block
|
10
|
+
end
|
11
|
+
end
|
12
|
+
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
@@ -1,13 +1,19 @@
|
|
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'
|
4
6
|
|
5
7
|
module Lograge
|
6
8
|
class Railtie < Rails::Railtie
|
7
|
-
config.lograge =
|
9
|
+
config.lograge = Lograge::OrderedOptions.new
|
8
10
|
config.lograge.enabled = false
|
9
11
|
|
10
|
-
initializer :
|
12
|
+
initializer :deprecator do |app|
|
13
|
+
app.deprecators[:lograge] = Lograge.deprecator if app.respond_to?(:deprecators)
|
14
|
+
end
|
15
|
+
|
16
|
+
config.after_initialize do |app|
|
11
17
|
Lograge.setup(app) if app.config.lograge.enabled
|
12
18
|
end
|
13
19
|
end
|
@@ -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,17 +1,27 @@
|
|
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'
|
5
8
|
require 'lograge/formatters/key_value'
|
9
|
+
require 'lograge/formatters/key_value_deep'
|
6
10
|
require 'lograge/formatters/l2met'
|
7
11
|
require 'lograge/formatters/lines'
|
8
12
|
require 'lograge/formatters/logstash'
|
13
|
+
require 'lograge/formatters/ltsv'
|
9
14
|
require 'lograge/formatters/raw'
|
10
|
-
require 'lograge/
|
15
|
+
require 'lograge/log_subscribers/base'
|
16
|
+
require 'lograge/log_subscribers/action_cable'
|
17
|
+
require 'lograge/log_subscribers/action_controller'
|
18
|
+
require 'lograge/silent_logger'
|
19
|
+
require 'lograge/ordered_options'
|
20
|
+
require 'active_support'
|
11
21
|
require 'active_support/core_ext/module/attribute_accessors'
|
12
22
|
require 'active_support/core_ext/string/inflections'
|
13
|
-
require 'active_support/ordered_options'
|
14
23
|
|
24
|
+
# rubocop:disable Metrics/ModuleLength
|
15
25
|
module Lograge
|
16
26
|
module_function
|
17
27
|
|
@@ -26,7 +36,7 @@ module Lograge
|
|
26
36
|
mattr_writer :custom_options
|
27
37
|
self.custom_options = nil
|
28
38
|
|
29
|
-
def
|
39
|
+
def custom_options(event)
|
30
40
|
if @@custom_options.respond_to?(:call)
|
31
41
|
@@custom_options.call(event)
|
32
42
|
else
|
@@ -40,7 +50,7 @@ module Lograge
|
|
40
50
|
mattr_writer :before_format
|
41
51
|
self.before_format = nil
|
42
52
|
|
43
|
-
def
|
53
|
+
def before_format(data, payload)
|
44
54
|
result = nil
|
45
55
|
result = @@before_format.call(data, payload) if @@before_format
|
46
56
|
result || data
|
@@ -49,7 +59,7 @@ module Lograge
|
|
49
59
|
# Set conditions for events that should be ignored
|
50
60
|
#
|
51
61
|
# Currently supported formats are:
|
52
|
-
# - A single string representing a controller action, e.g. '
|
62
|
+
# - A single string representing a controller action, e.g. 'UsersController#sign_in'
|
53
63
|
# - An array of strings representing controller actions
|
54
64
|
# - An object that responds to call with an event argument and returns
|
55
65
|
# true iff the event should be ignored.
|
@@ -58,18 +68,22 @@ module Lograge
|
|
58
68
|
# are given to 'ignore'. Both methods can be called multiple times, which
|
59
69
|
# just adds more ignore conditions to a list that is checked before logging.
|
60
70
|
|
61
|
-
def
|
71
|
+
def ignore_actions(actions)
|
62
72
|
ignore(lambda do |event|
|
63
|
-
params = event.payload
|
64
|
-
Array(actions).include?("#{params
|
73
|
+
params = event.payload
|
74
|
+
Array(actions).include?("#{controller_field(params)}##{params[:action]}")
|
65
75
|
end)
|
66
76
|
end
|
67
77
|
|
78
|
+
def controller_field(params)
|
79
|
+
params[:controller] || params[:channel_class] || params[:connection_class]
|
80
|
+
end
|
81
|
+
|
68
82
|
def ignore_tests
|
69
83
|
@ignore_tests ||= []
|
70
84
|
end
|
71
85
|
|
72
|
-
def
|
86
|
+
def ignore(test)
|
73
87
|
ignore_tests.push(test) if test
|
74
88
|
end
|
75
89
|
|
@@ -77,7 +91,7 @@ module Lograge
|
|
77
91
|
@ignore_tests = []
|
78
92
|
end
|
79
93
|
|
80
|
-
def
|
94
|
+
def ignore?(event)
|
81
95
|
ignore_tests.any? { |ignore_test| ignore_test.call(event) }
|
82
96
|
end
|
83
97
|
|
@@ -92,7 +106,7 @@ module Lograge
|
|
92
106
|
# - :logstash - JSON formatted as a Logstash Event.
|
93
107
|
mattr_accessor :formatter
|
94
108
|
|
95
|
-
def
|
109
|
+
def remove_existing_log_subscriptions
|
96
110
|
ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
|
97
111
|
case subscriber
|
98
112
|
when ActionView::LogSubscriber
|
@@ -103,38 +117,98 @@ module Lograge
|
|
103
117
|
end
|
104
118
|
end
|
105
119
|
|
106
|
-
def
|
120
|
+
def unsubscribe(component, subscriber)
|
107
121
|
events = subscriber.public_methods(false).reject { |method| method.to_s == 'call' }
|
108
122
|
events.each do |event|
|
109
|
-
|
110
|
-
if listener.instance_variable_get('@delegate') == subscriber
|
111
|
-
ActiveSupport::Notifications.unsubscribe listener
|
112
|
-
end
|
123
|
+
Lograge.notification_listeners_for("#{event}.#{component}").each do |listener|
|
124
|
+
ActiveSupport::Notifications.unsubscribe listener if listener.instance_variable_get('@delegate') == subscriber
|
113
125
|
end
|
114
126
|
end
|
115
127
|
end
|
116
128
|
|
117
|
-
def
|
129
|
+
def setup(app)
|
118
130
|
self.application = app
|
119
|
-
|
131
|
+
disable_rack_cache_verbose_output
|
132
|
+
keep_original_rails_log
|
133
|
+
|
134
|
+
attach_to_action_controller
|
135
|
+
attach_to_action_cable if defined?(ActionCable)
|
136
|
+
|
137
|
+
set_lograge_log_options
|
138
|
+
setup_custom_payload
|
139
|
+
support_deprecated_config # TODO: Remove with version 1.0
|
140
|
+
set_formatter
|
141
|
+
set_ignores
|
142
|
+
end
|
143
|
+
|
144
|
+
def set_ignores
|
145
|
+
Lograge.ignore_actions(lograge_config.ignore_actions)
|
146
|
+
Lograge.ignore(lograge_config.ignore_custom)
|
147
|
+
end
|
120
148
|
|
121
|
-
|
122
|
-
|
123
|
-
|
149
|
+
def set_formatter
|
150
|
+
Lograge.formatter = lograge_config.formatter || Lograge::Formatters::KeyValue.new
|
151
|
+
end
|
152
|
+
|
153
|
+
def attach_to_action_controller
|
154
|
+
Lograge::LogSubscribers::ActionController.attach_to :action_controller
|
155
|
+
end
|
156
|
+
|
157
|
+
def attach_to_action_cable
|
158
|
+
require 'lograge/rails_ext/action_cable/channel/base'
|
159
|
+
require 'lograge/rails_ext/action_cable/connection/base'
|
160
|
+
|
161
|
+
Lograge::LogSubscribers::ActionCable.attach_to :action_cable
|
162
|
+
end
|
163
|
+
|
164
|
+
def setup_custom_payload
|
165
|
+
return unless lograge_config.custom_payload_method.respond_to?(:call)
|
166
|
+
|
167
|
+
base_classes = Array(lograge_config.base_controller_class)
|
168
|
+
base_classes.map! { |klass| klass.try(:constantize) }
|
169
|
+
base_classes << ActionController::Base if base_classes.empty?
|
170
|
+
|
171
|
+
base_classes.each do |base_class|
|
172
|
+
extend_base_class(base_class)
|
124
173
|
end
|
174
|
+
end
|
125
175
|
|
126
|
-
|
176
|
+
def extend_base_class(klass)
|
177
|
+
append_payload_method = klass.instance_method(:append_info_to_payload)
|
178
|
+
custom_payload_method = lograge_config.custom_payload_method
|
127
179
|
|
128
|
-
|
180
|
+
klass.send(:define_method, :append_info_to_payload) do |payload|
|
181
|
+
append_payload_method.bind(self).call(payload)
|
182
|
+
payload[:custom_payload] = custom_payload_method.call(self)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def set_lograge_log_options
|
187
|
+
Lograge.logger = lograge_config.logger
|
129
188
|
Lograge.custom_options = lograge_config.custom_options
|
130
189
|
Lograge.before_format = lograge_config.before_format
|
131
190
|
Lograge.log_level = lograge_config.log_level || :info
|
132
|
-
support_deprecated_config # TODO: Remove with version 1.0
|
133
|
-
Lograge.formatter = lograge_config.formatter || Lograge::Formatters::KeyValue.new
|
134
|
-
Lograge.ignore_actions(lograge_config.ignore_actions)
|
135
|
-
Lograge.ignore(lograge_config.ignore_custom)
|
136
191
|
end
|
137
192
|
|
193
|
+
def disable_rack_cache_verbose_output
|
194
|
+
application.config.action_dispatch.rack_cache[:verbose] = false if rack_cache_hashlike?(application)
|
195
|
+
end
|
196
|
+
|
197
|
+
def keep_original_rails_log
|
198
|
+
return if lograge_config.keep_original_rails_log
|
199
|
+
|
200
|
+
require 'lograge/rails_ext/rack/logger'
|
201
|
+
|
202
|
+
require 'lograge/rails_ext/action_cable/server/base' if defined?(ActionCable)
|
203
|
+
|
204
|
+
Lograge.remove_existing_log_subscriptions
|
205
|
+
end
|
206
|
+
|
207
|
+
def rack_cache_hashlike?(app)
|
208
|
+
app.config.action_dispatch.rack_cache&.respond_to?(:[]=)
|
209
|
+
end
|
210
|
+
private_class_method :rack_cache_hashlike?
|
211
|
+
|
138
212
|
# TODO: Remove with version 1.0
|
139
213
|
|
140
214
|
def support_deprecated_config
|
@@ -142,7 +216,7 @@ module Lograge
|
|
142
216
|
|
143
217
|
legacy_log_format = lograge_config.log_format
|
144
218
|
warning = 'config.lograge.log_format is deprecated. Use config.lograge.formatter instead.'
|
145
|
-
|
219
|
+
deprecator.warn(warning, caller)
|
146
220
|
legacy_log_format = :key_value if legacy_log_format == :lograge
|
147
221
|
lograge_config.formatter = "Lograge::Formatters::#{legacy_log_format.to_s.classify}".constantize.new
|
148
222
|
end
|
@@ -150,6 +224,22 @@ module Lograge
|
|
150
224
|
def lograge_config
|
151
225
|
application.config.lograge
|
152
226
|
end
|
227
|
+
|
228
|
+
def deprecator
|
229
|
+
@deprecator ||= ActiveSupport::Deprecation.new('1.0', 'Lograge')
|
230
|
+
end
|
231
|
+
|
232
|
+
if ::ActiveSupport::VERSION::MAJOR >= 8 ||
|
233
|
+
(::ActiveSupport::VERSION::MAJOR >= 7 && ::ActiveSupport::VERSION::MINOR >= 1)
|
234
|
+
def notification_listeners_for(name)
|
235
|
+
ActiveSupport::Notifications.notifier.all_listeners_for(name)
|
236
|
+
end
|
237
|
+
else
|
238
|
+
def notification_listeners_for(name)
|
239
|
+
ActiveSupport::Notifications.notifier.listeners_for(name)
|
240
|
+
end
|
241
|
+
end
|
153
242
|
end
|
243
|
+
# rubocop:enable Metrics/ModuleLength
|
154
244
|
|
155
245
|
require 'lograge/railtie' if defined?(Rails)
|
metadata
CHANGED
@@ -1,112 +1,155 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lograge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.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: 2023-10-10 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
|
-
name:
|
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
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
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
|
44
59
|
requirement: !ruby/object:Gem::Requirement
|
45
60
|
requirements:
|
46
61
|
- - ">="
|
47
62
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
63
|
+
version: '4'
|
49
64
|
type: :runtime
|
50
65
|
prerelease: false
|
51
66
|
version_requirements: !ruby/object:Gem::Requirement
|
52
67
|
requirements:
|
53
68
|
- - ">="
|
54
69
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
70
|
+
version: '4'
|
56
71
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
72
|
+
name: activesupport
|
58
73
|
requirement: !ruby/object:Gem::Requirement
|
59
74
|
requirements:
|
60
75
|
- - ">="
|
61
76
|
- !ruby/object:Gem::Version
|
62
|
-
version: '
|
77
|
+
version: '4'
|
63
78
|
type: :runtime
|
64
79
|
prerelease: false
|
65
80
|
version_requirements: !ruby/object:Gem::Requirement
|
66
81
|
requirements:
|
67
82
|
- - ">="
|
68
83
|
- !ruby/object:Gem::Version
|
69
|
-
version: '
|
84
|
+
version: '4'
|
70
85
|
- !ruby/object:Gem::Dependency
|
71
86
|
name: railties
|
72
87
|
requirement: !ruby/object:Gem::Requirement
|
73
88
|
requirements:
|
74
89
|
- - ">="
|
75
90
|
- !ruby/object:Gem::Version
|
76
|
-
version: '
|
91
|
+
version: '4'
|
77
92
|
type: :runtime
|
78
93
|
prerelease: false
|
79
94
|
version_requirements: !ruby/object:Gem::Requirement
|
80
95
|
requirements:
|
81
96
|
- - ">="
|
82
97
|
- !ruby/object:Gem::Version
|
83
|
-
version: '
|
98
|
+
version: '4'
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: request_store
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - "~>"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '1.0'
|
106
|
+
type: :runtime
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '1.0'
|
84
113
|
description: Tame Rails' multi-line logging into a single line per request
|
85
114
|
email:
|
86
115
|
- meyer@paperplanes.de
|
87
116
|
- benjamin.lovell@gmail.com
|
117
|
+
- mike@mikebian.co
|
88
118
|
executables: []
|
89
119
|
extensions: []
|
90
120
|
extra_rdoc_files: []
|
91
121
|
files:
|
122
|
+
- LICENSE.txt
|
92
123
|
- lib/lograge.rb
|
93
124
|
- lib/lograge/formatters/cee.rb
|
94
125
|
- lib/lograge/formatters/graylog2.rb
|
126
|
+
- lib/lograge/formatters/helpers/method_and_path.rb
|
95
127
|
- lib/lograge/formatters/json.rb
|
96
128
|
- lib/lograge/formatters/key_value.rb
|
129
|
+
- lib/lograge/formatters/key_value_deep.rb
|
97
130
|
- lib/lograge/formatters/l2met.rb
|
98
131
|
- lib/lograge/formatters/lines.rb
|
99
132
|
- lib/lograge/formatters/logstash.rb
|
133
|
+
- lib/lograge/formatters/ltsv.rb
|
100
134
|
- lib/lograge/formatters/raw.rb
|
101
|
-
- lib/lograge/
|
135
|
+
- lib/lograge/log_subscribers/action_cable.rb
|
136
|
+
- lib/lograge/log_subscribers/action_controller.rb
|
137
|
+
- lib/lograge/log_subscribers/base.rb
|
138
|
+
- lib/lograge/ordered_options.rb
|
139
|
+
- lib/lograge/rails_ext/action_cable/channel/base.rb
|
140
|
+
- lib/lograge/rails_ext/action_cable/connection/base.rb
|
141
|
+
- lib/lograge/rails_ext/action_cable/server/base.rb
|
102
142
|
- lib/lograge/rails_ext/rack/logger.rb
|
103
143
|
- lib/lograge/railtie.rb
|
144
|
+
- lib/lograge/silent_logger.rb
|
104
145
|
- lib/lograge/version.rb
|
105
146
|
homepage: https://github.com/roidrage/lograge
|
106
147
|
licenses:
|
107
148
|
- MIT
|
108
|
-
metadata:
|
109
|
-
|
149
|
+
metadata:
|
150
|
+
rubygems_mfa_required: 'true'
|
151
|
+
changelog_uri: https://github.com/roidrage/lograge/blob/master/CHANGELOG.md
|
152
|
+
post_install_message:
|
110
153
|
rdoc_options: []
|
111
154
|
require_paths:
|
112
155
|
- lib
|
@@ -114,16 +157,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
157
|
requirements:
|
115
158
|
- - ">="
|
116
159
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
160
|
+
version: '2.5'
|
118
161
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
162
|
requirements:
|
120
163
|
- - ">="
|
121
164
|
- !ruby/object:Gem::Version
|
122
165
|
version: '0'
|
123
166
|
requirements: []
|
124
|
-
|
125
|
-
|
126
|
-
signing_key:
|
167
|
+
rubygems_version: 3.4.10
|
168
|
+
signing_key:
|
127
169
|
specification_version: 4
|
128
170
|
summary: Tame Rails' multi-line logging into a single line per request
|
129
171
|
test_files: []
|
@@ -1,96 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
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
|
-
|
13
|
-
data = extract_request(payload)
|
14
|
-
extract_status(data, payload)
|
15
|
-
runtimes(data, event)
|
16
|
-
location(data)
|
17
|
-
custom_options(data, event)
|
18
|
-
|
19
|
-
data = before_format(data, payload)
|
20
|
-
formatted_message = Lograge.formatter.call(data)
|
21
|
-
logger.send(Lograge.log_level, formatted_message)
|
22
|
-
end
|
23
|
-
|
24
|
-
def redirect_to(event)
|
25
|
-
Thread.current[:lograge_location] = event.payload[:location]
|
26
|
-
end
|
27
|
-
|
28
|
-
def logger
|
29
|
-
Lograge.logger.presence || super
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def extract_request(payload)
|
35
|
-
{
|
36
|
-
method: payload[:method],
|
37
|
-
path: extract_path(payload),
|
38
|
-
format: extract_format(payload),
|
39
|
-
controller: payload[:params]['controller'],
|
40
|
-
action: payload[:params]['action']
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
def extract_path(payload)
|
45
|
-
path = payload[:path]
|
46
|
-
index = path.index('?')
|
47
|
-
index ? path[0, index] : path
|
48
|
-
end
|
49
|
-
|
50
|
-
if ::ActionPack::VERSION::MAJOR == 3 && ::ActionPack::VERSION::MINOR == 0
|
51
|
-
def extract_format(payload)
|
52
|
-
payload[:formats].first
|
53
|
-
end
|
54
|
-
else
|
55
|
-
def extract_format(payload)
|
56
|
-
payload[:format]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def extract_status(data, payload)
|
61
|
-
if (status = payload[:status])
|
62
|
-
data[:status] = status.to_i
|
63
|
-
elsif (error = payload[:exception])
|
64
|
-
exception, message = error
|
65
|
-
data[:status] = 500
|
66
|
-
data[:error] = "#{exception}:#{message}"
|
67
|
-
else
|
68
|
-
data[:status] = 0
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def custom_options(data, event)
|
73
|
-
options = Lograge.custom_options(event)
|
74
|
-
data.merge! options if options
|
75
|
-
end
|
76
|
-
|
77
|
-
def before_format(data, payload)
|
78
|
-
Lograge.before_format(data, payload)
|
79
|
-
end
|
80
|
-
|
81
|
-
def runtimes(data, event)
|
82
|
-
payload = event.payload
|
83
|
-
data[:duration] = event.duration.to_f.round(2)
|
84
|
-
data[:view] = payload[:view_runtime].to_f.round(2) if payload.key?(:view_runtime)
|
85
|
-
data[:db] = payload[:db_runtime].to_f.round(2) if payload.key?(:db_runtime)
|
86
|
-
end
|
87
|
-
|
88
|
-
def location(data)
|
89
|
-
location = Thread.current[:lograge_location]
|
90
|
-
return unless location
|
91
|
-
|
92
|
-
Thread.current[:lograge_location] = nil
|
93
|
-
data[:location] = location
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|