sapience 2.10 → 2.15

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: b8328fe94f351331e7594422f677311ba6363758a907930a25d21d044b26546c
4
- data.tar.gz: a3504915777fc5ce3faf0ea8b8e310269b8cba1d0c6b9ad7013bec43884a4046
3
+ metadata.gz: a617af7787dbacebb45f2dcbfd6ec0c930e1d436488d37507bbd85e2f2856778
4
+ data.tar.gz: 68ebecc04c1377f17fd48d9f3e24cd0eab3b8bc813e14aa237426472e7377fc5
5
5
  SHA512:
6
- metadata.gz: ffcd578e958d88c52a12ebe6926478d7fec5077dc4d5d328a14e0bb088337758f3e81ab40e1a996211cac07d64cd6b66e73a1cf51b23ebb7eb7a953802146308
7
- data.tar.gz: f88677aa78333f3b804c50c9b3cad868d2d37fe71dbd994ba165943f657f40ba78d0e9a620c8b2b23aea98a82dd2b39fcfe1c781bdae8ca4470d74675fce231e
6
+ metadata.gz: 64ac6ba2a9084b6903aec351acc2811b272502a00ea366e80bc060e687fd2b6ad86aec8d348bdcc5f7ed1655369ef1d59c0441255ff46c37d7c5ebefeaa58df9
7
+ data.tar.gz: f514453bb97eb2a139b0c5139fc8a2e6215299f47a60da60df849e982fbc98da51f85e74dfa8b927bdf7fde753f0af20a9de5a3358120804cd66751e03f64433
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## v2.15
2
+ - The Formatter can now be configured to exclude selected log fields.
3
+ Currently only the Json formatter implements this.
4
+
5
+ ## v2.13
6
+ - Add config option to enable/disable metrics from grape
7
+
8
+ ## v2.12
9
+ - feature: 'log hooks', a mechanism for modifying the log event just before it is added to the appender
10
+
11
+ ## v2.11
12
+ - Add config option to enable/disable metrics from ActionController
13
+
1
14
  ## v2.10
2
15
  - Fix spec for Ruby 2.4.1
3
16
  - Bump version to 2.10 in order to properly highlight more significant change
data/README.md CHANGED
@@ -22,6 +22,15 @@ Add the gem:
22
22
  gem "sapience", require: "sapience/rails"
23
23
  ```
24
24
 
25
+ The rails integration has the following configuration options:
26
+
27
+ | Option | Description | Values | Default |
28
+ | --------------------- | ---------- | ------ | ----- |
29
+ | silent_rails | less noisy rails logs | `boolean` | `true` |
30
+ | silent_rack | suppress "Request Started..." log message from rack | `boolean` | `true` |
31
+ | silent_active_record | emit metrics from ActiveRecord | `boolean` | `true` |
32
+ | rails_ac_metrics | emit metrics from ActionController | `boolean` | `true` |
33
+
25
34
  ### Sinatra
26
35
  Add the gem:
27
36
 
@@ -119,6 +128,13 @@ API.logger = Sapience.logger
119
128
  **Note**: If you're using the rackup command to run your server in development, pass the -q flag to silence the default
120
129
  rack logger so you don't get double logging.
121
130
 
131
+
132
+ The grape integration has the following configuration options:
133
+
134
+ | Option | Description | Values | Default |
135
+ | --------------------- | ---------- | ------ | ----- |
136
+ | grape_metrics | emit metrics from grape | `boolean` | `true` |
137
+
122
138
  ### Standalone
123
139
  Add the gem:
124
140
 
@@ -156,6 +172,10 @@ Or if you, like us, have many projects that use the same configuration you can c
156
172
  default:
157
173
  app_name: My Application
158
174
  log_level: debug
175
+ silent_active_record: true
176
+ silent_rails: true
177
+ silent_rack: true
178
+ rails_ac_metrics: true
159
179
  appenders:
160
180
  - stream:
161
181
  io: STDOUT
@@ -236,6 +256,34 @@ For further details about "app_name", "filter_parameters", "appenders", "metrics
236
256
  - [logger](docs/logger.md)
237
257
 
238
258
 
259
+ ### Log hooks
260
+ *Log hooks* allow us to modify the log object **Sapience::Log** just before it is added to the appender. A 'log hook' can be an object that responds to #call. Multiple hooks can be used.
261
+ The following examples show how to use hooks to:
262
+
263
+ * inject Datadog APM tracing data in every log event.
264
+ * modify the logs event's **message** field.
265
+
266
+ ```ruby
267
+ my_logger = Sapience.logger
268
+
269
+ # inject Datadog tracing info in payload hash
270
+ my_logger.log_hooks << ->(log) do
271
+ trace_data = {
272
+ dd: {
273
+ span_id: ::Datadog.tracer.active_correlation.span_id.to_s,
274
+ trace_id: ::Datadog.tracer.active_correlation.trace_id.to_s
275
+ }
276
+ }
277
+ log.payload? ? log.payload.merge!(trace_data) : log.payload = trace_data
278
+ end
279
+
280
+ # append number of times a GC occurred since process started in field 'message'
281
+ my_logger.log_hooks << ->(log) do
282
+ log.message = "#{log.message} = GC count: #{GC.count}"
283
+ end
284
+ ```
285
+
286
+
239
287
  ## Running the tests
240
288
 
241
289
  You need to create the test postgres db, by running the command below:
@@ -13,6 +13,58 @@ Formatters can be specified by using the key `formatter: :camelized_formatter_na
13
13
  ### JSON
