applicaster-logger 0.7.0 → 0.8.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 +4 -4
- data/README.md +5 -2
- data/lib/applicaster-logger.rb +0 -4
- data/lib/applicaster/logger.rb +7 -78
- data/lib/applicaster/logger/formatter.rb +22 -38
- data/lib/applicaster/logger/lograge/formatter.rb +19 -0
- data/lib/applicaster/logger/rack.rb +9 -0
- data/lib/applicaster/logger/rack/request_data.rb +25 -0
- data/lib/applicaster/logger/rack/thread_context.rb +17 -0
- data/lib/applicaster/logger/railtie.rb +59 -7
- data/lib/applicaster/logger/sidekiq.rb +59 -0
- data/lib/applicaster/logger/sidekiq/common_events.rb +42 -0
- data/lib/applicaster/logger/sidekiq/exception_logger.rb +22 -0
- data/lib/applicaster/logger/sidekiq/job_logger.rb +24 -0
- data/lib/applicaster/logger/sidekiq/middleware.rb +35 -0
- data/lib/applicaster/logger/sidekiq/thread_context.rb +16 -0
- data/lib/applicaster/logger/thread_context.rb +20 -0
- data/lib/applicaster/logger/version.rb +1 -1
- metadata +13 -6
- data/lib/applicaster/rack/request_data.rb +0 -24
- data/lib/applicaster/sidekiq/exception_logger.rb +0 -27
- data/lib/applicaster/sidekiq/job_logger.rb +0 -50
- data/lib/applicaster/sidekiq/middleware.rb +0 -109
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fd75cd4993d54d8fa1c251c31497786172a0923
|
4
|
+
data.tar.gz: 7132629f33b219958435d825b07d926ed002ff0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 724db349ba49009faab7624ac1bd482d6c486d28d52e75d5b993836cb2b50e37f7045d74889391d25e2bc3855ae3a28327a38def721c042313fdaa3bef0ee145
|
7
|
+
data.tar.gz: be26f72fe14fe0210ff25054444b241eb3e4651f60ec49e4df7bc51fe081414e4296b25a3eaa98cf979879f0250d83de8b4208f55534a44975edb5b4de8f0ee4
|
data/README.md
CHANGED
@@ -25,6 +25,8 @@ And then execute:
|
|
25
25
|
end
|
26
26
|
```
|
27
27
|
|
28
|
+
defaults to: `ENV["LOGSTASH_URI"].present?`
|
29
|
+
|
28
30
|
2. Configuring logstash output:
|
29
31
|
|
30
32
|
```ruby
|
@@ -33,9 +35,10 @@ And then execute:
|
|
33
35
|
config.applicaster_logger.logstash_config = { type: :redis }
|
34
36
|
end
|
35
37
|
```
|
36
|
-
|
38
|
+
|
39
|
+
defaults to: `{ uri: ENV["LOGSTASH_URI"] }` if `LOGSTASH_URI` is set or `{ type: :stdout }` otherwise
|
37
40
|
|
38
|
-
For
|
41
|
+
For available options see: https://github.com/dwbutler/logstash-logger#basic-usage
|
39
42
|
|
40
43
|
3. To set the application name:
|
41
44
|
|
data/lib/applicaster-logger.rb
CHANGED
data/lib/applicaster/logger.rb
CHANGED
@@ -1,84 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative "./logger/formatter"
|
2
|
+
require_relative "./logger/rack"
|
3
|
+
require_relative "./logger/railtie"
|
4
|
+
require_relative "./logger/sidekiq"
|
5
|
+
require_relative "./logger/thread_context"
|
6
|
+
require_relative "./logger/version"
|
7
|
+
|
4
8
|
|
5
9
|
module Applicaster
|
6
10
|
module Logger
|
7
|
-
# taken from https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/log_subscriber.rb
|
8
|
-
INTERNAL_PARAMS = %w(controller action format only_path)
|
9
|
-
|
10
|
-
def self.setup_lograge(app)
|
11
|
-
app.config.lograge.enabled = true
|
12
|
-
app.config.lograge.formatter = Lograge::Formatters::Logstash.new
|
13
|
-
app.config.lograge.custom_options = lambda do |event|
|
14
|
-
{
|
15
|
-
params: event.payload[:params].except(*INTERNAL_PARAMS).inspect,
|
16
|
-
facility: "action_controller",
|
17
|
-
custom_params: event.payload[:custom_params],
|
18
|
-
}
|
19
|
-
end
|
20
|
-
|
21
|
-
app.middleware.insert_after ActionDispatch::RequestId,
|
22
|
-
Applicaster::Rack::RequestData
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.setup_logger(app)
|
26
|
-
logstash_config = app.config.applicaster_logger.logstash_config
|
27
|
-
|
28
|
-
app.config.logger = LogStashLogger.new(logstash_config)
|
29
|
-
app.config.logger.level = app.config.applicaster_logger.level
|
30
|
-
app.config.logger.formatter =
|
31
|
-
Applicaster::Logger::Formatter.new(facility: "rails_logger")
|
32
|
-
|
33
|
-
if defined?(Delayed)
|
34
|
-
Delayed::Worker.logger = LogStashLogger.new(logstash_config)
|
35
|
-
Delayed::Worker.logger.level = app.config.applicaster_logger.level
|
36
|
-
Delayed::Worker.logger.formatter =
|
37
|
-
Applicaster::Logger::Formatter.new(facility: "delayed_job")
|
38
|
-
end
|
39
|
-
|
40
|
-
if defined?(::Sidekiq)
|
41
|
-
::Sidekiq.configure_server do |config|
|
42
|
-
config.error_handlers.delete_if { |h| h.is_a?(::Sidekiq::ExceptionHandler::Logger) }
|
43
|
-
::Sidekiq.error_handlers << Applicaster::Sidekiq::ExceptionLogger.new
|
44
|
-
|
45
|
-
if Gem::Version.new(::Sidekiq::VERSION) < Gem::Version.new("5.0")
|
46
|
-
require 'sidekiq/api'
|
47
|
-
config.server_middleware do |chain|
|
48
|
-
chain.remove ::Sidekiq::Middleware::Server::Logging
|
49
|
-
chain.add Applicaster::Sidekiq::Middleware::Server::LogstashLogging
|
50
|
-
end
|
51
|
-
else
|
52
|
-
logger = LogStashLogger.new(logstash_config)
|
53
|
-
logger.level = app.config.applicaster_logger.level
|
54
|
-
logger.formatter = Applicaster::Logger::Formatter.new(facility: "sidekiq")
|
55
|
-
::Sidekiq::Logging.logger = logger
|
56
|
-
::Sidekiq.options[:job_logger] = ::Applicaster::Sidekiq::JobLogger
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
if defined?(Sidetiq)
|
62
|
-
Sidetiq.logger = LogStashLogger.new(logstash_config)
|
63
|
-
Sidetiq.logger.level = app.config.applicaster_logger.level
|
64
|
-
Sidetiq.logger.formatter =
|
65
|
-
Applicaster::Logger::Formatter.new(facility: "sidetiq")
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.with_thread_data(data)
|
70
|
-
old, Thread.current[:logger_thread_data] =
|
71
|
-
Thread.current[:logger_thread_data], data
|
72
|
-
|
73
|
-
yield
|
74
|
-
ensure
|
75
|
-
Thread.current[:logger_thread_data] = old
|
76
|
-
end
|
77
|
-
|
78
|
-
def self.current_thread_data
|
79
|
-
Thread.current[:logger_thread_data] || {}
|
80
|
-
end
|
81
|
-
|
82
11
|
# Truncates +text+ to at most <tt>bytesize</tt> bytes in length without
|
83
12
|
# breaking string encoding by splitting multibyte characters or breaking
|
84
13
|
# grapheme clusters ("perceptual characters") by truncating at combining
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'logger'
|
2
2
|
require 'socket'
|
3
3
|
require 'time'
|
4
|
+
require 'logstash-logger'
|
4
5
|
|
5
6
|
module Applicaster
|
6
7
|
module Logger
|
@@ -12,53 +13,36 @@ module Applicaster
|
|
12
13
|
attr_accessor :default_fields
|
13
14
|
|
14
15
|
def initialize(options = {})
|
15
|
-
@default_fields = options.
|
16
|
+
@default_fields = options.with_indifferent_access
|
16
17
|
@datetime_format = nil
|
17
18
|
end
|
18
19
|
|
19
20
|
def call(severity, time, progname, message)
|
20
|
-
|
21
|
+
data =
|
22
|
+
default_fields.
|
23
|
+
deep_merge(message_to_data(message)).
|
24
|
+
merge({ severity: severity, host: HOST }).
|
25
|
+
deep_merge(Applicaster::Logger::ThreadContext.current)
|
26
|
+
|
27
|
+
event = LogStash::Event.new(data)
|
28
|
+
event.timestamp = time.utc.iso8601(3)
|
29
|
+
event.tags = current_tags
|
30
|
+
"#{event.to_json}\n"
|
21
31
|
end
|
22
32
|
|
23
33
|
protected
|
24
34
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
else
|
36
|
-
LogStash::Event.new(message: msg2str(data), "@timestamp" => time)
|
37
|
-
end
|
38
|
-
|
39
|
-
event[:severity] ||= severity
|
40
|
-
event[:host] ||= HOST
|
41
|
-
event[:application] ||= Rails.application.config.applicaster_logger.application_name
|
42
|
-
event[:environment] ||= Rails.env
|
43
|
-
event[:token] = ENV['LOGZIO_TOKEN'] if ENV['LOGZIO_TOKEN']
|
44
|
-
|
45
|
-
Applicaster::Logger.current_thread_data.each do |field, value|
|
46
|
-
event[field] = value
|
47
|
-
end
|
48
|
-
|
49
|
-
default_fields.each do |field, value|
|
50
|
-
event[field] ||= value
|
35
|
+
def message_to_data(message)
|
36
|
+
case message
|
37
|
+
when Hash
|
38
|
+
message.with_indifferent_access
|
39
|
+
when LogStash::Event
|
40
|
+
message.to_hash.with_indifferent_access
|
41
|
+
when /^\{/
|
42
|
+
JSON.parse(message).with_indifferent_access rescue { message: msg2str(message) }
|
43
|
+
else
|
44
|
+
{ message: msg2str(message) }.with_indifferent_access
|
51
45
|
end
|
52
|
-
|
53
|
-
current_tags.each do |tag|
|
54
|
-
event.tag(tag)
|
55
|
-
end
|
56
|
-
|
57
|
-
# In case Time#to_json has been overridden
|
58
|
-
if event.timestamp.is_a?(Time)
|
59
|
-
event.timestamp = event.timestamp.iso8601(3)
|
60
|
-
end
|
61
|
-
"#{event.to_json}\n"
|
62
46
|
end
|
63
47
|
end
|
64
48
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Applicaster
|
2
|
+
module Logger
|
3
|
+
module Lograge
|
4
|
+
class Formatter
|
5
|
+
def call(data)
|
6
|
+
{
|
7
|
+
message: message(data),
|
8
|
+
facility: "action_controller",
|
9
|
+
action_controller: data,
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def message(data)
|
14
|
+
"[#{data[:status]}] #{data[:method]} #{data[:path]} (#{data[:controller]}##{data[:action]})"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Applicaster
|
2
|
+
module Logger
|
3
|
+
module Rack
|
4
|
+
class RequestData
|
5
|
+
def initialize(app)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
Applicaster::Logger::ThreadContext.add(request_data(env))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
|
14
|
+
def request_data(env)
|
15
|
+
request = ActionDispatch::Request.new(env)
|
16
|
+
{
|
17
|
+
request_uuid: request.uuid,
|
18
|
+
remote_ip: request.remote_ip,
|
19
|
+
request_host: request.host,
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,22 +1,74 @@
|
|
1
1
|
require 'rails/railtie'
|
2
2
|
require 'lograge'
|
3
3
|
require 'logstash-logger'
|
4
|
+
require_relative "./lograge/formatter"
|
4
5
|
|
5
6
|
module Applicaster
|
6
7
|
module Logger
|
7
8
|
class Railtie < Rails::Railtie
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
DEFAULT_APP_NAME = Rails.application.class.parent.to_s.underscore
|
10
|
+
|
11
|
+
# taken from https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/log_subscriber.rb
|
12
|
+
INTERNAL_PARAMS = %w(controller action format only_path)
|
13
|
+
|
14
|
+
config.applicaster_logger = ActiveSupport::OrderedOptions.new.tap do |config|
|
15
|
+
uri = ENV["LOGSTASH_URI"]
|
16
|
+
config.enabled = uri.present?
|
17
|
+
config.level = ::Logger::INFO
|
18
|
+
config.application_name = ENV.fetch("LOG_APP_NAME") { DEFAULT_APP_NAME }
|
19
|
+
config.logstash_config = uri.present? ? { uri: uri } : { type: :stdout }
|
20
|
+
config.logzio_token = ENV['LOGZIO_TOKEN'].presence
|
21
|
+
end
|
22
|
+
|
23
|
+
initializer :applicaster_logger_rack do |app|
|
24
|
+
app.middleware.insert 0, Applicaster::Logger::Rack::ThreadContext
|
25
|
+
app.middleware.insert_after ActionDispatch::RequestId, Applicaster::Logger::Rack::RequestData
|
26
|
+
end
|
13
27
|
|
14
28
|
initializer :applicaster_logger_lograge, before: :lograge do |app|
|
15
|
-
|
29
|
+
setup_lograge(app) if app.config.applicaster_logger.enabled
|
16
30
|
end
|
17
31
|
|
18
32
|
initializer :applicaster_logger, before: :initialize_logger do |app|
|
19
|
-
|
33
|
+
setup_logger(app) if app.config.applicaster_logger.enabled
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup_lograge(app)
|
37
|
+
app.config.lograge.enabled = true
|
38
|
+
app.config.lograge.formatter = Applicaster::Logger::Lograge::Formatter.new
|
39
|
+
app.config.lograge.custom_options = lambda do |event|
|
40
|
+
{
|
41
|
+
params: event.payload[:params].except(*INTERNAL_PARAMS).inspect,
|
42
|
+
custom_params: event.payload[:custom_params],
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def setup_logger(app)
|
48
|
+
config = app.config.applicaster_logger
|
49
|
+
app.config.logger = new_logger("rails_logger")
|
50
|
+
Applicaster::Logger::Sidekiq.setup(new_logger("sidekiq")) if defined?(::Sidekiq)
|
51
|
+
Sidetiq.logger = new_logger("sidetiq") if defined?(Sidetiq)
|
52
|
+
Delayed::Worker.logger = new_logger("delayed") if defined?(Delayed)
|
53
|
+
end
|
54
|
+
|
55
|
+
def new_logger(facility)
|
56
|
+
config = ::Rails.application.config.applicaster_logger
|
57
|
+
LogStashLogger.new(config.logstash_config).tap do |logger|
|
58
|
+
logger.level = config.level
|
59
|
+
|
60
|
+
logger.formatter = Applicaster::Logger::Formatter.new(
|
61
|
+
default_fields.merge({ facility: facility })
|
62
|
+
)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def default_fields
|
67
|
+
config = ::Rails.application.config.applicaster_logger
|
68
|
+
{
|
69
|
+
application: config.application_name,
|
70
|
+
environment: Rails.env.to_s
|
71
|
+
}.merge(config.logzio_token ? { token: config.logzio_token } : {})
|
20
72
|
end
|
21
73
|
end
|
22
74
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative "./sidekiq/middleware"
|
2
|
+
require_relative "./sidekiq/job_logger"
|
3
|
+
require_relative "./sidekiq/exception_logger"
|
4
|
+
require_relative "./sidekiq/thread_context"
|
5
|
+
|
6
|
+
module Applicaster
|
7
|
+
module Logger
|
8
|
+
module Sidekiq
|
9
|
+
def self.setup(logger)
|
10
|
+
::Sidekiq::Logging.logger = logger
|
11
|
+
::Sidekiq.configure_server do |config|
|
12
|
+
config.error_handlers.delete_if { |h| h.is_a?(::Sidekiq::ExceptionHandler::Logger) }
|
13
|
+
::Sidekiq.error_handlers << Applicaster::Logger::Sidekiq::ExceptionLogger.new
|
14
|
+
|
15
|
+
config.server_middleware do |chain|
|
16
|
+
chain.prepend Applicaster::Logger::Sidekiq::ThreadContext
|
17
|
+
end
|
18
|
+
|
19
|
+
if Gem::Version.new(::Sidekiq::VERSION) < Gem::Version.new("5.0")
|
20
|
+
require 'sidekiq/api'
|
21
|
+
config.server_middleware do |chain|
|
22
|
+
chain.remove ::Sidekiq::Middleware::Server::Logging
|
23
|
+
chain.add Applicaster::Logger::Sidekiq::Middleware::Server::LogstashLogging
|
24
|
+
end
|
25
|
+
else
|
26
|
+
::Sidekiq.options[:job_logger] = ::Applicaster::Logger::Sidekiq::JobLogger
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def job_context(item, queue)
|
32
|
+
{
|
33
|
+
sidekiq: {
|
34
|
+
# job ID
|
35
|
+
jid: item['jid'],
|
36
|
+
pid: ::Process.pid,
|
37
|
+
# thread ID
|
38
|
+
tid: ::Thread.current.object_id.to_s(36),
|
39
|
+
# batch ID
|
40
|
+
bid: item['bid'],
|
41
|
+
# If we're using a wrapper class, like ActiveJob, use the "wrapped"
|
42
|
+
# attribute to expose the underlying thing.
|
43
|
+
class: (item['wrapped'] || item['class']).to_s,
|
44
|
+
queue: queue,
|
45
|
+
args: item['args'].inspect,
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def logger
|
51
|
+
::Sidekiq.logger
|
52
|
+
end
|
53
|
+
|
54
|
+
def item_class_name(item)
|
55
|
+
(item['wrapped'] || item['class']).to_s
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Applicaster
|
2
|
+
module Logger
|
3
|
+
module Sidekiq
|
4
|
+
module CommonEvents
|
5
|
+
include Applicaster::Logger::Sidekiq
|
6
|
+
|
7
|
+
def start_event(item)
|
8
|
+
{
|
9
|
+
message: "Start: #{item_class_name(item)} JID-#{item['jid']}",
|
10
|
+
sidekiq: {
|
11
|
+
event: "start",
|
12
|
+
latency: ::Sidekiq::Job.new(item).latency,
|
13
|
+
}
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def done_event(item, opts)
|
18
|
+
{
|
19
|
+
message: "Done: #{item_class_name(item)} JID-#{item['jid']}",
|
20
|
+
sidekiq: {
|
21
|
+
event: "done",
|
22
|
+
runtime: opts.fetch(:runtime),
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def exception_event(item, opts)
|
28
|
+
exception = opts.fetch(:exception)
|
29
|
+
{
|
30
|
+
message: "Fail: #{item_class_name(item)} JID-#{item['jid']}",
|
31
|
+
sidekiq: {
|
32
|
+
event: "exception",
|
33
|
+
runtime: opts.fetch(:runtime),
|
34
|
+
exception_class: exception.class.to_s,
|
35
|
+
exception_message: Applicaster::Logger.truncate_bytes(exception.message.to_s, 500),
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative "./common_events"
|
2
|
+
|
3
|
+
module Applicaster
|
4
|
+
module Logger
|
5
|
+
module Sidekiq
|
6
|
+
class ExceptionLogger
|
7
|
+
include Applicaster::Logger::Sidekiq
|
8
|
+
include Applicaster::Logger::Sidekiq::CommonEvents
|
9
|
+
|
10
|
+
def call(exception, ctxHash)
|
11
|
+
item = ctxHash[:job]
|
12
|
+
queue = item[:queue]
|
13
|
+
|
14
|
+
logger.error(
|
15
|
+
job_context(item, queue).
|
16
|
+
deep_merge(exception_event(item, exception: exception, runtime: runtime))
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative "./common_events"
|
2
|
+
|
3
|
+
module Applicaster
|
4
|
+
module Sidekiq
|
5
|
+
class JobLogger
|
6
|
+
include Applicaster::Logger::Sidekiq
|
7
|
+
include Applicaster::Logger::Sidekiq::CommonEvents
|
8
|
+
|
9
|
+
def call(item, queue)
|
10
|
+
start = Time.now
|
11
|
+
logger.info(job_context(item, queue).deep_merge(start_event(item)))
|
12
|
+
yield
|
13
|
+
runtime = elapsed(start)
|
14
|
+
logger.info(job_context(item, queue).deep_merge(done_event(item, runtime: runtime)))
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def elapsed(start)
|
20
|
+
(Time.now - start).round(3)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative "./common_events"
|
2
|
+
|
3
|
+
module Applicaster
|
4
|
+
module Logger
|
5
|
+
module Sidekiq
|
6
|
+
module Middleware
|
7
|
+
module Server
|
8
|
+
class LogstashLogging
|
9
|
+
include Applicaster::Logger::Sidekiq
|
10
|
+
include Applicaster::Logger::Sidekiq::CommonEvents
|
11
|
+
|
12
|
+
def call(worker, item, queue)
|
13
|
+
logger.info(start_event(item))
|
14
|
+
start = Time.now
|
15
|
+
yield # Pass the torch
|
16
|
+
runtime = elapsed(start)
|
17
|
+
logger.info(done_event(item, runtime: runtime))
|
18
|
+
rescue Exception => exception
|
19
|
+
runtime = elapsed(start)
|
20
|
+
logger.error(exception_event(item, exception: exception, runtime: runtime))
|
21
|
+
raise exception
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def elapsed(start)
|
27
|
+
return nil if start.nil?
|
28
|
+
(Time.now - start).to_f.round(3)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Applicaster
|
2
|
+
module Logger
|
3
|
+
module Sidekiq
|
4
|
+
class ThreadContext
|
5
|
+
include Applicaster::Logger::Sidekiq
|
6
|
+
|
7
|
+
def call(worker, item, queue)
|
8
|
+
Applicaster::Logger::ThreadContext.add(job_context(item, queue))
|
9
|
+
yield # Pass the torch
|
10
|
+
ensure
|
11
|
+
Applicaster::Logger::ThreadContext.clear!
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Applicaster
|
2
|
+
module Logger
|
3
|
+
module ThreadContext
|
4
|
+
module_function
|
5
|
+
KEY = self.name.to_sym
|
6
|
+
|
7
|
+
def current
|
8
|
+
Thread.current[KEY] ||= HashWithIndifferentAccess.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(hash)
|
12
|
+
current.merge!(hash)
|
13
|
+
end
|
14
|
+
|
15
|
+
def clear!
|
16
|
+
Thread.current[KEY] = HashWithIndifferentAccess.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: applicaster-logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vitaly Gorodetsky
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logstash-logger
|
@@ -82,12 +82,19 @@ files:
|
|
82
82
|
- lib/applicaster-logger.rb
|
83
83
|
- lib/applicaster/logger.rb
|
84
84
|
- lib/applicaster/logger/formatter.rb
|
85
|
+
- lib/applicaster/logger/lograge/formatter.rb
|
86
|
+
- lib/applicaster/logger/rack.rb
|
87
|
+
- lib/applicaster/logger/rack/request_data.rb
|
88
|
+
- lib/applicaster/logger/rack/thread_context.rb
|
85
89
|
- lib/applicaster/logger/railtie.rb
|
90
|
+
- lib/applicaster/logger/sidekiq.rb
|
91
|
+
- lib/applicaster/logger/sidekiq/common_events.rb
|
92
|
+
- lib/applicaster/logger/sidekiq/exception_logger.rb
|
93
|
+
- lib/applicaster/logger/sidekiq/job_logger.rb
|
94
|
+
- lib/applicaster/logger/sidekiq/middleware.rb
|
95
|
+
- lib/applicaster/logger/sidekiq/thread_context.rb
|
96
|
+
- lib/applicaster/logger/thread_context.rb
|
86
97
|
- lib/applicaster/logger/version.rb
|
87
|
-
- lib/applicaster/rack/request_data.rb
|
88
|
-
- lib/applicaster/sidekiq/exception_logger.rb
|
89
|
-
- lib/applicaster/sidekiq/job_logger.rb
|
90
|
-
- lib/applicaster/sidekiq/middleware.rb
|
91
98
|
homepage: ''
|
92
99
|
licenses:
|
93
100
|
- MIT
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module Applicaster
|
2
|
-
module Rack
|
3
|
-
class RequestData
|
4
|
-
def initialize(app)
|
5
|
-
@app = app
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(env)
|
9
|
-
Applicaster::Logger.with_thread_data(request_data(env)) do
|
10
|
-
@app.call(env)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def request_data(env)
|
15
|
-
request = ActionDispatch::Request.new(env)
|
16
|
-
{
|
17
|
-
request_uuid: request.uuid,
|
18
|
-
remote_ip: request.remote_ip,
|
19
|
-
request_host: request.host,
|
20
|
-
}
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Applicaster
|
2
|
-
module Sidekiq
|
3
|
-
class ExceptionLogger
|
4
|
-
def call(exception, ctxHash)
|
5
|
-
item = ctxHash[:job]
|
6
|
-
queue = item[:queue]
|
7
|
-
|
8
|
-
event = log_context(item, queue).merge({
|
9
|
-
message: "Fail: #{item['class']} JID-#{item['jid']}",
|
10
|
-
exception_class: exception.class.to_s,
|
11
|
-
exception_message: Applicaster::Logger.truncate_bytes(exception.message.to_s, 500),
|
12
|
-
})
|
13
|
-
logger.info(event)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def log_context(item, queue)
|
19
|
-
Applicaster::Sidekiq::JobLogger.log_context(item, queue)
|
20
|
-
end
|
21
|
-
|
22
|
-
def logger
|
23
|
-
::Sidekiq.logger
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
module Applicaster
|
2
|
-
module Sidekiq
|
3
|
-
class JobLogger
|
4
|
-
def call(item, queue)
|
5
|
-
puts "JobLogger"
|
6
|
-
start = Time.now
|
7
|
-
event = log_context(item, queue).merge({
|
8
|
-
message: "Start: #{item['class']} JID-#{item['jid']}",
|
9
|
-
})
|
10
|
-
logger.info(event)
|
11
|
-
yield
|
12
|
-
event = log_context(item, queue).merge({
|
13
|
-
message: "Done: #{item['class']} JID-#{item['jid']}",
|
14
|
-
})
|
15
|
-
event[:sidekiq][:duration] = elapsed(start)
|
16
|
-
logger.info(event)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def elapsed(start)
|
22
|
-
(Time.now - start).round(3)
|
23
|
-
end
|
24
|
-
|
25
|
-
def logger
|
26
|
-
::Sidekiq.logger
|
27
|
-
end
|
28
|
-
|
29
|
-
def log_context(item, queue)
|
30
|
-
self.class.log_context(item, queue)
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.sidekiq_context
|
34
|
-
::Thread.current[:sidekiq_context]
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.log_context(item, queue)
|
38
|
-
{
|
39
|
-
sidekiq: {
|
40
|
-
jid: item['jid'],
|
41
|
-
context: sidekiq_context,
|
42
|
-
worker: item['class'].to_s,
|
43
|
-
queue: queue,
|
44
|
-
args: item['args'].inspect,
|
45
|
-
}
|
46
|
-
}
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,109 +0,0 @@
|
|
1
|
-
module Applicaster
|
2
|
-
module Sidekiq
|
3
|
-
module Middleware
|
4
|
-
module Server
|
5
|
-
class LogstashLogging
|
6
|
-
|
7
|
-
def call(worker, item, queue)
|
8
|
-
::Sidekiq::Logging.with_context("#{worker.class.to_s} JID-#{item['jid']}") do
|
9
|
-
begin
|
10
|
-
logger.info(filter_fields({
|
11
|
-
message: "Start: #{worker.class.to_s} JID-#{item['jid']}",
|
12
|
-
jid: item['jid'],
|
13
|
-
pid: pid,
|
14
|
-
tid: tid,
|
15
|
-
context: context,
|
16
|
-
worker: worker.class.to_s,
|
17
|
-
queue: queue,
|
18
|
-
args: item['args'].inspect,
|
19
|
-
latency: ::Sidekiq::Job.new(::Sidekiq.dump_json(item)).latency,
|
20
|
-
memory: memory
|
21
|
-
}))
|
22
|
-
|
23
|
-
start = Time.now
|
24
|
-
|
25
|
-
yield # Pass the torch
|
26
|
-
|
27
|
-
logger.info(filter_fields({
|
28
|
-
message: "Done: #{worker.class.to_s} JID-#{item['jid']}",
|
29
|
-
jid: item['jid'],
|
30
|
-
pid: pid,
|
31
|
-
tid: tid,
|
32
|
-
context: context,
|
33
|
-
worker: worker.class.to_s,
|
34
|
-
queue: queue,
|
35
|
-
args: item['args'].inspect,
|
36
|
-
runtime: elapsed(start),
|
37
|
-
memory: memory
|
38
|
-
}))
|
39
|
-
rescue Exception => e
|
40
|
-
logger.error(filter_fields({
|
41
|
-
message: "Fail: #{worker.class.to_s} JID-#{item['jid']}",
|
42
|
-
jid: item['jid'],
|
43
|
-
pid: pid,
|
44
|
-
tid: tid,
|
45
|
-
context: context,
|
46
|
-
worker: worker.class.to_s,
|
47
|
-
queue: queue,
|
48
|
-
args: item['args'].inspect,
|
49
|
-
runtime: elapsed(start),
|
50
|
-
exception_class: e.class.to_s,
|
51
|
-
exception_message: Applicaster::Logger.truncate_bytes(e.message.to_s, 500),
|
52
|
-
memory: memory
|
53
|
-
}))
|
54
|
-
|
55
|
-
raise e
|
56
|
-
ensure
|
57
|
-
logger.device.close
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def logger
|
63
|
-
@logger ||=
|
64
|
-
begin
|
65
|
-
applicaster_logger = ::Rails.application.config.applicaster_logger
|
66
|
-
logger = LogStashLogger.new(applicaster_logger.logstash_config)
|
67
|
-
logger.level = applicaster_logger.sidekiq_log_level || applicaster_logger.level
|
68
|
-
logger.formatter = Applicaster::Logger::Formatter.new(facility: "sidekiq")
|
69
|
-
logger
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
private
|
74
|
-
|
75
|
-
def pid
|
76
|
-
::Process.pid
|
77
|
-
end
|
78
|
-
|
79
|
-
def tid
|
80
|
-
::Thread.current.object_id.to_s(36)
|
81
|
-
end
|
82
|
-
|
83
|
-
def context
|
84
|
-
::Thread.current[:sidekiq_context]
|
85
|
-
end
|
86
|
-
|
87
|
-
def memory
|
88
|
-
`ps -o rss= -p #{::Process.pid}`.chomp.to_i
|
89
|
-
end
|
90
|
-
|
91
|
-
def elapsed(start)
|
92
|
-
return nil if start.nil?
|
93
|
-
(Time.now - start).to_f.round(3)
|
94
|
-
end
|
95
|
-
|
96
|
-
def filter_fields(data)
|
97
|
-
data.each do |key, val|
|
98
|
-
if val.is_a?(String) && val.length > 32766 # max message length
|
99
|
-
data[key] = "[omitted; length = #{val.length}, max = 32766]"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
data
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|