kiev 4.5.0 → 4.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -3
- data/gemfiles/que_0.12.3.gemfile +1 -1
- data/gemfiles/sidekiq_4.2.gemfile +3 -0
- data/lib/kiev/base.rb +29 -4
- data/lib/kiev/config.rb +38 -3
- data/lib/kiev/logger.rb +10 -8
- data/lib/kiev/param_filter.rb +27 -4
- data/lib/kiev/rack/request_logger.rb +0 -2
- data/lib/kiev/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d40605191a7b91d8df6797e3d0e9fa73f82eec5b60dc340f600f5a70b1374ce
|
4
|
+
data.tar.gz: 524309f5f0e91a96abc5d85ae158e9316f71c13af2f4076742c14f45812aaec8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52737e6382ca2e0ce2e6cf5c0ead72a30454e456ea8b126fc65c30f06c68dc02ba082f74534a84e041b88931d1ea6de1f365d6dff73e148c160c158659553b3f
|
7
|
+
data.tar.gz: 9010b961ccbef8dcbc2f39a844ab1f2992e50f7d4ede821cc5329391df24f5e8fde18422d06aa20f9fbc6110fa60d9d1170bd1b95918e7c630413c1f89c1d42e
|
data/README.md
CHANGED
@@ -176,13 +176,13 @@ Kiev::Kafka.inject_context(headers)
|
|
176
176
|
|
177
177
|
After this operation the headers variable will also include required context for the Kiev logger.
|
178
178
|
|
179
|
-
If you have a consumed `Kafka::FetchedMessage` you can extract logger context with:
|
179
|
+
If you have a consumed `Kafka::FetchedMessage` you can extract logger context with:
|
180
180
|
|
181
181
|
```ruby
|
182
182
|
Kiev::Kafka.extract_context(message)
|
183
183
|
```
|
184
184
|
|
185
|
-
This will work regardless if headers are in HTTP format, e.g. `X-Tracking-Id` or plain field names: `tracking_id`. Plus the `message_key` field will contain the key of processed message. In case you want to log some more fields configure `persistent_log_fields` and `jobs_propagated_fields`.
|
185
|
+
This will work regardless if headers are in HTTP format, e.g. `X-Tracking-Id` or plain field names: `tracking_id`. Plus the `message_key` field will contain the key of processed message. In case you want to log some more fields configure `persistent_log_fields` and `jobs_propagated_fields`.
|
186
186
|
|
187
187
|
### Que
|
188
188
|
|
@@ -251,7 +251,7 @@ For web requests the Kiev middleware will log the following information by defau
|
|
251
251
|
|
252
252
|
* `request_id` is the correlation ID and will be the same across all requests within a chain of requests. It's represented as a UUID (version 4). (currently deprecated in favor of a new name: `tracking_id`)
|
253
253
|
|
254
|
-
* `tracking_id` is the correlation ID and will be the same across all requests within a chain of requests. It's represented as a UUID (version 4). If not provided the value is seeded from deprecated `request_id`.
|
254
|
+
* `tracking_id` is the correlation ID and will be the same across all requests within a chain of requests. It's represented as a UUID (version 4). If not provided the value is seeded from deprecated `request_id`.
|
255
255
|
|
256
256
|
* `request_depth` represents the position of the current request within a chain of requests. It starts with 0.
|
257
257
|
|
@@ -317,6 +317,11 @@ Kiev.event(:my_event, { some_array: [1, 2, 3] })
|
|
317
317
|
|
318
318
|
# Log other data types (will be available under the `message` key)
|
319
319
|
Kiev.event(:my_event, "hello world")
|
320
|
+
|
321
|
+
# Log with given severity [debug, info, warn, error, fatal]
|
322
|
+
Kiev.info(:my_event)
|
323
|
+
Kiev.info(:my_event, { some_array: [1, 2, 3] })
|
324
|
+
Kiev.info(:my_event, "hello world")
|
320
325
|
```
|
321
326
|
|
322
327
|
However, `Kiev.logger` implements the Ruby `Logger` class, so all the other methods are available as well:
|
@@ -439,6 +444,28 @@ get "/" do
|
|
439
444
|
end
|
440
445
|
```
|
441
446
|
|
447
|
+
### log_level
|
448
|
+
You can specify log level.
|
449
|
+
|
450
|
+
```ruby
|
451
|
+
Kiev.configure do |config|
|
452
|
+
# One of: 0, 1, 2, 3, 4 (DEBUG, INFO, WARN, ERROR, FATAL)
|
453
|
+
config.log_level = 0
|
454
|
+
end
|
455
|
+
```
|
456
|
+
|
457
|
+
### disable_filter_for_log_levels
|
458
|
+
You can specify for which log levels personal identifying information filter will NOT be applied.
|
459
|
+
|
460
|
+
```ruby
|
461
|
+
Kiev.configure do |config|
|
462
|
+
# [DEBUG, INFO, WARN, ERROR, FATAL]
|
463
|
+
config.disable_filter_for_log_levels = [0, 1, 2, 3, 4]
|
464
|
+
end
|
465
|
+
```
|
466
|
+
|
467
|
+
**By default enabled for all suppported log levels.**
|
468
|
+
|
442
469
|
## nginx
|
443
470
|
|
444
471
|
If you want to log 499 and 50x errors in nginx, which will not be captured by Ruby application, consider adding this to your nginx configuration:
|
data/gemfiles/que_0.12.3.gemfile
CHANGED
@@ -11,5 +11,8 @@ gem "rspec", require: false
|
|
11
11
|
gem "minitest-reporters", require: false
|
12
12
|
|
13
13
|
gem "her"
|
14
|
+
# We need to do it, since her gem doesn't lock upper boundry
|
15
|
+
# https://github.com/remi/her/blob/master/her.gemspec#L26
|
16
|
+
gem "faraday", "~> 1.9.3"
|
14
17
|
|
15
18
|
gemspec path: "../"
|
data/lib/kiev/base.rb
CHANGED
@@ -13,21 +13,38 @@ require_relative "config"
|
|
13
13
|
require_relative "util"
|
14
14
|
require_relative "subrequest_helper"
|
15
15
|
require_relative "hanami"
|
16
|
+
require "forwardable"
|
17
|
+
require "logger"
|
16
18
|
|
17
19
|
module Kiev
|
18
20
|
class << self
|
21
|
+
extend Forwardable
|
22
|
+
|
23
|
+
def_delegators :config,
|
24
|
+
:logger,
|
25
|
+
:filtered_params,
|
26
|
+
:ignored_params,
|
27
|
+
:log_level,
|
28
|
+
:disable_filter_for_log_levels
|
29
|
+
|
19
30
|
EMPTY_OBJ = {}.freeze
|
20
31
|
|
21
32
|
def configure
|
22
33
|
yield(Config.instance)
|
23
34
|
end
|
24
35
|
|
25
|
-
def
|
26
|
-
Config.instance
|
36
|
+
def config
|
37
|
+
Config.instance
|
38
|
+
end
|
39
|
+
|
40
|
+
def event(log_name, data = EMPTY_OBJ, severity = log_level)
|
41
|
+
logger.log(severity, logged_data(data), log_name)
|
27
42
|
end
|
28
43
|
|
29
|
-
|
30
|
-
|
44
|
+
Config.instance.supported_log_levels.each_pair do |key, value|
|
45
|
+
define_method(key) do |log_name, data = EMPTY_OBJ|
|
46
|
+
event(log_name, data, value)
|
47
|
+
end
|
31
48
|
end
|
32
49
|
|
33
50
|
def []=(name, value)
|
@@ -51,5 +68,13 @@ module Kiev
|
|
51
68
|
end
|
52
69
|
|
53
70
|
alias_method :tracking_id, :request_id
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def logged_data(data)
|
75
|
+
return data if disable_filter_for_log_levels.include?(log_level)
|
76
|
+
|
77
|
+
ParamFilter.filter(data, filtered_params, ignored_params)
|
78
|
+
end
|
54
79
|
end
|
55
80
|
end
|
data/lib/kiev/config.rb
CHANGED
@@ -75,6 +75,16 @@ module Kiev
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
SUPPORTED_LOG_LEVELS = {
|
79
|
+
debug: ::Logger::DEBUG,
|
80
|
+
info: ::Logger::INFO,
|
81
|
+
warn: ::Logger::WARN,
|
82
|
+
error: ::Logger::ERROR,
|
83
|
+
fatal: ::Logger::FATAL
|
84
|
+
}.freeze
|
85
|
+
|
86
|
+
private_constant :SUPPORTED_LOG_LEVELS
|
87
|
+
|
78
88
|
attr_accessor :app,
|
79
89
|
:log_request_condition,
|
80
90
|
:log_request_error_condition,
|
@@ -89,10 +99,12 @@ module Kiev
|
|
89
99
|
|
90
100
|
attr_reader :development_mode,
|
91
101
|
:logger,
|
102
|
+
:log_level,
|
92
103
|
:http_propagated_fields,
|
93
104
|
:jobs_propagated_fields,
|
94
105
|
:all_http_propagated_fields, # for internal use
|
95
|
-
:all_jobs_propagated_fields # for internal use
|
106
|
+
:all_jobs_propagated_fields, # for internal use
|
107
|
+
:disable_filter_for_log_levels
|
96
108
|
|
97
109
|
def initialize
|
98
110
|
@log_request_condition = DEFAULT_LOG_REQUEST_CONDITION
|
@@ -105,9 +117,10 @@ module Kiev
|
|
105
117
|
@development_mode = false
|
106
118
|
@ignored_rack_exceptions = DEFAULT_IGNORED_RACK_EXCEPTIONS.dup
|
107
119
|
@logger = Kiev::Logger.new(STDOUT)
|
108
|
-
@log_level =
|
120
|
+
@log_level = default_log_level
|
109
121
|
@persistent_log_fields = []
|
110
122
|
@pre_rack_hook = DEFAULT_PRE_RACK_HOOK
|
123
|
+
@disable_filter_for_log_levels = []
|
111
124
|
self.propagated_fields = {}
|
112
125
|
update_logger_settings
|
113
126
|
end
|
@@ -138,20 +151,32 @@ module Kiev
|
|
138
151
|
end
|
139
152
|
|
140
153
|
def log_level=(value)
|
154
|
+
raise ArgumentError, "Unsupported log level #{value}" unless supported_log_level?(value)
|
155
|
+
|
141
156
|
@log_level = value
|
142
157
|
update_logger_settings
|
143
158
|
end
|
144
159
|
|
160
|
+
def disable_filter_for_log_levels=(log_levels)
|
161
|
+
raise ArgumentError, "Unsupported log levels" unless array_with_log_levels?(log_levels)
|
162
|
+
|
163
|
+
@disable_filter_for_log_levels = log_levels
|
164
|
+
end
|
165
|
+
|
145
166
|
def development_mode=(value)
|
146
167
|
@development_mode = value
|
147
168
|
update_logger_settings
|
148
169
|
end
|
149
170
|
|
171
|
+
def supported_log_levels
|
172
|
+
SUPPORTED_LOG_LEVELS
|
173
|
+
end
|
174
|
+
|
150
175
|
private
|
151
176
|
|
152
177
|
def update_logger_settings
|
153
178
|
@logger.formatter = formatter
|
154
|
-
@logger.level = @log_level
|
179
|
+
@logger.level = @log_level
|
155
180
|
end
|
156
181
|
|
157
182
|
def formatter
|
@@ -161,5 +186,15 @@ module Kiev
|
|
161
186
|
def default_log_level
|
162
187
|
development_mode ? ::Logger::DEBUG : ::Logger::INFO
|
163
188
|
end
|
189
|
+
|
190
|
+
def array_with_log_levels?(log_levels)
|
191
|
+
return false unless log_levels.is_a?(Array)
|
192
|
+
|
193
|
+
log_levels.all? { |level| supported_log_level?(level) }
|
194
|
+
end
|
195
|
+
|
196
|
+
def supported_log_level?(log_level)
|
197
|
+
supported_log_levels.value?(log_level)
|
198
|
+
end
|
164
199
|
end
|
165
200
|
end
|
data/lib/kiev/logger.rb
CHANGED
@@ -12,17 +12,19 @@ module Kiev
|
|
12
12
|
extend Forwardable
|
13
13
|
def_delegators(*([:@logger] + ::Logger.instance_methods(false)))
|
14
14
|
|
15
|
-
|
15
|
+
DEFAULT_LOG_NAME = "log"
|
16
|
+
DEFAULT_MESSAGE = "log"
|
16
17
|
LOG_ERROR = "ERROR"
|
17
18
|
ERROR_STATUS = 500
|
18
19
|
|
19
|
-
FORMATTER = proc do |severity, time,
|
20
|
+
FORMATTER = proc do |severity, time, log_name, data|
|
20
21
|
entry =
|
21
22
|
{
|
22
23
|
application: Config.instance.app,
|
23
|
-
|
24
|
+
log_name: log_name || DEFAULT_LOG_NAME,
|
24
25
|
level: severity,
|
25
26
|
timestamp: time.utc,
|
27
|
+
message: log_name || DEFAULT_MESSAGE,
|
26
28
|
tracking_id: RequestStore.store[:tracking_id],
|
27
29
|
request_id: RequestStore.store[:request_id],
|
28
30
|
request_depth: RequestStore.store[:request_depth],
|
@@ -39,12 +41,12 @@ module Kiev
|
|
39
41
|
entry[:jid] = RequestStore.store[:jid]
|
40
42
|
end
|
41
43
|
|
42
|
-
if !RequestStore.store[:subrequest_count] && %i(request_finished job_finished).include?(
|
44
|
+
if !RequestStore.store[:subrequest_count] && %i(request_finished job_finished).include?(log_name)
|
43
45
|
entry[:tree_leaf] = true
|
44
46
|
end
|
45
47
|
|
46
48
|
if RequestStore.store[:payload]
|
47
|
-
if %i(request_finished job_finished).include?(
|
49
|
+
if %i(request_finished job_finished).include?(log_name)
|
48
50
|
entry.merge!(RequestStore.store[:payload])
|
49
51
|
else
|
50
52
|
Config.instance.persistent_log_fields.each do |field|
|
@@ -68,17 +70,17 @@ module Kiev
|
|
68
70
|
JSON.logstash(entry)
|
69
71
|
end
|
70
72
|
|
71
|
-
DEVELOPMENT_FORMATTER = proc do |severity, time,
|
73
|
+
DEVELOPMENT_FORMATTER = proc do |severity, time, log_name, data|
|
72
74
|
entry = []
|
73
75
|
|
74
76
|
entry << time.iso8601
|
75
|
-
entry << (
|
77
|
+
entry << (log_name || severity).upcase
|
76
78
|
|
77
79
|
if data.is_a?(String)
|
78
80
|
entry << "#{data}\n"
|
79
81
|
end
|
80
82
|
|
81
|
-
if %i(request_finished job_finished).include?(
|
83
|
+
if %i(request_finished job_finished).include?(log_name)
|
82
84
|
verb = RequestStore.store[:request_verb]
|
83
85
|
path = RequestStore.store[:request_path]
|
84
86
|
entry << "#{verb} #{path}" if verb && path
|
data/lib/kiev/param_filter.rb
CHANGED
@@ -1,12 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Kiev
|
4
|
-
|
4
|
+
class ParamFilter
|
5
5
|
FILTERED = "[FILTERED]"
|
6
6
|
|
7
7
|
def self.filter(params, filtered_params, ignored_params)
|
8
|
+
new(filtered_params, ignored_params).call(params)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(filtered_params, ignored_params)
|
12
|
+
@filtered_params = normalize(filtered_params)
|
13
|
+
@ignored_params = normalize(ignored_params)
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(params)
|
17
|
+
return params unless filterable?(params)
|
18
|
+
|
8
19
|
params.each_with_object({}) do |(key, value), acc|
|
9
|
-
next if ignored_params.include?(key)
|
20
|
+
next if ignored_params.include?(key.to_s)
|
10
21
|
|
11
22
|
if defined?(ActionDispatch) && value.is_a?(ActionDispatch::Http::UploadedFile)
|
12
23
|
value = {
|
@@ -17,14 +28,26 @@ module Kiev
|
|
17
28
|
end
|
18
29
|
|
19
30
|
acc[key] =
|
20
|
-
if filtered_params.include?(key) && !value.is_a?(Hash)
|
31
|
+
if filtered_params.include?(key.to_s) && !value.is_a?(Hash)
|
21
32
|
FILTERED
|
22
33
|
elsif value.is_a?(Hash)
|
23
|
-
|
34
|
+
call(value)
|
24
35
|
else
|
25
36
|
value
|
26
37
|
end
|
27
38
|
end
|
28
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :filtered_params, :ignored_params
|
44
|
+
|
45
|
+
def filterable?(params)
|
46
|
+
params.respond_to?(:each_with_object)
|
47
|
+
end
|
48
|
+
|
49
|
+
def normalize(params)
|
50
|
+
Set.new(params.map(&:to_s))
|
51
|
+
end
|
29
52
|
end
|
30
53
|
end
|
@@ -85,8 +85,6 @@ module Kiev
|
|
85
85
|
request.params
|
86
86
|
end
|
87
87
|
|
88
|
-
params = ParamFilter.filter(params, config.filtered_params, config.ignored_params)
|
89
|
-
|
90
88
|
data = {
|
91
89
|
host: request.host, # env["HTTP_HOST"] || env["HTTPS_HOST"],
|
92
90
|
params: params.empty? ? nil : params, # env[Rack::QUERY_STRING],
|
data/lib/kiev/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kiev
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blacklane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oga
|
@@ -222,8 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
222
|
- !ruby/object:Gem::Version
|
223
223
|
version: '0'
|
224
224
|
requirements: []
|
225
|
-
|
226
|
-
rubygems_version: 2.7.6
|
225
|
+
rubygems_version: 3.3.7
|
227
226
|
signing_key:
|
228
227
|
specification_version: 4
|
229
228
|
summary: Distributed logging to JSON integrated with various Ruby frameworks and tools
|