sapience 2.11 → 3.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
- SHA256:
3
- metadata.gz: 4dea67688e4da16e54b354ef95c3307c40b4c48a7a9c731b036a759301993bad
4
- data.tar.gz: e95f42b7e1b564b96436119394c5cf36bfe764e151edc27f3bdd71571d373ff3
2
+ SHA1:
3
+ metadata.gz: c23794042cc619577603ac314507edf82fe9c668
4
+ data.tar.gz: 5d1908e88b61c429f295cb59d64620039c5737b1
5
5
  SHA512:
6
- metadata.gz: 9d44242c65762e0696ff3b34256d2ee67cee441c1a957efb988ecebaa6abd340ba2e02e1fbd5168973262e689333b7bbc4e4fd5835bc9a5472b22fbb2990c15d
7
- data.tar.gz: b803898eee7e30eedfcf704d9befc942e518e53da773fe699888d6c4cdfe79402ce4bdb7f9bbfdb5f1a14b2b78cc0d7101e658c32fe1da01c181c50a80f24fc0
6
+ metadata.gz: 48b75236add0e85e523e0695b6b1639f483cf5a68e3b4123f0b9e9ff6481ff8aa3460659764d3cd517b5a93b5e25cb7ea2819601eee04c5408037cb1e266349b
7
+ data.tar.gz: 06a282085bdc1f8b6af10db16ec081e0272cd126700d6ffb5374b28bcad6089d3a34016d8fc8e8dd066daf954428275ea097cf8e738f24600a3056516b8bb02d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ ## v3.0
2
+ - Updating gem dependencies:
3
+ - bundler -> 1.17.3
4
+ - dogstatsd -> 5.2.0
5
+ - rspec -> 3.10.0
6
+ - sentry-raven -> 3.1.2
7
+
8
+ ## v2.15
9
+ - The Formatter can now be configured to exclude selected log fields.
10
+ Currently only the Json formatter implements this.
11
+
12
+ ## v2.13
13
+ - Add config option to enable/disable metrics from grape
14
+
15
+ ## v2.12
16
+ - feature: 'log hooks', a mechanism for modifying the log event just before it is added to the appender
17
+
1
18
  ## v2.11
2
19
  - Add config option to enable/disable metrics from ActionController
3
20
 
data/README.md CHANGED
@@ -128,6 +128,13 @@ API.logger = Sapience.logger
128
128
  **Note**: If you're using the rackup command to run your server in development, pass the -q flag to silence the default
129
129
  rack logger so you don't get double logging.
130
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
+
131
138
  ### Standalone
132
139
  Add the gem:
133
140
 
@@ -249,15 +256,62 @@ For further details about "app_name", "filter_parameters", "appenders", "metrics
249
256
  - [logger](docs/logger.md)
250
257
 
251
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
+
252
287
  ## Running the tests
253
288
 
254
- You need to create the test postgres db, by running the command below:
289
+ You can run all of them with the following command:
290
+
291
+ `docker-compose up`
292
+
293
+ To run particular tests use the following commands:
294
+
295
+ Reevoocop:
296
+ `docker-compose up reevoocop`
297
+
298
+ Rspec:
299
+ `docker-compose up rspec`
300
+
301
+ Rspec with Rails 3.2:
302
+ `docker-compose up rails32`
303
+
304
+ Rspec with Rails 4.2:
305
+ `docker-compose up rails42`
255
306
 
256
- `createdb rails_app_test`
307
+ Rspec with Rails 5.0:
308
+ `docker-compose up rails50`
257
309
 
258
- Then you can run them with the following command:
310
+ Rspec with Grape:
311
+ `docker-compose up grape`
259
312
 
260
- `bin/tests`
313
+ Rspec with Sinatra:
314
+ `docker-compose up sinatra`
261
315
 
262
316
  ## Environment variables
263
317
 
@@ -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
@@ -9,7 +9,7 @@ module Sapience
9
9
  attr_writer :host
10
10
  attr_accessor :app_name, :ap_options, :appenders, :log_executor, :filter_parameters,
11
11
  :metrics, :error_handler, :silent_active_record, :silent_rails, :silent_rack,
12
- :rails_ac_metrics
12
+ :rails_ac_metrics, :grape_metrics
13
13
 
14
14
  SUPPORTED_EXECUTORS = %i(single_thread_executor immediate_executor).freeze
15
15
  DEFAULT = {
@@ -25,6 +25,7 @@ module Sapience
25
25
  silent_rails: false,
26
26
  silent_rack: false,
27
27
  rails_ac_metrics: true,
28
+ grape_metrics: true,
28
29
  }.freeze
