kiev 3.0.0 → 4.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/push.yml +79 -0
- data/.rubocop.yml +10 -3
- data/.ruby-version +1 -1
- data/Gemfile +1 -1
- data/README.md +32 -3
- data/gemfiles/que_0.12.2.gemfile +3 -1
- data/gemfiles/que_0.12.3.gemfile +3 -1
- data/gemfiles/rails_4.1.gemfile +4 -2
- data/gemfiles/rails_4.2.gemfile +4 -2
- data/gemfiles/rails_5.2.gemfile +15 -0
- data/gemfiles/{shoryuken_3.1.gemfile → shoryuken_4.0.gemfile} +4 -2
- data/gemfiles/sidekiq_4.2.gemfile +3 -2
- data/gemfiles/sinatra_1.4.gemfile +4 -2
- data/gemfiles/sinatra_2.0.gemfile +4 -2
- data/kiev.gemspec +8 -6
- data/lib/kiev/base.rb +1 -0
- data/lib/kiev/base52.rb +1 -1
- data/lib/kiev/config.rb +1 -0
- data/lib/kiev/context_reader.rb +6 -3
- data/lib/kiev/hanami.rb +19 -0
- data/lib/kiev/logger.rb +8 -4
- data/lib/kiev/que/job.rb +4 -1
- data/lib/kiev/rack/request_id.rb +15 -13
- data/lib/kiev/rack/request_logger.rb +16 -2
- data/lib/kiev/request_id.rb +2 -1
- data/lib/kiev/request_logger.rb +5 -2
- data/lib/kiev/shoryuken/context_reader.rb +2 -0
- data/lib/kiev/test.rb +2 -1
- data/lib/kiev/util.rb +1 -0
- data/lib/kiev/version.rb +1 -1
- metadata +30 -28
- data/.travis.yml +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f25b13c7dfe2a466ce7f9b0f03f3b4078d70158d3241aa589568124ab8b5501
|
4
|
+
data.tar.gz: 3665a4859072ec37b624a89c218ec362e019a2994236901a2ce2dfc55a2a60ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35a76a1baf47a1c857ef9c0a6b39f9adb513dd7366c372d6cbcb148980b25772759a529c82559af5779d61bf2eb51706016463fda47aaa85c8a0a3604d5667c0
|
7
|
+
data.tar.gz: b7830138907f5a65d062c3e5f2c7e2d3a9bced6595ac428b9e14ab47f11ebbef94abd35bd590a9dc5890e1045d8fdd86a85a643b1aa29c1dcb545d921045c2d6
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Main CI
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
strategy:
|
21
|
+
matrix:
|
22
|
+
ruby: ['2.5.1', '2.7.2', '2.6.5']
|
23
|
+
gemfile:
|
24
|
+
- gemfiles/que_0.12.2.gemfile
|
25
|
+
- gemfiles/que_0.12.3.gemfile
|
26
|
+
- gemfiles/rails_5.2.gemfile
|
27
|
+
- gemfiles/shoryuken_4.0.gemfile
|
28
|
+
- gemfiles/sidekiq_4.2.gemfile
|
29
|
+
- gemfiles/sinatra_1.4.gemfile
|
30
|
+
- gemfiles/sinatra_2.0.gemfile
|
31
|
+
allow_failures:
|
32
|
+
- false
|
33
|
+
include:
|
34
|
+
- os: ubuntu
|
35
|
+
ruby-version: ruby-head
|
36
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
37
|
+
allow_failures: true
|
38
|
+
env:
|
39
|
+
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
40
|
+
ALLOW_FAILURES: "${{ matrix.allow_failures }}"
|
41
|
+
REDIS_URL: "redis://localhost:6379/4"
|
42
|
+
DATABASE_URL: ${{ (startsWith(matrix.gemfile,'gemfiles/que') && 'postgres://postgres:postgres@localhost:5432/que_test') || 'sqlite3:db/combustion_test.sqlite'}}
|
43
|
+
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
|
44
|
+
|
45
|
+
# Service containers to run with `container-job`
|
46
|
+
services:
|
47
|
+
redis:
|
48
|
+
image: redis:latest
|
49
|
+
ports:
|
50
|
+
- 6379:6379
|
51
|
+
# Label used to access the service container
|
52
|
+
postgres:
|
53
|
+
# Docker Hub image
|
54
|
+
image: postgres:9.4
|
55
|
+
# Provide the password for postgres
|
56
|
+
env:
|
57
|
+
POSTGRES_PASSWORD: postgres
|
58
|
+
POSTGRES_DB: que_test
|
59
|
+
# Set health checks to wait until postgres has started
|
60
|
+
ports:
|
61
|
+
- 5432:5432
|
62
|
+
options: >-
|
63
|
+
--health-cmd pg_isready
|
64
|
+
--health-interval 10s
|
65
|
+
--health-timeout 5s
|
66
|
+
--health-retries 5
|
67
|
+
steps:
|
68
|
+
- uses: actions/checkout@v2
|
69
|
+
- name: Set up Ruby
|
70
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
71
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
72
|
+
# uses: ruby/setup-ruby@v1
|
73
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
74
|
+
with:
|
75
|
+
ruby-version: ${{ matrix.ruby }}
|
76
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
77
|
+
|
78
|
+
- name: Run tests
|
79
|
+
run: bundle exec rake || $ALLOW_FAILURES
|
data/.rubocop.yml
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
inherit_from:
|
2
2
|
- https://raw.githubusercontent.com/blacklane/rubocop/master/rubocop.yml
|
3
3
|
|
4
|
-
|
4
|
+
AllCops:
|
5
|
+
TargetRubyVersion: 2.5
|
5
6
|
Exclude:
|
6
|
-
- test/
|
7
|
-
-
|
7
|
+
- test/rails_app/**/*.rb # auto-generated
|
8
|
+
- spec/**/*.rb
|
9
|
+
- test/**/*.rb
|
10
|
+
- vendor/bundle/**/*
|
11
|
+
Lint/SuppressedException:
|
12
|
+
Exclude:
|
13
|
+
- test/**/*.rb
|
14
|
+
- spec/**/*.rb
|
8
15
|
Lint/RescueException:
|
9
16
|
Exclude:
|
10
17
|
- lib/kiev/request_body_filter/json.rb
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.1
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Kiev [![Build Status](https://
|
1
|
+
# Kiev [![Build Status](https://github.com/blacklane/kiev/workflows/Main%20CI/badge.svg?branch=master)](https://github.com/blacklane/kiev/actions?query=workflow%3A%22Main+CI%22) [![Gem Version](https://badge.fury.io/rb/kiev.svg)](https://badge.fury.io/rb/kiev)
|
2
2
|
|
3
3
|
Kiev is a comprehensive logging library aimed at covering a wide range of frameworks and tools from the Ruby ecosystem:
|
4
4
|
|
@@ -107,6 +107,35 @@ end
|
|
107
107
|
run(app)
|
108
108
|
```
|
109
109
|
|
110
|
+
### Hanami
|
111
|
+
|
112
|
+
Place your configuration under `config/initializers/kiev.rb`:
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
require "kiev"
|
116
|
+
|
117
|
+
Kiev.configure do |config|
|
118
|
+
config.app = :my_app
|
119
|
+
config.development_mode = Hanami.env?(:development)
|
120
|
+
config.log_path = File.join("log", "structured.log")
|
121
|
+
end
|
122
|
+
```
|
123
|
+
|
124
|
+
Within your `MyApp::Application` file, include the `Kiev::Hanami` module, in order to register the middleware stack.
|
125
|
+
The `include` should be added before `configure` block.
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
module MyApp
|
129
|
+
class Application < Hanami::Application
|
130
|
+
include Kiev::Hanami
|
131
|
+
|
132
|
+
configure do
|
133
|
+
# ...
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
```
|
138
|
+
|
110
139
|
### Sidekiq
|
111
140
|
|
112
141
|
Add the following lines to your initializer code:
|
@@ -168,7 +197,7 @@ For web requests the Kiev middleware will log the following information by defau
|
|
168
197
|
"event":"request_finished",
|
169
198
|
"level":"INFO",
|
170
199
|
"timestamp":"2017-01-27T16:11:44.123Z",
|
171
|
-
"
|
200
|
+
"host":"localhost",
|
172
201
|
"verb":"GET",
|
173
202
|
"path":"/",
|
174
203
|
"params":"{\"hello\":\"world\",\"password\":\"[FILTERED]\"}",
|
@@ -386,7 +415,7 @@ If you want to log 499 and 50x errors in nginx, which will not be captured by Ru
|
|
386
415
|
log_format kiev '{"application":"app_name", "event":"request_finished",'
|
387
416
|
'"timestamp":"$time_iso8601", "request_id":"$http_x_request_id",'
|
388
417
|
'"user_agent":"$http_user_agent", "status":$status,'
|
389
|
-
'"request_duration_seconds":$request_time, "
|
418
|
+
'"request_duration_seconds":$request_time, "host":"$host",'
|
390
419
|
'"verb":"$request_method", "path":"$request_uri", "tree_path": "$http_x_tree_path"}';
|
391
420
|
|
392
421
|
log_format simple_log '$remote_addr - $remote_user [$time_local] '
|
data/gemfiles/que_0.12.2.gemfile
CHANGED
data/gemfiles/que_0.12.3.gemfile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
# need it because of bug in https://github.com/chanks/que/issues/191
|
@@ -12,4 +14,4 @@ gem "rack-test", require: false
|
|
12
14
|
gem "rspec", require: false
|
13
15
|
gem "minitest-reporters", require: false
|
14
16
|
|
15
|
-
gemspec :
|
17
|
+
gemspec path: "../"
|
data/gemfiles/rails_4.1.gemfile
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gem "oj"
|
4
6
|
|
5
7
|
gem "rails", "4.1.16"
|
6
|
-
gem "sqlite3"
|
8
|
+
gem "sqlite3", "1.3.13"
|
7
9
|
|
8
10
|
gem "combustion"
|
9
11
|
gem "rspec", require: false
|
10
12
|
gem "rspec-rails", require: false
|
11
13
|
gem "minitest-reporters", require: false
|
12
14
|
|
13
|
-
gemspec :
|
15
|
+
gemspec path: "../"
|
data/gemfiles/rails_4.2.gemfile
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gem "oj"
|
4
6
|
|
5
7
|
gem "rails", "4.2.7"
|
6
|
-
gem "sqlite3"
|
8
|
+
gem "sqlite3", "1.3.13"
|
7
9
|
|
8
10
|
gem "combustion"
|
9
11
|
gem "rspec", require: false
|
10
12
|
gem "rspec-rails", require: false
|
11
13
|
gem "minitest-reporters", require: false
|
12
14
|
|
13
|
-
gemspec :
|
15
|
+
gemspec path: "../"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "oj"
|
6
|
+
|
7
|
+
gem "rails", "~> 5.2.4"
|
8
|
+
gem "sqlite3", "1.3.13"
|
9
|
+
|
10
|
+
gem "combustion"
|
11
|
+
gem "rspec", require: false
|
12
|
+
gem "rspec-rails", require: false
|
13
|
+
gem "minitest-reporters", require: false
|
14
|
+
|
15
|
+
gemspec path: "../"
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gem "aws-sdk", "~> 2.0"
|
4
|
-
gem "shoryuken", "~>
|
6
|
+
gem "shoryuken", "~> 4.0"
|
5
7
|
|
6
8
|
gem "rack-test", require: false
|
7
9
|
gem "minitest-reporters", require: false
|
8
10
|
|
9
|
-
gemspec :
|
11
|
+
gemspec path: "../"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gem "oj"
|
@@ -6,10 +8,10 @@ gem "xml-simple"
|
|
6
8
|
|
7
9
|
gem "sinatra", "1.4.7"
|
8
10
|
gem "sinatra-contrib"
|
9
|
-
gem "rack-parser", :
|
11
|
+
gem "rack-parser", require: "rack/parser"
|
10
12
|
|
11
13
|
gem "rack-test", require: false
|
12
14
|
gem "rspec", require: false
|
13
15
|
gem "minitest-reporters", require: false
|
14
16
|
|
15
|
-
gemspec :
|
17
|
+
gemspec path: "../"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gem "oj"
|
@@ -6,10 +8,10 @@ gem "xml-simple"
|
|
6
8
|
|
7
9
|
gem "sinatra", "2.0.0"
|
8
10
|
gem "sinatra-contrib"
|
9
|
-
gem "rack-parser", :
|
11
|
+
gem "rack-parser", require: "rack/parser"
|
10
12
|
|
11
13
|
gem "rack-test", require: false
|
12
14
|
gem "rspec", require: false
|
13
15
|
gem "minitest-reporters", require: false
|
14
16
|
|
15
|
-
gemspec :
|
17
|
+
gemspec path: "../"
|
data/kiev.gemspec
CHANGED
@@ -9,7 +9,9 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.licenses = ["MIT"]
|
10
10
|
|
11
11
|
spec.summary = "Distributed logging to JSON integrated with various Ruby frameworks and tools"
|
12
|
-
spec.description = "Kiev is a logging tool aimed at distributed environments. It logs to JSON, while providing
|
12
|
+
spec.description = "Kiev is a logging tool aimed at distributed environments. It logs to JSON, while providing "\
|
13
|
+
"human-readable output in development mode. It integrates nicely with Rails, Sinatra and other"\
|
14
|
+
" Rack-based frameworks, Sidekiq, Que, HTTParty, Her and other Faraday-based HTTP clients."
|
13
15
|
spec.homepage = "https://github.com/blacklane/kiev"
|
14
16
|
|
15
17
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
@@ -17,12 +19,12 @@ Gem::Specification.new do |spec|
|
|
17
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
20
|
spec.require_paths = ["lib"]
|
19
21
|
|
20
|
-
spec.required_ruby_version = ">= 2.
|
22
|
+
spec.required_ruby_version = ">= 2.5"
|
23
|
+
spec.add_dependency "oga", "~> 2.2"
|
21
24
|
spec.add_dependency "rack", ">= 1", "< 3"
|
22
25
|
spec.add_dependency "request_store", ">= 1.0", "< 1.4"
|
23
|
-
spec.add_dependency "oga", "~> 2.2"
|
24
26
|
spec.add_dependency "ruby_dig", "~> 0.0.2" # to support ruby 2.2
|
25
|
-
spec.add_development_dependency "rake"
|
26
|
-
spec.add_development_dependency "rspec"
|
27
|
-
spec.add_development_dependency "rubocop", "0.
|
27
|
+
spec.add_development_dependency "rake", '~> 0'
|
28
|
+
spec.add_development_dependency "rspec", '~> 0'
|
29
|
+
spec.add_development_dependency "rubocop", "~> 0.54"
|
28
30
|
end
|
data/lib/kiev/base.rb
CHANGED
data/lib/kiev/base52.rb
CHANGED
data/lib/kiev/config.rb
CHANGED
data/lib/kiev/context_reader.rb
CHANGED
@@ -6,6 +6,7 @@ module Kiev
|
|
6
6
|
# change field lookup.
|
7
7
|
class ContextReader
|
8
8
|
REQUEST_ID = "request_id"
|
9
|
+
TRACKING_ID = "tracking_id"
|
9
10
|
REQUEST_DEPTH = "request_depth"
|
10
11
|
TREE_PATH = "tree_path"
|
11
12
|
|
@@ -17,12 +18,14 @@ module Kiev
|
|
17
18
|
subject[key]
|
18
19
|
end
|
19
20
|
|
20
|
-
def
|
21
|
-
self[REQUEST_ID] || SecureRandom.uuid
|
21
|
+
def tracking_id
|
22
|
+
self[TRACKING_ID] || self[REQUEST_ID] || SecureRandom.uuid
|
22
23
|
end
|
23
24
|
|
25
|
+
alias_method :request_id, :tracking_id
|
26
|
+
|
24
27
|
def tree_root?
|
25
|
-
!self[REQUEST_ID]
|
28
|
+
!self[TRACKING_ID] && !self[REQUEST_ID]
|
26
29
|
end
|
27
30
|
|
28
31
|
def request_depth
|
data/lib/kiev/hanami.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "rack/request_logger"
|
4
|
+
require_relative "rack/store_request_details"
|
5
|
+
require_relative "rack/request_id"
|
6
|
+
|
7
|
+
module Kiev
|
8
|
+
module Hanami
|
9
|
+
def self.included(base)
|
10
|
+
base.configure do
|
11
|
+
# The order is important
|
12
|
+
middleware.use(::RequestStore::Middleware)
|
13
|
+
middleware.use(Kiev::Rack::RequestLogger)
|
14
|
+
middleware.use(Kiev::Rack::StoreRequestDetails)
|
15
|
+
middleware.use(Kiev::Rack::RequestId)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/kiev/logger.rb
CHANGED
@@ -13,6 +13,8 @@ module Kiev
|
|
13
13
|
def_delegators(*([:@logger] + ::Logger.instance_methods(false)))
|
14
14
|
|
15
15
|
DEFAULT_EVENT_NAME = "log"
|
16
|
+
LOG_ERROR = "ERROR"
|
17
|
+
ERROR_STATUS = 500
|
16
18
|
|
17
19
|
FORMATTER = proc do |severity, time, event_name, data|
|
18
20
|
entry =
|
@@ -21,6 +23,7 @@ module Kiev
|
|
21
23
|
event: event_name || DEFAULT_EVENT_NAME,
|
22
24
|
level: severity,
|
23
25
|
timestamp: time.utc,
|
26
|
+
tracking_id: RequestStore.store[:tracking_id],
|
24
27
|
request_id: RequestStore.store[:request_id],
|
25
28
|
request_depth: RequestStore.store[:request_depth],
|
26
29
|
tree_path: RequestStore.store[:tree_path]
|
@@ -54,8 +57,11 @@ module Kiev
|
|
54
57
|
entry.merge!(data)
|
55
58
|
elsif !data.nil?
|
56
59
|
entry[:message] = data.to_s
|
60
|
+
entry[:status] = ERROR_STATUS if data.to_s.downcase.include?(LOG_ERROR)
|
57
61
|
end
|
58
62
|
|
63
|
+
entry[:level] = LOG_ERROR if entry[:status].to_i.between?(400, 599)
|
64
|
+
|
59
65
|
# Save some disk space
|
60
66
|
entry.reject! { |_, value| value.nil? }
|
61
67
|
|
@@ -87,10 +93,8 @@ module Kiev
|
|
87
93
|
entry << "(#{duration}ms)" if duration
|
88
94
|
entry << "\n"
|
89
95
|
|
90
|
-
meta =
|
91
|
-
|
92
|
-
request_depth: RequestStore.store[:request_depth]
|
93
|
-
}.merge!(Hash(RequestStore.store[:payload]))
|
96
|
+
meta = RequestStore.store.slice(:trakcing_id, :request_id, :request_depth)
|
97
|
+
.reverse_merge!(Hash(RequestStore.store[:payload]))
|
94
98
|
|
95
99
|
meta.reject! { |_, value| value.nil? }
|
96
100
|
|
data/lib/kiev/que/job.rb
CHANGED
@@ -27,6 +27,7 @@ module Kiev
|
|
27
27
|
private
|
28
28
|
|
29
29
|
NEW_LINE = "\n"
|
30
|
+
LOG_ERROR = "ERROR"
|
30
31
|
|
31
32
|
def kiev_run
|
32
33
|
args = attrs[:args]
|
@@ -46,7 +47,8 @@ module Kiev
|
|
46
47
|
Kiev[key] = payload[key]
|
47
48
|
end
|
48
49
|
request_store = Kiev::RequestStore.store
|
49
|
-
request_store[:
|
50
|
+
request_store[:tracking_id] = payload[:tracking_id]
|
51
|
+
request_store[:request_id] = payload[:tracking_id] || payload[:request_id]
|
50
52
|
request_store[:request_depth] = payload[:request_depth].to_i + 1
|
51
53
|
request_store[:tree_path] = payload[:tree_path]
|
52
54
|
|
@@ -69,6 +71,7 @@ module Kiev
|
|
69
71
|
data[:error_class] = error.class.name
|
70
72
|
data[:error_message] = error.message[0..5000]
|
71
73
|
data[:error_backtrace] = Array(error.backtrace).join(NEW_LINE)[0..5000]
|
74
|
+
data[:level] = LOG_ERROR
|
72
75
|
end
|
73
76
|
|
74
77
|
Kiev.event(:job_finished, data)
|
data/lib/kiev/rack/request_id.rb
CHANGED
@@ -14,24 +14,26 @@ module Kiev
|
|
14
14
|
|
15
15
|
def call(env)
|
16
16
|
request_id_header_out = to_rack(:request_id)
|
17
|
-
|
17
|
+
tracking_id_header_out = to_rack(:tracking_id)
|
18
18
|
|
19
|
-
|
20
|
-
RequestStore.store[:
|
19
|
+
tracking_id = make_tracking_id(env[to_http(:tracking_id)] || env[RAILS_REQUEST_ID] || env[to_http(:request_id)])
|
20
|
+
RequestStore.store[:tracking_id] = tracking_id
|
21
|
+
RequestStore.store[:request_id] = tracking_id
|
21
22
|
RequestStore.store[:request_depth] = request_depth(env)
|
22
23
|
RequestStore.store[:tree_path] = tree_path(env)
|
23
24
|
|
24
|
-
@app.call(env).tap
|
25
|
+
@app.call(env).tap do |_status, headers, _body|
|
26
|
+
headers[tracking_id_header_out] = tracking_id
|
27
|
+
headers[request_id_header_out] = tracking_id
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
private
|
28
32
|
|
29
|
-
# TODO: in Rails 5 they set `headers[X_REQUEST_ID]`, so this will not work
|
30
|
-
# https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/request_id.rb
|
31
|
-
# https://github.com/interagent/pliny/blob/master/lib/pliny/middleware/request_id.rb
|
32
33
|
def tree_root?(env)
|
34
|
+
tracking_id_header_in = to_http(:tracking_id)
|
33
35
|
request_id_header_in = to_http(:request_id)
|
34
|
-
!env[request_id_header_in]
|
36
|
+
!env[tracking_id_header_in] && !env[request_id_header_in]
|
35
37
|
end
|
36
38
|
|
37
39
|
def request_depth(env)
|
@@ -52,15 +54,15 @@ module Kiev
|
|
52
54
|
Config.instance.all_http_propagated_fields[value]
|
53
55
|
end
|
54
56
|
|
55
|
-
def
|
56
|
-
if
|
57
|
-
|
57
|
+
def make_tracking_id(tracking_id)
|
58
|
+
if tracking_id.nil? || tracking_id.empty?
|
59
|
+
internal_tracking_id
|
58
60
|
else
|
59
|
-
Util.sanitize(
|
61
|
+
Util.sanitize(tracking_id)
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
|
-
def
|
65
|
+
def internal_tracking_id
|
64
66
|
SecureRandom.uuid
|
65
67
|
end
|
66
68
|
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "zlib"
|
4
|
+
|
3
5
|
module Kiev
|
4
6
|
module Rack
|
5
7
|
class RequestLogger
|
6
8
|
ERROR_STATUS = 500
|
7
9
|
ERROR_HEADERS = [].freeze
|
8
10
|
ERROR_BODY = [""].freeze
|
11
|
+
LOG_ERROR = "ERROR"
|
9
12
|
|
10
13
|
def initialize(app)
|
11
14
|
@app = app
|
@@ -85,7 +88,7 @@ module Kiev
|
|
85
88
|
params = ParamFilter.filter(params, config.filtered_params, config.ignored_params)
|
86
89
|
|
87
90
|
data = {
|
88
|
-
|
91
|
+
host: request.host, # env["HTTP_HOST"] || env["HTTPS_HOST"],
|
89
92
|
params: params.empty? ? nil : params, # env[Rack::QUERY_STRING],
|
90
93
|
ip: request.ip, # split_http_x_forwarded_headers(env) || env["REMOTE_ADDR"]
|
91
94
|
user_agent: env[HTTP_USER_AGENT],
|
@@ -94,6 +97,8 @@ module Kiev
|
|
94
97
|
route: extract_route(env)
|
95
98
|
}
|
96
99
|
|
100
|
+
data[:level] = LOG_ERROR if data[:status].to_i.between?(400, 599)
|
101
|
+
|
97
102
|
if env[HTTP_X_REQUEST_START]
|
98
103
|
data[:request_latency] = ((began_at - env[HTTP_X_REQUEST_START].to_f) * 1000).round(3)
|
99
104
|
end
|
@@ -115,6 +120,15 @@ module Kiev
|
|
115
120
|
full_body << str
|
116
121
|
end
|
117
122
|
data[:body] = full_body.join
|
123
|
+
if data[:body] && !data[:body].empty? && response.headers["Content-Encoding"] == "gzip"
|
124
|
+
begin
|
125
|
+
sio = StringIO.new(data[:body])
|
126
|
+
gz = Zlib::GzipReader.new(sio)
|
127
|
+
data[:body] = gz.read
|
128
|
+
rescue Zlib::GzipFile::Error => e
|
129
|
+
data[:gzip_parse_error] = e.message
|
130
|
+
end
|
131
|
+
end
|
118
132
|
end
|
119
133
|
|
120
134
|
should_log_errors = config.log_request_error_condition.call(request, response)
|
@@ -122,8 +136,8 @@ module Kiev
|
|
122
136
|
data[:error_class] = exception.class.name
|
123
137
|
data[:error_message] = exception.message[0..5000]
|
124
138
|
data[:error_backtrace] = Array(exception.backtrace).join(NEW_LINE)[0..5000]
|
139
|
+
data[:level] = LOG_ERROR
|
125
140
|
end
|
126
|
-
|
127
141
|
data
|
128
142
|
end
|
129
143
|
|
data/lib/kiev/request_id.rb
CHANGED
@@ -7,7 +7,8 @@ module Kiev
|
|
7
7
|
|
8
8
|
def wrap_request_id(context_reader, &_block)
|
9
9
|
request_store = Kiev::RequestStore.store
|
10
|
-
request_store[:
|
10
|
+
request_store[:tracking_id] = context_reader.tracking_id || context_reader.request_id
|
11
|
+
request_store[:request_id] = request_store[:tracking_id]
|
11
12
|
request_store[:request_depth] = context_reader.request_depth
|
12
13
|
request_store[:tree_path] = context_reader.tree_path
|
13
14
|
yield
|
data/lib/kiev/request_logger.rb
CHANGED
@@ -4,6 +4,7 @@ module Kiev
|
|
4
4
|
module RequestLogger
|
5
5
|
module Mixin
|
6
6
|
NEW_LINE = "\n"
|
7
|
+
LOG_ERROR = "ERROR"
|
7
8
|
|
8
9
|
def wrap_request_logger(event, **data, &_block)
|
9
10
|
began_at = Time.now
|
@@ -11,8 +12,8 @@ module Kiev
|
|
11
12
|
|
12
13
|
begin
|
13
14
|
return_value = yield
|
14
|
-
rescue StandardError =>
|
15
|
-
error =
|
15
|
+
rescue StandardError => e
|
16
|
+
error = e
|
16
17
|
end
|
17
18
|
|
18
19
|
begin
|
@@ -21,11 +22,13 @@ module Kiev
|
|
21
22
|
data[:error_class] = error.class.name
|
22
23
|
data[:error_message] = error.message[0..5000]
|
23
24
|
data[:error_backtrace] = Array(error.backtrace).join(NEW_LINE)[0..5000]
|
25
|
+
data[:level] = LOG_ERROR
|
24
26
|
end
|
25
27
|
|
26
28
|
Kiev.event(event, data)
|
27
29
|
ensure
|
28
30
|
raise error if error
|
31
|
+
|
29
32
|
return_value
|
30
33
|
end
|
31
34
|
end
|
data/lib/kiev/test.rb
CHANGED
data/lib/kiev/util.rb
CHANGED
data/lib/kiev/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kiev
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.4.0
|
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: 2021-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: oga
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.2'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rack
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,20 +64,6 @@ dependencies:
|
|
50
64
|
- - "<"
|
51
65
|
- !ruby/object:Gem::Version
|
52
66
|
version: '1.4'
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: oga
|
55
|
-
requirement: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
57
|
-
- - "~>"
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: '2.2'
|
60
|
-
type: :runtime
|
61
|
-
prerelease: false
|
62
|
-
version_requirements: !ruby/object:Gem::Requirement
|
63
|
-
requirements:
|
64
|
-
- - "~>"
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version: '2.2'
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: ruby_dig
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,44 +82,44 @@ dependencies:
|
|
82
82
|
name: rake
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
84
84
|
requirements:
|
85
|
-
- - "
|
85
|
+
- - "~>"
|
86
86
|
- !ruby/object:Gem::Version
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
90
|
version_requirements: !ruby/object:Gem::Requirement
|
91
91
|
requirements:
|
92
|
-
- - "
|
92
|
+
- - "~>"
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0'
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
96
|
name: rspec
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
98
98
|
requirements:
|
99
|
-
- - "
|
99
|
+
- - "~>"
|
100
100
|
- !ruby/object:Gem::Version
|
101
101
|
version: '0'
|
102
102
|
type: :development
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
|
-
- - "
|
106
|
+
- - "~>"
|
107
107
|
- !ruby/object:Gem::Version
|
108
108
|
version: '0'
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
name: rubocop
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
112
112
|
requirements:
|
113
|
-
- -
|
113
|
+
- - "~>"
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version: 0.
|
115
|
+
version: '0.54'
|
116
116
|
type: :development
|
117
117
|
prerelease: false
|
118
118
|
version_requirements: !ruby/object:Gem::Requirement
|
119
119
|
requirements:
|
120
|
-
- -
|
120
|
+
- - "~>"
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: 0.
|
122
|
+
version: '0.54'
|
123
123
|
description: Kiev is a logging tool aimed at distributed environments. It logs to
|
124
124
|
JSON, while providing human-readable output in development mode. It integrates nicely
|
125
125
|
with Rails, Sinatra and other Rack-based frameworks, Sidekiq, Que, HTTParty, Her
|
@@ -129,11 +129,11 @@ executables: []
|
|
129
129
|
extensions: []
|
130
130
|
extra_rdoc_files: []
|
131
131
|
files:
|
132
|
+
- ".github/workflows/push.yml"
|
132
133
|
- ".gitignore"
|
133
134
|
- ".rspec"
|
134
135
|
- ".rubocop.yml"
|
135
136
|
- ".ruby-version"
|
136
|
-
- ".travis.yml"
|
137
137
|
- Gemfile
|
138
138
|
- LICENSE.md
|
139
139
|
- README.md
|
@@ -144,7 +144,8 @@ files:
|
|
144
144
|
- gemfiles/que_0.12.3.gemfile
|
145
145
|
- gemfiles/rails_4.1.gemfile
|
146
146
|
- gemfiles/rails_4.2.gemfile
|
147
|
-
- gemfiles/
|
147
|
+
- gemfiles/rails_5.2.gemfile
|
148
|
+
- gemfiles/shoryuken_4.0.gemfile
|
148
149
|
- gemfiles/sidekiq_4.2.gemfile
|
149
150
|
- gemfiles/sinatra_1.4.gemfile
|
150
151
|
- gemfiles/sinatra_2.0.gemfile
|
@@ -155,6 +156,7 @@ files:
|
|
155
156
|
- lib/kiev/base52.rb
|
156
157
|
- lib/kiev/config.rb
|
157
158
|
- lib/kiev/context_reader.rb
|
159
|
+
- lib/kiev/hanami.rb
|
158
160
|
- lib/kiev/her_ext/client_request_id.rb
|
159
161
|
- lib/kiev/httparty.rb
|
160
162
|
- lib/kiev/json.rb
|
@@ -206,7 +208,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
206
208
|
requirements:
|
207
209
|
- - ">="
|
208
210
|
- !ruby/object:Gem::Version
|
209
|
-
version: 2.
|
211
|
+
version: '2.5'
|
210
212
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
213
|
requirements:
|
212
214
|
- - ">="
|
@@ -214,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
216
|
version: '0'
|
215
217
|
requirements: []
|
216
218
|
rubyforge_project:
|
217
|
-
rubygems_version: 2.7.
|
219
|
+
rubygems_version: 2.7.6
|
218
220
|
signing_key:
|
219
221
|
specification_version: 4
|
220
222
|
summary: Distributed logging to JSON integrated with various Ruby frameworks and tools
|
data/.travis.yml
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
branches:
|
3
|
-
only:
|
4
|
-
- master
|
5
|
-
cache:
|
6
|
-
- bundler
|
7
|
-
language: ruby
|
8
|
-
rvm:
|
9
|
-
- 2.3.3
|
10
|
-
- 2.2.3
|
11
|
-
addons:
|
12
|
-
postgresql: "9.4"
|
13
|
-
services:
|
14
|
-
- postgresql
|
15
|
-
- redis-server
|
16
|
-
before_script:
|
17
|
-
- psql -c 'create database que_test;' -U postgres
|
18
|
-
gemfile:
|
19
|
-
- gemfiles/que_0.12.2.gemfile
|
20
|
-
- gemfiles/que_0.12.3.gemfile
|
21
|
-
- gemfiles/rails_4.1.gemfile
|
22
|
-
- gemfiles/rails_4.2.gemfile
|
23
|
-
- gemfiles/shoryuken_3.1.gemfile
|
24
|
-
- gemfiles/sidekiq_4.2.gemfile
|
25
|
-
- gemfiles/sinatra_1.4.gemfile
|
26
|
-
- gemfiles/sinatra_2.0.gemfile
|
27
|
-
matrix:
|
28
|
-
fast_finish: true
|