14
14
 
15
15
  `formatter: :json` - logs are saved as a single line json. Useful for production like environments.
16
+ The json formatter can be configured to filter out select log fields. The following configuration demonstrates this:
17
+
18
+ ```yaml
19
+ json_formatter: &json_slim
20
+ json:
21
+ exclude_fields:
22
+ - "name"
23
+ - "request_id"
24
+ - "thread"
25
+ - "pid"
26
+ - "level_index"
27
+ - "host"
28
+ - "app_name"
29
+ - "request_id"
30
+ - "action"
31
+ - "controller"
32
+ - "route"
33
+ - "file"
34
+ - "line"
35
+ - "format"
36
+ - "tags"
37
+
38
+ ci:
39
+ log_level: warn
40
+ appenders:
41
+ - stream:
42
+ io: STDOUT
43
+ formatter: color
44
+
45
+ production:
46
+ log_level: info
47
+ appenders:
48
+ - stream:
49
+ io: STDOUT
50
+ formatter:
51
+ <<: *json_slim
52
+
53
+ staging:
54
+ log_level: info
55
+ appenders:
56
+ - stream:
57
+ io: STDOUT
58
+ formatter:
59
+ <<: *json_slim
60
+
61
+ development:
62
+ log_level: debug
63
+ appenders:
64
+ - stream:
65
+ io: STDOUT
66
+ formatter: json
67
+ ```
16
68
 
17
69
  ### RAW
18
70
 
data/lib/sapience/base.rb CHANGED
@@ -3,7 +3,7 @@ module Sapience
3
3
  # rubocop:disable ClassLength
4
4
  class Base
5
5
  # Class name to be logged
6
- attr_accessor :name, :filter
6
+ attr_accessor :name, :filter, :log_hooks
7
7
  include Sapience::LogMethods
8
8
 
9
9
  # Set the logging level for this logger
@@ -174,7 +174,7 @@ module Sapience
174
174
  # Proc: Only include log messages where the supplied Proc returns true
175
175
  # The Proc must return true or false
176
176
  # rubocop:disable AbcSize, PerceivedComplexity, CyclomaticComplexity, LineLength
177
- def initialize(klass, level = nil, filter = nil)
177
+ def initialize(klass, level = nil, filter = nil, log_hooks = [])
178
178
  # Support filtering all messages to this logger using a Regular Expression
179
179
  # or Proc
180
180
  fail ArgumentError, ":filter must be a Regexp or Proc" unless filter.nil? || filter.is_a?(Regexp) || filter.is_a?(Proc)
@@ -183,6 +183,7 @@ module Sapience
183
183
  @name = klass if klass.is_a?(String)
184
184
  @name ||= klass.name if klass.respond_to?(:name)
185
185
  @name ||= klass.class.name
186
+ @log_hooks = log_hooks
186
187
 
187
188
  if level.nil?
188
189
  # Allow the global default level to determine this loggers log level
@@ -271,6 +272,9 @@ module Sapience
271
272
  end
272
273
  log.payload = payload unless payload.empty?
273
274
  end
275
+
276
+ log_hooks.each { |h| h.call(log) }
277
+
274
278
  self.log(log) if include_message?(log)
275
279
  end
276
280
  # rubocop:enable AbcSize, PerceivedComplexity, CyclomaticComplexity, LineLength
@@ -70,12 +70,13 @@ module Sapience
70
70
  if YAML.respond_to?(:safe_load) # Ruby 2.1+
71
71
  if defined?(SafeYAML) && SafeYAML.respond_to?(:load)
72
72
  SafeYAML.load(yaml_code, filename,
73
- whitelisted_tags: %w(!ruby/regexp))
73
+ whitelisted_tags: %w(!ruby/regexp),
74
+ aliases: true)
74
75
  else