29
30
 
30
31
  # Initial default Level for all new instances of Sapience::Logger
@@ -46,7 +47,8 @@ module Sapience
46
47
  self.silent_active_record = @options[:silent_active_record]
47
48
  self.silent_rails = @options[:silent_rails]
48
49
  self.silent_rack = @options[:silent_rack]
49
- self.rails_ac_metrics = @options[:rails_ac_metrics]
50
+ self.rails_ac_metrics = @options[:rails_ac_metrics]
51
+ self.grape_metrics = @options[:grape_metrics]
50
52
  end
51
53
 
52
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)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Sapience
3
- VERSION = "2.11"
3
+ VERSION = "3.0"
4
4
  end
data/sapience.gemspec CHANGED
@@ -28,9 +28,9 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency "concurrent-ruby", "~> 1.0"
29
29
  spec.add_development_dependency "active_model_serializers", "~> 0.10.0"
30
30
  spec.add_development_dependency "appraisal"
31
- spec.add_development_dependency "bundler", "~> 1"
31
+ spec.add_development_dependency "bundler", "~> 1.17.3"
32
32
  spec.add_development_dependency "codeclimate-test-reporter"
33
- spec.add_development_dependency "dogstatsd-ruby", "~> 2.0"
33
+ spec.add_development_dependency "dogstatsd-ruby", "~> 5.2.0"
34
34
  spec.add_development_dependency "fuubar"
35
35
  spec.add_development_dependency "gem-release"
36
36
  spec.add_development_dependency "grape"
@@ -39,10 +39,10 @@ Gem::Specification.new do |spec|
39
39
  spec.add_development_dependency "rails", "~> 5.0.0.1"
40
40
  spec.add_development_dependency "rake"
41
41
  spec.add_development_dependency "reevoocop"
42
- spec.add_development_dependency "rspec", "~> 3.0"
42
+ spec.add_development_dependency "rspec", "~> 3.10.0"
43
43
  spec.add_development_dependency "rspec-its"
44
44
  spec.add_development_dependency "rspec-prof"
45
- spec.add_development_dependency "sentry-raven"
45
+ spec.add_development_dependency "sentry-raven", "~> 3.1.2"
46
46
  spec.add_development_dependency "simplecov"
47
47
  spec.add_development_dependency "simplecov-json"
48
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sapience
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.11'
4
+ version: '3.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-03-09 00:00:00.000000000 Z
12
+ date: 2021-07-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: concurrent-ruby
@@ -59,14 +59,14 @@ dependencies:
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '1'
62
+ version: 1.17.3
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '1'
69
+ version: 1.17.3
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: codeclimate-test-reporter
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -87,14 +87,14 @@ dependencies:
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: '2.0'
90
+ version: 5.2.0
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: '2.0'
97
+ version: 5.2.0
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: fuubar
100
100
  requirement: !ruby/object:Gem::Requirement
@@ -213,14 +213,14 @@ dependencies:
213
213
  requirements:
214
214
  - - "~>"
215
215
  - !ruby/object:Gem::Version
216
- version: '3.0'
216
+ version: 3.10.0
217
217
  type: :development
218
218
  prerelease: false
219
219
  version_requirements: !ruby/object:Gem::Requirement
220
220
  requirements:
221
221
  - - "~>"
222
222
  - !ruby/object:Gem::Version
223
- version: '3.0'
223
+ version: 3.10.0
224
224
  - !ruby/object:Gem::Dependency
225
225
  name: rspec-its
226
226
  requirement: !ruby/object:Gem::Requirement
@@ -253,16 +253,16 @@ dependencies:
253
253
  name: sentry-raven
254
254
  requirement: !ruby/object:Gem::Requirement
255
255
  requirements:
256
- - - ">="
256
+ - - "~>"
257
257
  - !ruby/object:Gem::Version
258
- version: '0'
258
+ version: 3.1.2
259
259
  type: :development
260
260
  prerelease: false
261
261
  version_requirements: !ruby/object:Gem::Requirement
262
262
  requirements:
263
- - - ">="
263
+ - - "~>"
264
264
  - !ruby/object:Gem::Version
265
- version: '0'
265
+ version: 3.1.2
266
266
  - !ruby/object:Gem::Dependency
267
267
  name: simplecov
268
268
  requirement: !ruby/object:Gem::Requirement
@@ -404,7 +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
407
+ rubyforge_project:
408
+ rubygems_version: 2.6.14.4
408
409
  signing_key:
409
410
  specification_version: 4
410
411
  summary: Hasslefree autoconfiguration for logging, metrics and exception collection.