logstasher 2.0.1 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
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