75
- YAML.safe_load(yaml_code, [Regexp], [], false, filename)
76
+ YAML.safe_load(yaml_code, [Regexp], [], true, filename)
76
77
  end
77
78
  else
78
- YAML.safe_load(yaml_code, filename)
79
+ YAML.safe_load(yaml_code, filename, aliases: true)
79
80
  end
80
81
  end
81
82
  end
@@ -8,7 +8,8 @@ module Sapience
8
8
  attr_reader :default_level, :backtrace_level, :backtrace_level_index
9
9
  attr_writer :host
10
10
  attr_accessor :app_name, :ap_options, :appenders, :log_executor, :filter_parameters,
11
- :metrics, :error_handler, :silent_active_record, :silent_rails, :silent_rack
11
+ :metrics, :error_handler, :silent_active_record, :silent_rails, :silent_rack,
12
+ :rails_ac_metrics, :grape_metrics
12
13
 
13
14
  SUPPORTED_EXECUTORS = %i(single_thread_executor immediate_executor).freeze
14
15
  DEFAULT = {
@@ -23,6 +24,8 @@ module Sapience
23
24
  silent_active_record: false,
24
25
  silent_rails: false,
25
26
  silent_rack: false,
27
+ rails_ac_metrics: true,
28
+ grape_metrics: true,
26
29
  }.freeze
27
30
 
28
31
  # Initial default Level for all new instances of Sapience::Logger
@@ -44,6 +47,8 @@ module Sapience
44
47
  self.silent_active_record = @options[:silent_active_record]
45
48
  self.silent_rails = @options[:silent_rails]
46
49
  self.silent_rack = @options[:silent_rack]
50
+ self.rails_ac_metrics = @options[:rails_ac_metrics]
51
+ self.grape_metrics = @options[:grape_metrics]
47
52
  end
48
53
 
49
54
  # Sets the global default log level
@@ -2,7 +2,7 @@
2
2
  module Sapience
3
3
  module Formatters
4
4
  class Base
5
- attr_accessor :time_format, :precision, :log_host, :log_application
5
+ attr_accessor :time_format, :default_time_format, :precision, :log_host, :log_application, :exclude_fields
6
6
 
7
7
  # Parameters
8
8
  # time_format: [String|Symbol|nil]
@@ -11,13 +11,9 @@ module Sapience
11
11
  # nil: Returns Empty string for time ( no time is output ).
12
12
  # Default: '%Y-%m-%d %H:%M:%S.%6N'
13
13
  def initialize(options = {})
14
- options = options.dup
15
- @precision = 6
16
- default_format = "%Y-%m-%d %H:%M:%S.%#{precision}N"
17
- @time_format = options.key?(:time_format) ? options.delete(:time_format) : default_format
18
- @log_host = options.key?(:log_host) ? options.delete(:log_host) : true
19
- @log_application = options.key?(:log_application) ? options.delete(:log_application) : true
20
- fail(ArgumentError, "Unknown options: #{options.inspect}") unless options.empty?
14
+ @precision = 6
15
+ @default_time_format = "%Y-%m-%d %H:%M:%S.%#{precision}N"
16
+ parse_options(options.dup)
21
17
  end
22
18
 
23
19
  # Return the Time as a formatted string
@@ -32,6 +28,15 @@ module Sapience
32
28
  end
33
29
  end
34
30
 
31
+ private
32
+
33
+ def parse_options(options)
34
+ @time_format = options.key?(:time_format) ? options.delete(:time_format) : default_time_format
35
+ @log_host = options.key?(:log_host) ? options.delete(:log_host) : true
36
+ @log_application = options.key?(:log_application) ? options.delete(:log_application) : true
37
+ @exclude_fields = options.key?(:exclude_fields) ? options.delete(:exclude_fields).map(&:to_sym) : {}
38
+ fail(ArgumentError, "Unknown options: #{options.inspect}") unless options.empty?
39
+ end
35
40
  end
36
41
  end
37
42
  end
@@ -13,9 +13,25 @@ module Sapience
13
13
  # Returns log messages in JSON format
14
14
  def call(log, logger)
15
15
  h = super(log, logger)
16
- h.delete(:time)
17
- h[:timestamp] = format_time(log.time)
18
- h.to_json
16
+ prepare(h, log).to_json
17
+ end
18
+
19
+ private
20
+
21
+ def prepare(log_hash, log)
22
+ set_timestamp(log_hash, log)
23
+ remove_fields(log_hash)
24
+ log_hash
25
+ end
26
+
27
+ def set_timestamp(log_hash, log)
28
+ log_hash.delete(:time)
29
+ log_hash[:timestamp] = format_time(log.time)
30
+ log_hash
31
+ end
32
+
33
+ def remove_fields(log_hash)
34
+ log_hash.delete_if { |k, _v| exclude_fields.include?(k.to_sym) } if exclude_fields.any?
19
35
  end
