kiev 3.0.0 → 4.4.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
2
  SHA256:
3
- metadata.gz: a4af5ecbba63c1047f216399bf8eed12d144f45a624e44dd9f165d17195e744c
4
- data.tar.gz: '09a4f7f96577a537d7f8160b7697b2050698c7f7da725f9f82a395a978353657'
3
+ metadata.gz: 9f25b13c7dfe2a466ce7f9b0f03f3b4078d70158d3241aa589568124ab8b5501
4
+ data.tar.gz: 3665a4859072ec37b624a89c218ec362e019a2994236901a2ce2dfc55a2a60ca
5
5
  SHA512:
6
- metadata.gz: 2a3609ce3f0d8ff4c19c264c33310cb794fbac34947c1f56d6a796daea343e90868acc980652b66fb18cff747ae3dbfe53eeefb362df5ab7454fc26381a93997
7
- data.tar.gz: 5901954627dbeec180b4946118765736004e7512ad5e8d232f72cd3903178fe735e0e931c38bfcae21c555612d4dd4ce1e388a7bbb3aa84d7d52aaf518b974b4
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
- Lint/HandleExceptions:
4
+ AllCops:
5
+ TargetRubyVersion: 2.5
5
6
  Exclude:
6
- - test/rails_integration_test.rb
7
- - test/sinatra_integration_test.rb
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.3.3
1
+ 2.5.1
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- eval_gemfile(File.join(File.dirname(__FILE__), "gemfiles/rails_4.1.gemfile"))
3
+ eval_gemfile(File.join(File.dirname(__FILE__), "gemfiles/rails_5.2.gemfile"))
4
4
 
5
5
  gem "wwtd"
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Kiev [![Build Status](https://travis-ci.org/blacklane/kiev.svg?branch=master)](https://travis-ci.org/blacklane/kiev)
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
- "request_host":"localhost",
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, "request_host":"$host",'
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] '
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  gem "oj"
@@ -11,4 +13,4 @@ gem "rack-test", require: false
11
13
  gem "rspec", require: false
12
14
  gem "minitest-reporters", require: false
13
15
 
14
- gemspec :path => "../"
16
+ gemspec path: "../"
@@ -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 :path => "../"
17
+ gemspec path: "../"
@@ -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 :path => "../"
15
+ gemspec path: "../"
@@ -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 :path => "../"
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", "~> 3.1.0"
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 :path => "../"
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", "~> 2"
@@ -10,5 +12,4 @@ gem "minitest-reporters", require: false
10
12
 
11
13
  gem "her"
12
14
 
13
- gemspec :path => "../"
14
-
15
+ 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", :require => "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 :path => "../"
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", :require => "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 :path => "../"
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 human-readable output in development mode. It integrates nicely with Rails, Sinatra and other Rack-based frameworks, Sidekiq, Que, HTTParty, Her and other Faraday-based HTTP clients."
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.0.0"
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.49.1"
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
@@ -12,6 +12,7 @@ require_relative "version"
12
12
  require_relative "config"
13
13
  require_relative "util"
14
14
  require_relative "subrequest_helper"
15
+ require_relative "hanami"
15
16
 
16
17
  module Kiev
17
18
  class << self
data/lib/kiev/base52.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Kiev
4
4
  module Base52
5
5
  KEYS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".freeze
6
- BASE = KEYS.length.freeze
6
+ BASE = KEYS.length
7
7
 
8
8
  def self.encode(num)
9
9
  return KEYS[0] if num == 0
data/lib/kiev/config.rb CHANGED
@@ -63,6 +63,7 @@ module Kiev
63
63
  ) << :tempfile).freeze
64
64
 
65
65
  DEFAULT_HTTP_PROPAGATED_FIELDS = {
66
+ tracking_id: "X-Tracking-Id",
66
67
  request_id: "X-Request-Id",
67
68
  request_depth: "X-Request-Depth",
68
69
  tree_path: "X-Tree-Path"
@@ -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 request_id
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
@@ -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
- request_id: RequestStore.store[:request_id],
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[:request_id] = payload[:request_id]
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)
@@ -14,24 +14,26 @@ module Kiev
14
14
 
15
15
  def call(env)
16
16
  request_id_header_out = to_rack(:request_id)
17
- request_id_header_in = to_http(:request_id)
17
+ tracking_id_header_out = to_rack(:tracking_id)
18
18
 
19
- request_id = make_request_id(env[RAILS_REQUEST_ID] || env[request_id_header_in])
20
- RequestStore.store[:request_id] = request_id
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 { |_status, headers, _body| headers[request_id_header_out] = request_id }
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 make_request_id(request_id)
56
- if request_id.nil? || request_id.empty?
57
- internal_request_id
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(request_id)
61
+ Util.sanitize(tracking_id)
60
62
  end
61
63
  end
62
64
 
63
- def internal_request_id
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
- request_host: request.host, # env["HTTP_HOST"] || env["HTTPS_HOST"],
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
 
@@ -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[:request_id] = context_reader.request_id
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
@@ -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 => exception
15
- error = exception
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
@@ -12,8 +12,10 @@ module Kiev
12
12
 
13
13
  def [](key)
14
14
  return unless @message_attributes.key?(key)
15
+
15
16
  attribute_value = @message_attributes[key]
16
17
  return unless attribute_value.data_type == "String"
18
+
17
19
  attribute_value.string_value
18
20
  end
19
21
  end
data/lib/kiev/test.rb CHANGED
@@ -25,8 +25,9 @@ module Kiev
25
25
 
26
26
  def entries
27
27
  return @logs unless @logs.empty?
28
+
28
29
  @logs = raw_logs.each_line.map(&::JSON.method(:parse))
29
- rescue
30
+ rescue StandardError
30
31
  puts raw_logs
31
32
  raise
32
33
  end
data/lib/kiev/util.rb CHANGED
@@ -4,6 +4,7 @@ module Kiev
4
4
  module Util
5
5
  def self.sanitize(value)
6
6
  return unless value
7
+
7
8
  value.gsub(/[^\w\-]/, "")[0...255]
8
9
  end
9
10
 
data/lib/kiev/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kiev
4
- VERSION = "3.0.0"
4
+ VERSION = "4.4.0"
5
5
  end
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: 3.0.0
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: 2018-07-04 00:00:00.000000000 Z
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.49.1
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.49.1
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/shoryuken_3.1.gemfile
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.0.0
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.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