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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14eb9fb38934bed703677d907edb9a25dbf3c6fa
4
- data.tar.gz: a99a2cb2212f1d8d3846fb3790b254d030b9afbc
3
+ metadata.gz: 7fd75cd4993d54d8fa1c251c31497786172a0923
4
+ data.tar.gz: 7132629f33b219958435d825b07d926ed002ff0b
5
5
  SHA512:
6
- metadata.gz: 7240f155356278285e8fd0a7c6c2523acf49dfeb78eab01ffaf66a27c4fa5484b6f32946e902e07f17754780ed2d34bd8d17c85e93d503c0531f4b20873afb43
7
- data.tar.gz: 89a300fbbf6c3eb294c0408a7d64178443354061d718ca37e35cfa2f571a9c76266ccc1d17f30e18980df90b04fa38af194e7c3445f6ec7b78c9264e14e20477
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
- defaults to: `{ type: :stdout }`
38
+
39
+ defaults to: `{ uri: ENV["LOGSTASH_URI"] }` if `LOGSTASH_URI` is set or `{ type: :stdout }` otherwise
37
40
 
38
- For availible options see: https://github.com/dwbutler/logstash-logger#basic-usage
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
 
@@ -1,5 +1 @@
1
1
  require 'applicaster/logger'
2
- require "applicaster/rack/request_data"
3
- require "applicaster/sidekiq/middleware"
4
- require "applicaster/sidekiq/job_logger"
5
- require "applicaster/sidekiq/exception_logger"
@@ -1,84 +1,13 @@
1
- require "applicaster/logger/version"
2
- require "applicaster/logger/railtie"
3
- require "applicaster/logger/formatter"
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.dup
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
- build_event(message, severity, time)
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 build_event(message, severity, time)
26
- data = JSON.parse(message).symbolize_keys rescue nil if message.is_a?(String)
27
- data ||= message
28
-
29
- event =
30
- case data
31
- when LogStash::Event
32
- data.clone
33
- when Hash
34
- LogStash::Event.new(data.merge("@timestamp" => time))
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,9 @@
1
+ require_relative "./rack/request_data"
2
+ require_relative "./rack/thread_context"
3
+
4
+ module Applicaster
5
+ module Logger
6
+ module Rack
7
+ end
8
+ end
9
+ 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
@@ -0,0 +1,17 @@
1
+ module Applicaster
2
+ module Logger
3
+ module Rack
4
+ class ThreadContext
5
+ def initialize(app)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ @app.call(env)
11
+ ensure
12
+ Applicaster::Logger::ThreadContext.clear!
13
+ end
14
+ end
15
+ end
16
+ end
17
+ 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
- config.applicaster_logger = ActiveSupport::OrderedOptions.new
9
- config.applicaster_logger.enabled = false
10
- config.applicaster_logger.level = ::Logger::INFO
11
- config.applicaster_logger.logstash_config = { type: :stdout }
12
- config.applicaster_logger.application_name = Rails.application.class.parent.to_s.underscore
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
- Applicaster::Logger.setup_lograge(app) if app.config.applicaster_logger.enabled
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
- Applicaster::Logger.setup_logger(app) if app.config.applicaster_logger.enabled
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
@@ -1,5 +1,5 @@
1
1
  module Applicaster
2
2
  module Logger
3
- VERSION = "0.7.0"
3
+ VERSION = "0.8.0"
4
4
  end
5
5
  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.7.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-08-10 00:00:00.000000000 Z
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