20
36
  end
21
37
  end
@@ -19,6 +19,6 @@ module Sapience
19
19
  end
20
20
  Sapience.configure
21
21
  ::Grape::API.send(:include, Sapience::Loggable)
22
- Sapience::Extensions::Grape::Notifications.use
22
+ Sapience::Extensions::Grape::Notifications.use if Sapience.config.grape_metrics
23
23
  end
24
24
  end
@@ -42,12 +42,14 @@ module Sapience
42
42
  # Replace the Sidekiq logger
43
43
  Sidekiq::Logging.logger = Sapience[Sidekiq] if defined?(Sidekiq)
44
44
 
45
- # Replace the Sequel logger
46
- Sequel::Database.logger = Sapience[Sequel] if defined?(Sequel::Database)
47
-
48
45
  # Replace the Sidetiq logger
49
46
  Sidetiq.logger = Sapience[Sidetiq] if defined?(Sidetiq)
50
47
 
48
+ # Replace the Sequel logger
49
+ if defined?(Sequel::Database) && Sequel::Database.respond_to?(:logger=)
50
+ Sequel::Database.logger = Sapience[Sequel]
51
+ end
52
+
51
53
  # Replace the Raven logger
52
54
  # Raven::Configuration.logger = Sapience[Raven::Configuration] if defined?(Raven::Configuration)
53
55
  Raven.send(:include, Sapience::Loggable)
@@ -83,7 +85,7 @@ module Sapience
83
85
  end
84
86
  Sapience::Extensions::ActionView::LogSubscriber.attach_to :action_view
85
87
  # Sapience::Extensions::ActiveJob::LogSubscriber.attach_to :active_job
86
- Sapience::Extensions::ActionController::Notifications.use
88
+ Sapience::Extensions::ActionController::Notifications.use if Sapience.config.rails_ac_metrics
87
89
  Sapience::Extensions::ActiveJob::Notifications.use if defined?(ActiveJob)
88
90
  end
89
91
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Sapience
3
- VERSION = "2.10"
3
+ VERSION = "2.15"
4
4
  end
data/sapience.gemspec CHANGED
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency "memory_profiler"
38
38
  spec.add_development_dependency "pry-nav"
39
39
  spec.add_development_dependency "rails", "~> 5.0.0.1"
40
- spec.add_development_dependency "rake", "~> 10.0"
40
+ spec.add_development_dependency "rake"
41
41
  spec.add_development_dependency "reevoocop"
42
42
  spec.add_development_dependency "rspec", "~> 3.0"
43
43
  spec.add_development_dependency "rspec-its"
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sapience
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.10'
4
+ version: '2.15'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson
8
8
  - Alex Malkov
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-03-09 00:00:00.000000000 Z
12
+ date: 2021-05-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: concurrent-ruby
@@ -183,16 +183,16 @@ dependencies:
183
183
  name: rake
184
184
  requirement: !ruby/object:Gem::Requirement
185
185
  requirements:
186
- - - "~>"
186
+ - - ">="
187
187
  - !ruby/object:Gem::Version
188
- version: '10.0'
188
+ version: '0'
189
189
  type: :development
190
190
  prerelease: false
191
191
  version_requirements: !ruby/object:Gem::Requirement
192
192
  requirements:
193
- - - "~>"
193
+ - - ">="
194
194
  - !ruby/object:Gem::Version
195
- version: '10.0'
195
+ version: '0'
196
196
  - !ruby/object:Gem::Dependency
197
197
  name: reevoocop
198
198
  requirement: !ruby/object:Gem::Requirement
@@ -389,7 +389,7 @@ licenses:
389
389
  - MIT
390
390
  metadata:
391
391
  allowed_push_host: https://rubygems.org
392
- post_install_message:
392
+ post_install_message:
393
393
  rdoc_options: []
394
394
  require_paths:
395
395
  - lib
@@ -404,8 +404,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
404
404
  - !ruby/object:Gem::Version
405
405
  version: '0'
406
406
  requirements: []
407
- rubygems_version: 3.1.2
408
- signing_key:
407
+ rubygems_version: 3.0.3
408
+ signing_key:
409
409
  specification_version: 4
410
410
  summary: Hasslefree autoconfiguration for logging, metrics and exception collection.
411
411
  test_files: []