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 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