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 +5 -5
- data/CHANGELOG.md +17 -0
- data/README.md +58 -4
- data/docs/appenders/formatters.md +52 -0
- data/lib/sapience/base.rb +6 -2
- data/lib/sapience/config_loader.rb +4 -3
- data/lib/sapience/configuration.rb +4 -2
- data/lib/sapience/formatters/base.rb +13 -8
- data/lib/sapience/formatters/json.rb +19 -3
- data/lib/sapience/grape.rb +1 -1
- data/lib/sapience/rails/engine.rb +5 -3
- data/lib/sapience/version.rb +1 -1
- data/sapience.gemspec +4 -4
- metadata +14 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c23794042cc619577603ac314507edf82fe9c668
|
4
|
+
data.tar.gz: 5d1908e88b61c429f295cb59d64620039c5737b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
307
|
+
Rspec with Rails 5.0:
|
308
|
+
`docker-compose up rails50`
|
257
309
|
|
258
|
-
|
310
|
+
Rspec with Grape:
|
311
|
+
`docker-compose up grape`
|
259
312
|
|
260
|
-
|
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], [],
|
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
|
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
|
-
|
15
|
-
@
|
16
|
-
|
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.
|
17
|
-
|
18
|
-
|
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
|
data/lib/sapience/grape.rb
CHANGED
@@ -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)
|
data/lib/sapience/version.rb
CHANGED
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: '
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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
|
-
|
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.
|