super-pure-pkg 0.0.1
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 +7 -0
- data/lograge-0.14.0/LICENSE.txt +21 -0
- data/lograge-0.14.0/lib/lograge/formatters/cee.rb +11 -0
- data/lograge-0.14.0/lib/lograge/formatters/graylog2.rb +24 -0
- data/lograge-0.14.0/lib/lograge/formatters/helpers/method_and_path.rb +14 -0
- data/lograge-0.14.0/lib/lograge/formatters/json.rb +12 -0
- data/lograge-0.14.0/lib/lograge/formatters/key_value.rb +33 -0
- data/lograge-0.14.0/lib/lograge/formatters/key_value_deep.rb +42 -0
- data/lograge-0.14.0/lib/lograge/formatters/l2met.rb +57 -0
- data/lograge-0.14.0/lib/lograge/formatters/lines.rb +20 -0
- data/lograge-0.14.0/lib/lograge/formatters/logstash.rb +24 -0
- data/lograge-0.14.0/lib/lograge/formatters/ltsv.rb +44 -0
- data/lograge-0.14.0/lib/lograge/formatters/raw.rb +11 -0
- data/lograge-0.14.0/lib/lograge/log_subscribers/action_cable.rb +34 -0
- data/lograge-0.14.0/lib/lograge/log_subscribers/action_controller.rb +75 -0
- data/lograge-0.14.0/lib/lograge/log_subscribers/base.rb +81 -0
- data/lograge-0.14.0/lib/lograge/ordered_options.rb +12 -0
- data/lograge-0.14.0/lib/lograge/rails_ext/action_cable/channel/base.rb +25 -0
- data/lograge-0.14.0/lib/lograge/rails_ext/action_cable/connection/base.rb +21 -0
- data/lograge-0.14.0/lib/lograge/rails_ext/action_cable/server/base.rb +10 -0
- data/lograge-0.14.0/lib/lograge/rails_ext/rack/logger.rb +30 -0
- data/lograge-0.14.0/lib/lograge/railtie.rb +20 -0
- data/lograge-0.14.0/lib/lograge/silent_logger.rb +13 -0
- data/lograge-0.14.0/lib/lograge/version.rb +5 -0
- data/lograge-0.14.0/lib/lograge.rb +245 -0
- data/super-pure-pkg.gemspec +12 -0
- metadata +66 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 384fa284408b5105c65bfbc1e371040eddcffa16afb88bfb2f16cd2311f9ba3d
|
|
4
|
+
data.tar.gz: 54b232e0493e0142a1054ced155c9d94f94e1d36822af1a7be2d597e23ae8857
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2a3a79bf422d4d069d68f427c12697c9763cf206c6559e5272d5119e9a7750f14550adb142a4ce2a4f132591ba67b79d851dd974ff2615c727f9b3dab3fc7218
|
|
7
|
+
data.tar.gz: 42db663616cb18ec8b6e750acf83e1c4dc6e1c91fdea7aac9b8c926afd602b65ff9dd55b37ab3e6bd15dc4a6f8b647822d51e18c1d52aa20f54fb4486605f7b7
|
|
@@ -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.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lograge
|
|
4
|
+
module Formatters
|
|
5
|
+
class Graylog2
|
|
6
|
+
include Lograge::Formatters::Helpers::MethodAndPath
|
|
7
|
+
|
|
8
|
+
def call(data)
|
|
9
|
+
# Add underscore to every key to follow GELF additional field syntax.
|
|
10
|
+
data.transform_keys { |k| underscore_prefix(k) }.merge(
|
|
11
|
+
short_message: short_message(data)
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def underscore_prefix(key)
|
|
16
|
+
"_#{key}".to_sym
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def short_message(data)
|
|
20
|
+
"[#{data[:status]}]#{method_and_path_string(data)}(#{data[:controller]}##{data[:action]})"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
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
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lograge
|
|
4
|
+
module Formatters
|
|
5
|
+
class KeyValue
|
|
6
|
+
def call(data)
|
|
7
|
+
fields_to_display(data)
|
|
8
|
+
.map { |key| format(key, data[key]) }
|
|
9
|
+
.join(' ')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
def fields_to_display(data)
|
|
15
|
+
data.keys
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def format(key, value)
|
|
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
|
|
28
|
+
|
|
29
|
+
value
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
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
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'lograge/formatters/key_value'
|
|
4
|
+
|
|
5
|
+
module Lograge
|
|
6
|
+
module Formatters
|
|
7
|
+
class L2met < KeyValue
|
|
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
|
|
25
|
+
|
|
26
|
+
def call(data)
|
|
27
|
+
super(modify_payload(data))
|
|
28
|
+
end
|
|
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
|
+
|
|
40
|
+
def format(key, value)
|
|
41
|
+
key = "measure#page.#{key}" if value.is_a?(Float)
|
|
42
|
+
|
|
43
|
+
super(key, value)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def modify_payload(data)
|
|
47
|
+
data[:source] = source_field(data) if data[:controller] && data[:action]
|
|
48
|
+
|
|
49
|
+
data
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def source_field(data)
|
|
53
|
+
"#{data[:controller].to_s.tr('/', '-')}:#{data[:action]}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lograge
|
|
4
|
+
module Formatters
|
|
5
|
+
class Lines
|
|
6
|
+
def call(data)
|
|
7
|
+
load_dependencies
|
|
8
|
+
|
|
9
|
+
::Lines.dump(data)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def load_dependencies
|
|
13
|
+
require 'lines'
|
|
14
|
+
rescue LoadError
|
|
15
|
+
puts 'You need to install the lines gem to use this output.'
|
|
16
|
+
raise
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lograge
|
|
4
|
+
module Formatters
|
|
5
|
+
class Logstash
|
|
6
|
+
include Lograge::Formatters::Helpers::MethodAndPath
|
|
7
|
+
|
|
8
|
+
def call(data)
|
|
9
|
+
load_dependencies
|
|
10
|
+
event = LogStash::Event.new(data)
|
|
11
|
+
|
|
12
|
+
event['message'] = "[#{data[:status]}]#{method_and_path_string(data)}(#{data[:controller]}##{data[:action]})"
|
|
13
|
+
event.to_json
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def load_dependencies
|
|
17
|
+
require 'logstash-event'
|
|
18
|
+
rescue LoadError
|
|
19
|
+
puts 'You need to install the logstash-event gem to use the logstash output.'
|
|
20
|
+
raise
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -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)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support'
|
|
4
|
+
require 'active_support/concern'
|
|
5
|
+
require 'rails/rack/logger'
|
|
6
|
+
|
|
7
|
+
module Rails
|
|
8
|
+
module Rack
|
|
9
|
+
# Overwrites defaults of Rails::Rack::Logger that cause
|
|
10
|
+
# unnecessary logging.
|
|
11
|
+
# This effectively removes the log lines from the log
|
|
12
|
+
# that say:
|
|
13
|
+
# Started GET / for 192.168.2.1...
|
|
14
|
+
class Logger
|
|
15
|
+
# Overwrites Rails code that logs new requests
|
|
16
|
+
def call_app(*args)
|
|
17
|
+
env = args.last
|
|
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
|
|
22
|
+
ensure
|
|
23
|
+
ActiveSupport::LogSubscriber.flush_all!
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Overwrites Rails 3.0/3.1 code that logs new requests
|
|
27
|
+
def before_dispatch(_env); end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/railtie'
|
|
4
|
+
require 'action_view/log_subscriber'
|
|
5
|
+
require 'action_controller/log_subscriber'
|
|
6
|
+
|
|
7
|
+
module Lograge
|
|
8
|
+
class Railtie < Rails::Railtie
|
|
9
|
+
config.lograge = Lograge::OrderedOptions.new
|
|
10
|
+
config.lograge.enabled = false
|
|
11
|
+
|
|
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|
|
|
17
|
+
Lograge.setup(app) if app.config.lograge.enabled
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
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
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'lograge/version'
|
|
4
|
+
require 'lograge/formatters/helpers/method_and_path'
|
|
5
|
+
require 'lograge/formatters/cee'
|
|
6
|
+
require 'lograge/formatters/json'
|
|
7
|
+
require 'lograge/formatters/graylog2'
|
|
8
|
+
require 'lograge/formatters/key_value'
|
|
9
|
+
require 'lograge/formatters/key_value_deep'
|
|
10
|
+
require 'lograge/formatters/l2met'
|
|
11
|
+
require 'lograge/formatters/lines'
|
|
12
|
+
require 'lograge/formatters/logstash'
|
|
13
|
+
require 'lograge/formatters/ltsv'
|
|
14
|
+
require 'lograge/formatters/raw'
|
|
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'
|
|
21
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
|
22
|
+
require 'active_support/core_ext/string/inflections'
|
|
23
|
+
|
|
24
|
+
# rubocop:disable Metrics/ModuleLength
|
|
25
|
+
module Lograge
|
|
26
|
+
module_function
|
|
27
|
+
|
|
28
|
+
mattr_accessor :logger, :application, :ignore_tests
|
|
29
|
+
|
|
30
|
+
# Custom options that will be appended to log line
|
|
31
|
+
#
|
|
32
|
+
# Currently supported formats are:
|
|
33
|
+
# - Hash
|
|
34
|
+
# - Any object that responds to call and returns a hash
|
|
35
|
+
#
|
|
36
|
+
mattr_writer :custom_options
|
|
37
|
+
self.custom_options = nil
|
|
38
|
+
|
|
39
|
+
def custom_options(event)
|
|
40
|
+
if @@custom_options.respond_to?(:call)
|
|
41
|
+
@@custom_options.call(event)
|
|
42
|
+
else
|
|
43
|
+
@@custom_options
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Before format allows you to change the structure of the output.
|
|
48
|
+
# You've to pass in something callable
|
|
49
|
+
#
|
|
50
|
+
mattr_writer :before_format
|
|
51
|
+
self.before_format = nil
|
|
52
|
+
|
|
53
|
+
def before_format(data, payload)
|
|
54
|
+
result = nil
|
|
55
|
+
result = @@before_format.call(data, payload) if @@before_format
|
|
56
|
+
result || data
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Set conditions for events that should be ignored
|
|
60
|
+
#
|
|
61
|
+
# Currently supported formats are:
|
|
62
|
+
# - A single string representing a controller action, e.g. 'UsersController#sign_in'
|
|
63
|
+
# - An array of strings representing controller actions
|
|
64
|
+
# - An object that responds to call with an event argument and returns
|
|
65
|
+
# true iff the event should be ignored.
|
|
66
|
+
#
|
|
67
|
+
# The action ignores are given to 'ignore_actions'. The callable ignores
|
|
68
|
+
# are given to 'ignore'. Both methods can be called multiple times, which
|
|
69
|
+
# just adds more ignore conditions to a list that is checked before logging.
|
|
70
|
+
|
|
71
|
+
def ignore_actions(actions)
|
|
72
|
+
ignore(lambda do |event|
|
|
73
|
+
params = event.payload
|
|
74
|
+
Array(actions).include?("#{controller_field(params)}##{params[:action]}")
|
|
75
|
+
end)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def controller_field(params)
|
|
79
|
+
params[:controller] || params[:channel_class] || params[:connection_class]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def ignore_tests
|
|
83
|
+
@ignore_tests ||= []
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def ignore(test)
|
|
87
|
+
ignore_tests.push(test) if test
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def ignore_nothing
|
|
91
|
+
@ignore_tests = []
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def ignore?(event)
|
|
95
|
+
ignore_tests.any? { |ignore_test| ignore_test.call(event) }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Loglines are emitted with this log level
|
|
99
|
+
mattr_accessor :log_level
|
|
100
|
+
self.log_level = :info
|
|
101
|
+
|
|
102
|
+
# The emitted log format
|
|
103
|
+
#
|
|
104
|
+
# Currently supported formats are>
|
|
105
|
+
# - :lograge - The custom tense lograge format
|
|
106
|
+
# - :logstash - JSON formatted as a Logstash Event.
|
|
107
|
+
mattr_accessor :formatter
|
|
108
|
+
|
|
109
|
+
def remove_existing_log_subscriptions
|
|
110
|
+
ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
|
|
111
|
+
case subscriber
|
|
112
|
+
when ActionView::LogSubscriber
|
|
113
|
+
unsubscribe(:action_view, subscriber)
|
|
114
|
+
when ActionController::LogSubscriber
|
|
115
|
+
unsubscribe(:action_controller, subscriber)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def unsubscribe(component, subscriber)
|
|
121
|
+
events = subscriber.public_methods(false).reject { |method| method.to_s == 'call' }
|
|
122
|
+
events.each do |event|
|
|
123
|
+
Lograge.notification_listeners_for("#{event}.#{component}").each do |listener|
|
|
124
|
+
ActiveSupport::Notifications.unsubscribe listener if listener.instance_variable_get('@delegate') == subscriber
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def setup(app)
|
|
130
|
+
self.application = app
|
|
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
|
|
148
|
+
|
|
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)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
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
|
|
179
|
+
|
|
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
|
|
188
|
+
Lograge.custom_options = lograge_config.custom_options
|
|
189
|
+
Lograge.before_format = lograge_config.before_format
|
|
190
|
+
Lograge.log_level = lograge_config.log_level || :info
|
|
191
|
+
end
|
|
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
|
+
|
|
212
|
+
# TODO: Remove with version 1.0
|
|
213
|
+
|
|
214
|
+
def support_deprecated_config
|
|
215
|
+
return unless lograge_config.log_format
|
|
216
|
+
|
|
217
|
+
legacy_log_format = lograge_config.log_format
|
|
218
|
+
warning = 'config.lograge.log_format is deprecated. Use config.lograge.formatter instead.'
|
|
219
|
+
deprecator.warn(warning, caller)
|
|
220
|
+
legacy_log_format = :key_value if legacy_log_format == :lograge
|
|
221
|
+
lograge_config.formatter = "Lograge::Formatters::#{legacy_log_format.to_s.classify}".constantize.new
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def lograge_config
|
|
225
|
+
application.config.lograge
|
|
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
|
|
242
|
+
end
|
|
243
|
+
# rubocop:enable Metrics/ModuleLength
|
|
244
|
+
|
|
245
|
+
require 'lograge/railtie' if defined?(Rails)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = "super-pure-pkg"
|
|
3
|
+
s.version = "0.0.1"
|
|
4
|
+
s.summary = "Research test"
|
|
5
|
+
s.description = "University research based on lograge"
|
|
6
|
+
s.authors = ["Andrey78"]
|
|
7
|
+
s.email = ["cakoc614@gmail.com"]
|
|
8
|
+
s.files = Dir.glob("**/*").reject { |f| f.end_with?('.gem') }
|
|
9
|
+
s.homepage = "https://rubygems.org/profiles/Andrey78"
|
|
10
|
+
s.license = "MIT"
|
|
11
|
+
s.metadata = { "source_code_uri" => "https://github.com/Andrey78/super-pure-pkg" }
|
|
12
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: super-pure-pkg
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Andrey78
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-07-06 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: University research based on lograge
|
|
13
|
+
email:
|
|
14
|
+
- cakoc614@gmail.com
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- lograge-0.14.0/LICENSE.txt
|
|
20
|
+
- lograge-0.14.0/lib/lograge.rb
|
|
21
|
+
- lograge-0.14.0/lib/lograge/formatters/cee.rb
|
|
22
|
+
- lograge-0.14.0/lib/lograge/formatters/graylog2.rb
|
|
23
|
+
- lograge-0.14.0/lib/lograge/formatters/helpers/method_and_path.rb
|
|
24
|
+
- lograge-0.14.0/lib/lograge/formatters/json.rb
|
|
25
|
+
- lograge-0.14.0/lib/lograge/formatters/key_value.rb
|
|
26
|
+
- lograge-0.14.0/lib/lograge/formatters/key_value_deep.rb
|
|
27
|
+
- lograge-0.14.0/lib/lograge/formatters/l2met.rb
|
|
28
|
+
- lograge-0.14.0/lib/lograge/formatters/lines.rb
|
|
29
|
+
- lograge-0.14.0/lib/lograge/formatters/logstash.rb
|
|
30
|
+
- lograge-0.14.0/lib/lograge/formatters/ltsv.rb
|
|
31
|
+
- lograge-0.14.0/lib/lograge/formatters/raw.rb
|
|
32
|
+
- lograge-0.14.0/lib/lograge/log_subscribers/action_cable.rb
|
|
33
|
+
- lograge-0.14.0/lib/lograge/log_subscribers/action_controller.rb
|
|
34
|
+
- lograge-0.14.0/lib/lograge/log_subscribers/base.rb
|
|
35
|
+
- lograge-0.14.0/lib/lograge/ordered_options.rb
|
|
36
|
+
- lograge-0.14.0/lib/lograge/rails_ext/action_cable/channel/base.rb
|
|
37
|
+
- lograge-0.14.0/lib/lograge/rails_ext/action_cable/connection/base.rb
|
|
38
|
+
- lograge-0.14.0/lib/lograge/rails_ext/action_cable/server/base.rb
|
|
39
|
+
- lograge-0.14.0/lib/lograge/rails_ext/rack/logger.rb
|
|
40
|
+
- lograge-0.14.0/lib/lograge/railtie.rb
|
|
41
|
+
- lograge-0.14.0/lib/lograge/silent_logger.rb
|
|
42
|
+
- lograge-0.14.0/lib/lograge/version.rb
|
|
43
|
+
- super-pure-pkg.gemspec
|
|
44
|
+
homepage: https://rubygems.org/profiles/Andrey78
|
|
45
|
+
licenses:
|
|
46
|
+
- MIT
|
|
47
|
+
metadata:
|
|
48
|
+
source_code_uri: https://github.com/Andrey78/super-pure-pkg
|
|
49
|
+
rdoc_options: []
|
|
50
|
+
require_paths:
|
|
51
|
+
- lib
|
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - ">="
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '0'
|
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
requirements: []
|
|
63
|
+
rubygems_version: 3.6.2
|
|
64
|
+
specification_version: 4
|
|
65
|
+
summary: Research test
|
|
66
|
+
test_files: []
|