sapience 2.10 → 2.15

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: 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: []