logstasher 2.0.1 → 2.1.3
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 +4 -4
- data/lib/logstasher.rb +12 -7
- data/lib/logstasher/action_view/log_subscriber.rb +3 -1
- data/lib/logstasher/active_job/log_subscriber.rb +92 -85
- data/lib/logstasher/active_record/log_subscriber.rb +9 -3
- data/lib/logstasher/active_support/log_subscriber.rb +12 -10
- data/lib/logstasher/active_support/mailer_log_subscriber.rb +8 -1
- data/lib/logstasher/custom_fields.rb +2 -0
- data/lib/logstasher/device/redis.rb +3 -1
- data/lib/logstasher/event.rb +2 -0
- data/lib/logstasher/rails_ext/action_controller/base.rb +2 -0
- data/lib/logstasher/rails_ext/action_controller/metal/instrumentation.rb +2 -0
- data/lib/logstasher/rails_ext/rack/logger.rb +2 -0
- data/lib/logstasher/railtie.rb +5 -3
- data/lib/logstasher/version.rb +3 -1
- metadata +7 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59cdc11b4f36e90443fcc8ea7332552874da2ad2205f38e4efac48c8e4dda63a
|
4
|
+
data.tar.gz: 997cb22cb6799f67d28562e986e326fa23597ee5168a635bdc917d6a9bb65c6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd6d94a4055566fd119a570107724ce1fc1c1f3f1781f2929c248e4f2b227a3f95adb010b6e059f44cf49991f5baa1d9f3271f272efb5a97415104a265eb0e1b
|
7
|
+
data.tar.gz: 35d3e80b5e460753033b327e41d51149d24b20c7b1321189a2ec24373ac5aa9c713189eba701ddc3ec5904fbf86a2b98657deff4c2a02fcfcee20f93c31fd9f9
|
data/lib/logstasher.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'logstasher/version'
|
2
4
|
require 'logstasher/active_support/log_subscriber'
|
3
5
|
require 'logstasher/active_support/mailer_log_subscriber'
|
@@ -18,7 +20,7 @@ module LogStasher
|
|
18
20
|
REQUEST_CONTEXT_KEY = :logstasher_request_context
|
19
21
|
|
20
22
|
attr_accessor :logger, :logger_path, :enabled, :log_controller_parameters, :source, :backtrace,
|
21
|
-
:controller_monkey_patch, :field_renaming
|
23
|
+
:controller_monkey_patch, :field_renaming, :backtrace_filter
|
22
24
|
|
23
25
|
# Setting the default to 'unknown' to define the default behaviour
|
24
26
|
@source = 'unknown'
|
@@ -36,7 +38,9 @@ module LogStasher
|
|
36
38
|
unsubscribe(:action_mailer, subscriber)
|
37
39
|
when 'ActiveRecord::LogSubscriber'
|
38
40
|
unsubscribe(:active_record, subscriber)
|
39
|
-
when 'ActiveJob::
|
41
|
+
when 'ActiveJob::LogSubscriber' # For Rails 6
|
42
|
+
unsubscribe(:active_job, subscriber)
|
43
|
+
when 'ActiveJob::Logging::LogSubscriber' # For Rails 5
|
40
44
|
unsubscribe(:active_job, subscriber)
|
41
45
|
end
|
42
46
|
end
|
@@ -107,8 +111,9 @@ module LogStasher
|
|
107
111
|
self.logger = config.logger || new_logger(logger_path)
|
108
112
|
logger.level = config.log_level || Logger::WARN
|
109
113
|
self.source = config.source unless config.source.nil?
|
110
|
-
self.log_controller_parameters =
|
111
|
-
self.backtrace =
|
114
|
+
self.log_controller_parameters = !config.log_controller_parameters.nil?
|
115
|
+
self.backtrace = !config.backtrace.nil? unless config.backtrace.nil?
|
116
|
+
self.backtrace_filter = config.backtrace_filter
|
112
117
|
set_data_for_rake
|
113
118
|
set_data_for_console
|
114
119
|
self.field_renaming = Hash(config.field_renaming)
|
@@ -123,7 +128,7 @@ module LogStasher
|
|
123
128
|
end
|
124
129
|
|
125
130
|
def called_as_rake?
|
126
|
-
File.basename($
|
131
|
+
File.basename($PROGRAM_NAME) == 'rake'
|
127
132
|
end
|
128
133
|
|
129
134
|
def called_as_console?
|
@@ -158,7 +163,7 @@ module LogStasher
|
|
158
163
|
# LogStasher.info("message", timing:1234)
|
159
164
|
# LogStasher.info(custom1:"yes", custom2:"no")
|
160
165
|
def log(severity, message, additional_fields = {})
|
161
|
-
if logger
|
166
|
+
if logger&.send("#{severity}?")
|
162
167
|
|
163
168
|
data = { 'level' => severity }
|
164
169
|
if message.respond_to?(:to_hash)
|
@@ -171,7 +176,7 @@ module LogStasher
|
|
171
176
|
tags = Array(additional_fields.delete(:tags) || 'log')
|
172
177
|
|
173
178
|
data.merge!(additional_fields)
|
174
|
-
logger << build_logstash_event(data, tags).to_json
|
179
|
+
logger << "#{build_logstash_event(data, tags).to_json}\n"
|
175
180
|
|
176
181
|
end
|
177
182
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/notifications'
|
2
4
|
require 'action_view/log_subscriber'
|
3
5
|
require 'logstasher/custom_fields'
|
@@ -31,7 +33,7 @@ module LogStasher
|
|
31
33
|
|
32
34
|
tags = []
|
33
35
|
tags.push('exception') if data[:exception]
|
34
|
-
logger << LogStasher.build_logstash_event(data, tags).to_json
|
36
|
+
logger << "#{LogStasher.build_logstash_event(data, tags).to_json}\n"
|
35
37
|
end
|
36
38
|
|
37
39
|
def extract_data(data)
|
@@ -1,91 +1,98 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# For Rails 6.0 or below, require the logging module which contains LogSubscriber
|
4
|
+
if ActiveJob::VERSION::MAJOR < 6 || (ActiveJob::VERSION::MAJOR == 6 && ActiveJob::VERSION::MINOR.zero?)
|
3
5
|
require 'active_job/logging'
|
4
|
-
|
6
|
+
else
|
7
|
+
require 'active_job/log_subscriber'
|
5
8
|
end
|
6
9
|
|
7
|
-
|
8
|
-
module
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
10
|
+
module LogStasher
|
11
|
+
module ActiveJob
|
12
|
+
BASE_SUBSCRIBER = if defined?(::ActiveJob::LogSubscriber)
|
13
|
+
::ActiveJob::LogSubscriber
|
14
|
+
else
|
15
|
+
::ActiveJob::Logging::LogSubscriber
|
16
|
+
end
|
17
|
+
|
18
|
+
class LogSubscriber < BASE_SUBSCRIBER
|
19
|
+
def enqueue(event)
|
20
|
+
process_event(event, 'enqueue')
|
21
|
+
end
|
22
|
+
|
23
|
+
def enqueue_at(event)
|
24
|
+
process_event(event, 'enqueue_at')
|
25
|
+
end
|
26
|
+
|
27
|
+
def perform(event)
|
28
|
+
process_event(event, 'perform')
|
29
|
+
|
30
|
+
# Revert the request id back, in the event that the inline adapter is being used or a
|
31
|
+
# perform_now was used.
|
32
|
+
LogStasher.request_context[:request_id] = Thread.current[:old_request_id]
|
33
|
+
Thread.current[:old_request_id] = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def perform_start(event)
|
37
|
+
# Use the job_id as the request id, so that any custom logging done for a job
|
38
|
+
# shares a request id, and has the job id in each log line.
|
39
|
+
#
|
40
|
+
# It's not being set when the job is enqueued, so enqueuing a job will have it's default
|
41
|
+
# request_id. In a lot of cases, it will be because of a web request.
|
42
|
+
#
|
43
|
+
# Hang onto the old request id, so we can revert after the job is done being performed.
|
44
|
+
Thread.current[:old_request_id] = LogStasher.request_context[:request_id]
|
45
|
+
LogStasher.request_context[:request_id] = event.payload[:job].job_id
|
46
|
+
|
47
|
+
process_event(event, 'perform_start')
|
48
|
+
end
|
49
|
+
|
50
|
+
def logger
|
51
|
+
LogStasher.logger
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def process_event(event, type)
|
57
|
+
data = extract_metadata(event)
|
58
|
+
data.merge! extract_exception(event)
|
59
|
+
data.merge! extract_scheduled_at(event) if type == 'enqueue_at'
|
60
|
+
data.merge! extract_duration(event) if type == 'perform'
|
61
|
+
data.merge! request_context
|
62
|
+
|
63
|
+
tags = ['job', type]
|
64
|
+
tags.push('exception') if data[:exception]
|
65
|
+
logger << "#{LogStasher.build_logstash_event(data, tags).to_json}\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
def extract_metadata(event)
|
69
|
+
{
|
70
|
+
job_id: event.payload[:job].job_id,
|
71
|
+
queue_name: queue_name(event),
|
72
|
+
job_class: event.payload[:job].class.to_s,
|
73
|
+
job_args: args_info(event.payload[:job])
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def extract_duration(event)
|
78
|
+
{ duration: event.duration.to_f.round(2) }
|
79
|
+
end
|
80
|
+
|
81
|
+
def extract_exception(event)
|
82
|
+
event.payload.slice(:exception)
|
83
|
+
end
|
84
|
+
|
85
|
+
def extract_scheduled_at(event)
|
86
|
+
{ scheduled_at: scheduled_at(event) }
|
87
|
+
end
|
88
|
+
|
89
|
+
def request_context
|
90
|
+
LogStasher.request_context
|
91
|
+
end
|
92
|
+
|
93
|
+
# The default args_info makes a string. We need objects to turn into JSON.
|
94
|
+
def args_info(job)
|
95
|
+
::ActiveJob::Arguments.serialize(job.arguments)
|
89
96
|
end
|
90
97
|
end
|
91
98
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/notifications'
|
2
4
|
require 'active_record/log_subscriber'
|
3
5
|
require 'logstasher/custom_fields'
|
@@ -9,7 +11,7 @@ module LogStasher
|
|
9
11
|
|
10
12
|
def identity(event)
|
11
13
|
lsevent = logstash_event(event)
|
12
|
-
logger << lsevent.to_json
|
14
|
+
logger << "#{lsevent.to_json}\n" if logger && lsevent
|
13
15
|
end
|
14
16
|
alias sql identity
|
15
17
|
|
@@ -21,9 +23,13 @@ module LogStasher
|
|
21
23
|
|
22
24
|
def logstash_event(event)
|
23
25
|
self.class.runtime += event.duration
|
24
|
-
data = event.payload
|
26
|
+
data = event.payload.dup
|
27
|
+
|
28
|
+
return if data[:name] == 'SCHEMA'
|
25
29
|
|
26
|
-
|
30
|
+
# A connection cannot be converted to JSON as it fails with
|
31
|
+
# SystemStackError when running against ActiveSupport JSON patches.
|
32
|
+
data.delete(:connection)
|
27
33
|
|
28
34
|
data.merge! runtimes(event)
|
29
35
|
data.merge! extract_sql(data)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/core_ext/class/attribute'
|
2
4
|
require 'active_support/log_subscriber'
|
3
5
|
require 'logstasher/custom_fields'
|
@@ -20,7 +22,7 @@ module LogStasher
|
|
20
22
|
|
21
23
|
tags = ['request']
|
22
24
|
tags.push('exception') if payload[:exception]
|
23
|
-
logger << LogStasher.build_logstash_event(data, tags).to_json
|
25
|
+
logger << "#{LogStasher.build_logstash_event(data, tags).to_json}\n"
|
24
26
|
end
|
25
27
|
|
26
28
|
def redirect_to(event)
|
@@ -48,11 +50,7 @@ module LogStasher
|
|
48
50
|
end
|
49
51
|
|
50
52
|
def extract_format(payload)
|
51
|
-
|
52
|
-
payload[:formats].first
|
53
|
-
else
|
54
|
-
payload[:format]
|
55
|
-
end
|
53
|
+
payload[:format]
|
56
54
|
end
|
57
55
|
|
58
56
|
def extract_status(payload)
|
@@ -88,10 +86,14 @@ module LogStasher
|
|
88
86
|
exception, message = payload[:exception]
|
89
87
|
status = ::ActionDispatch::ExceptionWrapper.status_code_for_exception(exception)
|
90
88
|
backtrace = if LogStasher.backtrace
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
if LogStasher.backtrace_filter.respond_to?(:call)
|
90
|
+
LogStasher.backtrace_filter.call($!.backtrace).join("\n")
|
91
|
+
else
|
92
|
+
$!.backtrace.join("\n")
|
93
|
+
end
|
94
|
+
else
|
95
|
+
$!.backtrace.first
|
96
|
+
end
|
95
97
|
message = "#{exception}\n#{message}\n#{backtrace}"
|
96
98
|
{ status: status, error: message }
|
97
99
|
else
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/core_ext/class/attribute'
|
2
4
|
require 'active_support/log_subscriber'
|
3
5
|
|
@@ -10,6 +12,11 @@ module LogStasher
|
|
10
12
|
process_event(event, %w[mailer deliver])
|
11
13
|
end
|
12
14
|
|
15
|
+
# This method will only be invoked on Rails 6.0 and prior.
|
16
|
+
# Starting in Rails 6.0 the receive method was deprecated in
|
17
|
+
# favor of ActionMailbox. The receive method was removed
|
18
|
+
# from ActionMailer in Rails 6.1, and there doesn't appear to
|
19
|
+
# be corresponding instrumentation for ActionMailbox.
|
13
20
|
def receive(event)
|
14
21
|
process_event(event, %w[mailer receive])
|
15
22
|
end
|
@@ -26,7 +33,7 @@ module LogStasher
|
|
26
33
|
|
27
34
|
def process_event(event, tags)
|
28
35
|
data = LogStasher.request_context.merge(extract_metadata(event.payload))
|
29
|
-
logger << LogStasher.build_logstash_event(data, tags).to_json
|
36
|
+
logger << "#{LogStasher.build_logstash_event(data, tags).to_json}\n"
|
30
37
|
end
|
31
38
|
|
32
39
|
def extract_metadata(payload)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'redis'
|
2
4
|
|
3
5
|
module LogStasher
|
@@ -22,7 +24,7 @@ module LogStasher
|
|
22
24
|
def redis_options
|
23
25
|
unless @redis_options
|
24
26
|
default_keys = default_options.keys
|
25
|
-
@redis_options = options.
|
27
|
+
@redis_options = options.reject { |k, _v| default_keys.include?(k) }
|
26
28
|
end
|
27
29
|
|
28
30
|
@redis_options
|
data/lib/logstasher/event.rb
CHANGED
data/lib/logstasher/railtie.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
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'
|
@@ -20,7 +22,7 @@ module LogStasher
|
|
20
22
|
config_file = File.expand_path './config/logstasher.yml'
|
21
23
|
|
22
24
|
# Load and ERB templating of YAML files
|
23
|
-
LOGSTASHER = File.exist?(config_file) ? YAML.
|
25
|
+
LOGSTASHER = File.exist?(config_file) ? YAML.safe_load(ERB.new(File.read(config_file)).result).symbolize_keys : nil
|
24
26
|
|
25
27
|
initializer :logstasher, before: :load_config_initializers do |app|
|
26
28
|
if LOGSTASHER.present?
|
@@ -42,7 +44,7 @@ module LogStasher
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def rack_cache_hashlike?(app)
|
45
|
-
app.config.action_dispatch.rack_cache
|
47
|
+
app.config.action_dispatch.rack_cache&.respond_to?(:[]=)
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
@@ -55,7 +57,7 @@ module LogStasher
|
|
55
57
|
# get all available IP address lists and use the first one.
|
56
58
|
# This will always be `127.0.0.1`.
|
57
59
|
address_info = Socket.ip_address_list.first
|
58
|
-
address_info
|
60
|
+
address_info&.ip_address
|
59
61
|
else
|
60
62
|
IPSocket.getaddress(Socket.gethostname)
|
61
63
|
end
|
data/lib/logstasher/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstasher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shadab Ahmed
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
11
|
+
date: 2020-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '5.
|
19
|
+
version: '5.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '5.
|
26
|
+
version: '5.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: request_store
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: activerecord
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '5.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '5.0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: bundler
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +58,14 @@ dependencies:
|
|
72
58
|
requirements:
|
73
59
|
- - ">="
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '5.
|
61
|
+
version: '5.2'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - ">="
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '5.
|
68
|
+
version: '5.2'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rspec
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -134,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
120
|
- !ruby/object:Gem::Version
|
135
121
|
version: '0'
|
136
122
|
requirements: []
|
137
|
-
rubygems_version: 3.
|
123
|
+
rubygems_version: 3.1.4
|
138
124
|
signing_key:
|
139
125
|
specification_version: 4
|
140
126
|
summary: Awesome rails logs
|