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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c4f5c6311cd4d8ae8883aaff46a0238f688f456af9f8774abd79619e5cbba28
4
- data.tar.gz: 654cdd782f29136fa87517fff5468ce45bd4e861783d9d305b344943cfbbacc0
3
+ metadata.gz: 59cdc11b4f36e90443fcc8ea7332552874da2ad2205f38e4efac48c8e4dda63a
4
+ data.tar.gz: 997cb22cb6799f67d28562e986e326fa23597ee5168a635bdc917d6a9bb65c6b
5
5
  SHA512:
6
- metadata.gz: efbf0988e5ba529f52bbe17f57088473099b8d9931f147f9c8c572dcd71f5e9a5154e4486ffe381186fb2c5514e9ed34324bb5b3552a4c5f5fbad5eab28b1064
7
- data.tar.gz: 411ac7f12e116ac6a2b2a2f6db01d08c76df82553eaf8a29bcd93bd2fb94df62e6b0c11c7eabe7748a97a662900b33f5fa0860888d3c557e4c1fa76b6868650c
6
+ metadata.gz: dd6d94a4055566fd119a570107724ce1fc1c1f3f1781f2929c248e4f2b227a3f95adb010b6e059f44cf49991f5baa1d9f3271f272efb5a97415104a265eb0e1b
7
+ data.tar.gz: 35d3e80b5e460753033b327e41d51149d24b20c7b1321189a2ec24373ac5aa9c713189eba701ddc3ec5904fbf86a2b98657deff4c2a02fcfcee20f93c31fd9f9
@@ -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::Logging::LogSubscriber'
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 = !!config.log_controller_parameters
111
- self.backtrace = !!config.backtrace unless config.backtrace.nil?
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($0) == 'rake'
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 && logger.send("#{severity}?")
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 + "\n"
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 + "\n"
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
- begin
2
- # `rescue nil` didn't work for some Ruby versions
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
- rescue LoadError
6
+ else
7
+ require 'active_job/log_subscriber'
5
8
  end
6
9
 
7
- if defined?(::ActiveJob::Logging::LogSubscriber)
8
- module LogStasher
9
- module ActiveJob
10
- class LogSubscriber < ::ActiveJob::Logging::LogSubscriber
11
- def enqueue(event)
12
- process_event(event, 'enqueue')
13
- end
14
-
15
- def enqueue_at(event)
16
- process_event(event, 'enqueue_at')
17
- end
18
-
19
- def perform(event)
20
- process_event(event, 'perform')
21
-
22
- # Revert the request id back, in the event that the inline adapter is being used or a
23
- # perform_now was used.
24
- LogStasher.request_context[:request_id] = Thread.current[:old_request_id]
25
- Thread.current[:old_request_id] = nil
26
- end
27
-
28
- def perform_start(event)
29
- # Use the job_id as the request id, so that any custom logging done for a job
30
- # shares a request id, and has the job id in each log line.
31
- #
32
- # It's not being set when the job is enqueued, so enqueuing a job will have it's default
33
- # request_id. In a lot of cases, it will be because of a web request.
34
- #
35
- # Hang onto the old request id, so we can revert after the job is done being performed.
36
- Thread.current[:old_request_id] = LogStasher.request_context[:request_id]
37
- LogStasher.request_context[:request_id] = event.payload[:job].job_id
38
-
39
- process_event(event, 'perform_start')
40
- end
41
-
42
- def logger
43
- LogStasher.logger
44
- end
45
-
46
- private
47
-
48
- def process_event(event, type)
49
- data = extract_metadata(event)
50
- data.merge! extract_exception(event)
51
- data.merge! extract_scheduled_at(event) if type == 'enqueue_at'
52
- data.merge! extract_duration(event) if type == 'perform'
53
- data.merge! request_context
54
-
55
- tags = ['job', type]
56
- tags.push('exception') if data[:exception]
57
- logger << LogStasher.build_logstash_event(data, tags).to_json + "\n"
58
- end
59
-
60
- def extract_metadata(event)
61
- {
62
- job_id: event.payload[:job].job_id,
63
- queue_name: queue_name(event),
64
- job_class: event.payload[:job].class.to_s,
65
- job_args: args_info(event.payload[:job])
66
- }
67
- end
68
-
69
- def extract_duration(event)
70
- { duration: event.duration.to_f.round(2) }
71
- end
72
-
73
- def extract_exception(event)
74
- event.payload.slice(:exception)
75
- end
76
-
77
- def extract_scheduled_at(event)
78
- { scheduled_at: scheduled_at(event) }
79
- end
80
-
81
- def request_context
82
- LogStasher.request_context
83
- end
84
-
85
- # The default args_info makes a string. We need objects to turn into JSON.
86
- def args_info(job)
87
- job.arguments.map { |arg| arg.try(:to_global_id).try(:to_s) || arg }
88
- end
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 + "\n" if logger && lsevent
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
- return if 'SCHEMA' == data[:name]
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 + "\n"
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
- if ::ActionPack::VERSION::MAJOR == 3 && ::ActionPack::VERSION::MINOR == 0
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
- $!.backtrace.join("\n")
92
- else
93
- $!.backtrace.first
94
- end
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 + "\n"
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
  module LogStasher
2
4
  module CustomFields
3
5
  module LogSubscriber
@@ -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.select { |k, _v| !default_keys.include?(k) }
27
+ @redis_options = options.reject { |k, _v| default_keys.include?(k) }
26
28
  end
27
29
 
28
30
  @redis_options
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'time'
3
5
  require 'date'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LogStasher
2
4
  module ActionController
3
5
  module Instrumentation
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  module Instrumentation
3
5
  alias orig_process_action process_action
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/rack/logger'
2
4
 
3
5
  module Rails
@@ -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.load(ERB.new(File.read(config_file)).result).symbolize_keys : nil
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 && app.config.action_dispatch.rack_cache.respond_to?(:[]=)
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 && address_info.ip_address
60
+ address_info&.ip_address
59
61
  else
60
62
  IPSocket.getaddress(Socket.gethostname)
61
63
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LogStasher
2
- VERSION = '2.0.1'.freeze
4
+ VERSION = '2.1.3'
3
5
  end
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.0.1
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-28 00:00:00.000000000 Z
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.0'
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.0'
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.0'
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.0'
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.0.3
123
+ rubygems_version: 3.1.4
138
124
  signing_key:
139
125
  specification_version: 4
140
126
  summary: Awesome rails logs