kiev 2.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.rubocop.yml +25 -0
- data/.ruby-version +1 -0
- data/.travis.yml +27 -0
- data/Gemfile +5 -0
- data/LICENSE.md +7 -0
- data/README.md +461 -0
- data/Rakefile +18 -0
- data/bin/console +8 -0
- data/config.ru +9 -0
- data/gemfiles/que_0.12.2.gemfile +14 -0
- data/gemfiles/que_0.12.3.gemfile +15 -0
- data/gemfiles/rails_4.1.gemfile +13 -0
- data/gemfiles/rails_4.2.gemfile +13 -0
- data/gemfiles/sidekiq_4.2.gemfile +14 -0
- data/gemfiles/sinatra_1.4.gemfile +15 -0
- data/gemfiles/sinatra_2.0.gemfile +15 -0
- data/kiev.gemspec +28 -0
- data/lib/ext/rack/common_logger.rb +12 -0
- data/lib/kiev.rb +9 -0
- data/lib/kiev/base.rb +51 -0
- data/lib/kiev/base52.rb +20 -0
- data/lib/kiev/config.rb +164 -0
- data/lib/kiev/her_ext/client_request_id.rb +14 -0
- data/lib/kiev/httparty.rb +11 -0
- data/lib/kiev/json.rb +118 -0
- data/lib/kiev/logger.rb +122 -0
- data/lib/kiev/param_filter.rb +30 -0
- data/lib/kiev/que/job.rb +78 -0
- data/lib/kiev/rack.rb +20 -0
- data/lib/kiev/rack/request_id.rb +68 -0
- data/lib/kiev/rack/request_logger.rb +140 -0
- data/lib/kiev/rack/silence_action_dispatch_logger.rb +22 -0
- data/lib/kiev/rack/store_request_details.rb +21 -0
- data/lib/kiev/railtie.rb +55 -0
- data/lib/kiev/request_body_filter.rb +36 -0
- data/lib/kiev/request_body_filter/default.rb +11 -0
- data/lib/kiev/request_body_filter/form_data.rb +12 -0
- data/lib/kiev/request_body_filter/json.rb +14 -0
- data/lib/kiev/request_body_filter/xml.rb +18 -0
- data/lib/kiev/request_store.rb +32 -0
- data/lib/kiev/sidekiq.rb +41 -0
- data/lib/kiev/sidekiq/client_request_id.rb +12 -0
- data/lib/kiev/sidekiq/request_id.rb +39 -0
- data/lib/kiev/sidekiq/request_logger.rb +39 -0
- data/lib/kiev/sidekiq/request_store.rb +13 -0
- data/lib/kiev/sidekiq/store_request_details.rb +27 -0
- data/lib/kiev/subrequest_helper.rb +61 -0
- data/lib/kiev/util.rb +14 -0
- data/lib/kiev/version.rb +5 -0
- metadata +208 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4993218a36a9d91204d3af2a87327a3394494e3f
|
4
|
+
data.tar.gz: f446c0d1c31a6aacf5d12d47488cafb19756dabd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 66768446011943507c8741451239becbbaa9397b1d4cf96214f3bc0bc31e524d407821d55566ea998953092ae5bcf869c8e3a74622ad06f9a0cca446f1fcf0d2
|
7
|
+
data.tar.gz: d11e2427f18cb51feb4ccddcb270b840638f37531819685e9913c6a1825a0cc8dc2d5fd6e44cfd2799a27b47caaa94178edabad127b135cbc6d5c40161c288c5
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
inherit_from:
|
2
|
+
- https://raw.githubusercontent.com/blacklane/rubocop/master/rubocop.yml
|
3
|
+
|
4
|
+
Lint/HandleExceptions:
|
5
|
+
Exclude:
|
6
|
+
- test/rails_integration_test.rb
|
7
|
+
- test/sinatra_integration_test.rb
|
8
|
+
Lint/RescueException:
|
9
|
+
Exclude:
|
10
|
+
- lib/kiev/request_body_filter/json.rb
|
11
|
+
- lib/kiev/sidekiq/request_logger.rb
|
12
|
+
- lib/kiev/rack/request_logger.rb
|
13
|
+
- lib/kiev/json.rb
|
14
|
+
- test/sidekiq_test.rb
|
15
|
+
Style/GlobalVars:
|
16
|
+
Exclude:
|
17
|
+
- test/helper.rb
|
18
|
+
Style/GuardClause:
|
19
|
+
Exclude:
|
20
|
+
- lib/kiev/logger.rb
|
21
|
+
Style/NestedParenthesizedCalls:
|
22
|
+
Exclude:
|
23
|
+
- spec/lib/kiev/json_spec.rb
|
24
|
+
Style/BlockDelimiters:
|
25
|
+
EnforcedStyle: line_count_based
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.3
|
data/.travis.yml
ADDED
@@ -0,0 +1,27 @@
|
|
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/sidekiq_4.2.gemfile
|
24
|
+
- gemfiles/sinatra_1.4.gemfile
|
25
|
+
- gemfiles/sinatra_2.0.gemfile
|
26
|
+
matrix:
|
27
|
+
fast_finish: true
|
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright 2017 Blacklane
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,461 @@
|
|
1
|
+
# Kiev [![Build Status](https://travis-ci.com/blacklane/kiev.svg?token=j5tcq3Fz9ERKZ2HhzC8T&branch=master)](https://travis-ci.com/blacklane/kiev)
|
2
|
+
|
3
|
+
Kiev is a comprehensive logging library aimed at covering a wide range of frameworks and tools from the Ruby ecosystem:
|
4
|
+
|
5
|
+
- Rails
|
6
|
+
- Sinatra
|
7
|
+
- Rack and other Rack-based frameworks
|
8
|
+
- Sidekiq
|
9
|
+
- Que
|
10
|
+
- Her and other Faraday-based libraries
|
11
|
+
- HTTParty
|
12
|
+
|
13
|
+
The main goal of Kiev is consistent logging across distributed systems, like **tracking HTTP requests across various Ruby micro-services**. Kiev will generate and propagate request IDs and make it easy for you to identify service calls and branching requests, **including background jobs triggered by these requests**.
|
14
|
+
|
15
|
+
Aside from web requests and background jobs, which are tracked out of the box, Kiev makes it easy to append additional information or introduce **custom events**.
|
16
|
+
|
17
|
+
Kiev produces structured logs in the **JSON format**, which are ready to be ingested by ElasticSearch or other similar JSON-driven data stores. It eliminates the need for Logstash in a typical ELK stack.
|
18
|
+
|
19
|
+
In **development mode**, Kiev can print human-readable logs - pretty much like the default Rails logger, but including all the additional information that you've provided via Kiev events.
|
20
|
+
|
21
|
+
## Install
|
22
|
+
|
23
|
+
Add the gem to your `Gemfile`:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
gem "kiev"
|
27
|
+
```
|
28
|
+
|
29
|
+
Don't forget to `bundle install`.
|
30
|
+
|
31
|
+
## Configure
|
32
|
+
|
33
|
+
### Rails
|
34
|
+
|
35
|
+
Place your configuration under `config/initializers/kiev.rb`:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
require "kiev"
|
39
|
+
|
40
|
+
Kiev.configure do |config|
|
41
|
+
config.app = :my_app
|
42
|
+
config.development_mode = Rails.env.development?
|
43
|
+
config.log_path = Rails.root.join("log", "structured.log") unless Rails.env.development? || $stdout.isatty
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
The middleware stack is included automatically via a *Railtie*.
|
48
|
+
|
49
|
+
### Sinatra
|
50
|
+
|
51
|
+
Somewhere in your code, ideally before the server configuration, add the following lines:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
require "kiev"
|
55
|
+
|
56
|
+
Kiev.configure do |config|
|
57
|
+
config.app = :my_app
|
58
|
+
config.log_path = File.join("log", "structured.log")
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
Within your `Sinatra::Base` implementation, include the `Kiev::Rack` module, in order to register the middleware stack:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
require "kiev"
|
66
|
+
require "sinatra/base"
|
67
|
+
|
68
|
+
class MyController < Sinatra::Base
|
69
|
+
include Kiev::Rack
|
70
|
+
|
71
|
+
use SomeOtherMiddleware
|
72
|
+
|
73
|
+
get "/hello" do
|
74
|
+
"world"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
### Rack
|
80
|
+
|
81
|
+
Somewhere in your code, ideally before the server configuration, add the following lines:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
require "kiev"
|
85
|
+
|
86
|
+
Kiev.configure do |config|
|
87
|
+
config.app = :my_app
|
88
|
+
config.log_path = File.join("log", "structured.log")
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
Within your `Rack::Builder` implementation, include the `Kiev::Rack` module, in order to register the middleware stack:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
require "kiev"
|
96
|
+
require "rack"
|
97
|
+
|
98
|
+
app = Rack::Builder.new do
|
99
|
+
include Kiev::Rack
|
100
|
+
|
101
|
+
use SomeOtherMiddleware
|
102
|
+
|
103
|
+
run labmda { |env| [ 200, {}, [ "hello world" ] ] }
|
104
|
+
end
|
105
|
+
|
106
|
+
run(app)
|
107
|
+
```
|
108
|
+
|
109
|
+
### Sidekiq
|
110
|
+
|
111
|
+
Add the following lines to your initializer code:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
Kiev::Sidekiq.enable
|
115
|
+
```
|
116
|
+
|
117
|
+
### Que
|
118
|
+
|
119
|
+
Add the following lines to your initializer code:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
require "kiev/que/job"
|
123
|
+
|
124
|
+
class MyJob < Kiev::Que::Job
|
125
|
+
...
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
### Her
|
130
|
+
|
131
|
+
Add the following lines to your initializer code:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
Her::API.setup(url: "https://api.example.com") do |c|
|
135
|
+
c.use Kiev::HerExt::ClientRequestId
|
136
|
+
# other middleware
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
## Loading only the required parts
|
141
|
+
|
142
|
+
You can load only parts of the gem, if you don't want to use all features:
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
require "kiev/her_ext/client_request_id"
|
146
|
+
```
|
147
|
+
|
148
|
+
## Logging
|
149
|
+
|
150
|
+
### Requests
|
151
|
+
|
152
|
+
For web requests the Kiev middleware will log the following information by default:
|
153
|
+
|
154
|
+
```json
|
155
|
+
{
|
156
|
+
"application":"my_app",
|
157
|
+
"event":"request_finished",
|
158
|
+
"level":"INFO",
|
159
|
+
"timestamp":"2017-01-27T16:11:44.123Z",
|
160
|
+
"host":"localhost",
|
161
|
+
"verb":"GET",
|
162
|
+
"path":"/",
|
163
|
+
"params":"{\"hello\":\"world\",\"password\":\"[FILTERED]\"}",
|
164
|
+
"ip":"127.0.0.1",
|
165
|
+
"request_id":"UUID",
|
166
|
+
"request_depth":0,
|
167
|
+
"route":"RootController#index",
|
168
|
+
"user_agent":"curl/7.50.1",
|
169
|
+
"status":200,
|
170
|
+
"request_duration":62.3773,
|
171
|
+
"body":"See #log_response_body_condition",
|
172
|
+
"error_message": "...",
|
173
|
+
"error_class": "...",
|
174
|
+
"error_backtrace": "...",
|
175
|
+
"tree_path": "ACE",
|
176
|
+
"tree_leaf": true
|
177
|
+
}
|
178
|
+
```
|
179
|
+
|
180
|
+
The `params` attribute will store both query parameters and request body fields (as long as they are parseable). Sensitive fields will be filtered out - see the `#filtered_params` option.
|
181
|
+
|
182
|
+
The `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).
|
183
|
+
|
184
|
+
The `request_depth` represents the position of the current request within a chain of requests. It starts with 0.
|
185
|
+
|
186
|
+
The `route` attribute will be set to either the Rails route (`RootController#index`) or Sinatra route (`/`) or the path, depending on the context.
|
187
|
+
|
188
|
+
The `request_duration` is measured in miliseconds.
|
189
|
+
|
190
|
+
The `body` attribute coresponds to the response body and will be logged depending on the `#log_response_body_condition` option.
|
191
|
+
|
192
|
+
The `tree_path` attribute can be used to follow the branching of requests within a chain of requests. It's a lexicographically sortable string.
|
193
|
+
|
194
|
+
The `tree_leaf` points out that this request is a leaf in the request chain tree structure.
|
195
|
+
|
196
|
+
### Background jobs
|
197
|
+
|
198
|
+
For background jobs, Kiev will log the following information by default:
|
199
|
+
|
200
|
+
```json
|
201
|
+
{
|
202
|
+
"application":"my_app",
|
203
|
+
"event":"job_finished",
|
204
|
+
"level":"INFO",
|
205
|
+
"timestamp":"2017-01-27T16:11:44.123Z",
|
206
|
+
"job_name":"name",
|
207
|
+
"params": "...",
|
208
|
+
"jid":123,
|
209
|
+
"request_id":"UUID",
|
210
|
+
"request_depth":0,
|
211
|
+
"request_duration":0.000623773,
|
212
|
+
"error_message": "...",
|
213
|
+
"error_class": "...",
|
214
|
+
"error_backtrace": "...",
|
215
|
+
"tree_path": "BDF",
|
216
|
+
"tree_leaf": true
|
217
|
+
}
|
218
|
+
```
|
219
|
+
|
220
|
+
### Appending data to the request log entry
|
221
|
+
|
222
|
+
You can also append **arbitrary data** to the request log by calling:
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
# Append structured data (will be merged)
|
226
|
+
Kiev.payload(first_name: "john", last_name: "smith")
|
227
|
+
|
228
|
+
# Same thing
|
229
|
+
Kiev[:first_name] = "john"
|
230
|
+
Kiev[:last_name] = "smith"
|
231
|
+
```
|
232
|
+
|
233
|
+
### Other events
|
234
|
+
|
235
|
+
Kiev allows you to log custom events as well.
|
236
|
+
|
237
|
+
The recommended way to do this is by using the `#event` method:
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
# Log event without any data
|
241
|
+
Kiev.event(:my_event)
|
242
|
+
|
243
|
+
# Log structured data (will be merged)
|
244
|
+
Kiev.event(:my_event, { some_array: [1, 2, 3] })
|
245
|
+
|
246
|
+
# Log other data types (will be available under the `message` key)
|
247
|
+
Kiev.event(:my_event, "hello world")
|
248
|
+
```
|
249
|
+
|
250
|
+
However, `Kiev.logger` implements the Ruby `Logger` class, so all the other methods are available as well:
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
Kiev.logger.info("hello world")
|
254
|
+
Kiev.logger.debug({ first_name: "john", last_name: "smith" })
|
255
|
+
```
|
256
|
+
|
257
|
+
Note that, even when logging custom events, Kiev **will try to append request information** to the entries: the HTTP `verb` and `path` for web request or `job_name` and `jid` for background jobs. The payload, however, will be logged only for the `request_finished` or `job_finished` events. If you want to add a payload to a custom event, use the second argument of the `event` method.
|
258
|
+
|
259
|
+
## Advanced configuration
|
260
|
+
|
261
|
+
### development_mode
|
262
|
+
|
263
|
+
Kiev offers human-readable logging for development purposes. You can enable it via the `development_mode` option:
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
Kiev.configure do |config|
|
267
|
+
config.development_mode = Rails.env.development?
|
268
|
+
end
|
269
|
+
```
|
270
|
+
|
271
|
+
### filtered_params
|
272
|
+
|
273
|
+
By default, Kiev filters out the values for the following parameters:
|
274
|
+
|
275
|
+
- client_secret
|
276
|
+
- token
|
277
|
+
- password,
|
278
|
+
- password_confirmation
|
279
|
+
- old_password
|
280
|
+
- credit_card_number
|
281
|
+
- credit_card_cvv
|
282
|
+
|
283
|
+
You can override this behaviour via the `filtered_params` option:
|
284
|
+
|
285
|
+
```ruby
|
286
|
+
Kiev.configure do |config|
|
287
|
+
config.filtered_params = %w(email first_name last_name)
|
288
|
+
end
|
289
|
+
```
|
290
|
+
|
291
|
+
### ignored_params
|
292
|
+
|
293
|
+
By default, Kiev ignores the following parameters:
|
294
|
+
|
295
|
+
- controller
|
296
|
+
- action
|
297
|
+
- format
|
298
|
+
- authenticity_token
|
299
|
+
- utf8
|
300
|
+
|
301
|
+
You can override this behaviour via the `ignored_params` option:
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
Kiev.configure do |config|
|
305
|
+
config.ignored_params = %w(some_field some_other_field)
|
306
|
+
end
|
307
|
+
```
|
308
|
+
|
309
|
+
### log_request_condition
|
310
|
+
|
311
|
+
By default, Kiev doesn't log requests to `/ping` or `/health` or requests to assets.
|
312
|
+
|
313
|
+
You can override this behaviour via the `log_request_condition` option, which should be a `proc` returning a `boolean`:
|
314
|
+
|
315
|
+
```ruby
|
316
|
+
Kiev.configure do |config|
|
317
|
+
config.log_request_condition = proc do |request, response|
|
318
|
+
!%r{(^(/ping|/health))|(\.(js|css|png|jpg|gif)$)}.match(request.path)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
```
|
322
|
+
|
323
|
+
### log_request_error_condition
|
324
|
+
|
325
|
+
Kiev logs Ruby exceptions. By default, it won't log the exceptions produced by 404s.
|
326
|
+
|
327
|
+
You can override this behaviour via the `log_request_error_condition` option, which should be a `proc` returning a `boolean`:
|
328
|
+
|
329
|
+
```ruby
|
330
|
+
Kiev.configure do |config|
|
331
|
+
config.log_request_error_condition = proc do |request, response|
|
332
|
+
response.status != 404
|
333
|
+
end
|
334
|
+
end
|
335
|
+
```
|
336
|
+
|
337
|
+
### log_response_body_condition
|
338
|
+
|
339
|
+
Kiev can log the response body. By default, it will only log the response body when the status code is in the 4xx range and the content type is JSON or XML.
|
340
|
+
|
341
|
+
You can override this behaviour via the `log_response_body_condition` option, which should be a `proc` returning a `boolean`:
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
Kiev.configure do |config|
|
345
|
+
config.log_response_body_condition = proc do |request, response|
|
346
|
+
response.status >= 400 && response.status < 500 && response.content_type =~ /(json|xml)/
|
347
|
+
end
|
348
|
+
end
|
349
|
+
```
|
350
|
+
|
351
|
+
### persistent_log_fields
|
352
|
+
|
353
|
+
If you need to log some data for every event in the session (e.g. the user ID), you can do this via the `persistent_log_fields` option.
|
354
|
+
|
355
|
+
```ruby
|
356
|
+
Kiev.configure do |config|
|
357
|
+
config.persistent_log_fields = [:user_id]
|
358
|
+
end
|
359
|
+
|
360
|
+
# Somewhere in application
|
361
|
+
before do
|
362
|
+
Kiev[:user_id] = current_user.id
|
363
|
+
end
|
364
|
+
|
365
|
+
get "/" do
|
366
|
+
"hello world"
|
367
|
+
end
|
368
|
+
```
|
369
|
+
|
370
|
+
## nginx
|
371
|
+
|
372
|
+
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:
|
373
|
+
|
374
|
+
```
|
375
|
+
log_format kiev '{"application":"app_name", "event":"request_finished",'
|
376
|
+
'"timestamp":"$time_iso8601", "request_id":"$http_x_request_id",'
|
377
|
+
'"user_agent":"$http_user_agent", "status":$status,'
|
378
|
+
'"request_duration_seconds":$request_time, "host":"$host",'
|
379
|
+
'"verb":"$request_method", "path":"$request_uri", "tree_path": "$http_x_tree_path"}';
|
380
|
+
|
381
|
+
log_format simple_log '$remote_addr - $remote_user [$time_local] '
|
382
|
+
'"$request" $status $bytes_sent '
|
383
|
+
'"$http_referer" "$http_user_agent"';
|
384
|
+
|
385
|
+
map $status $not_loggable {
|
386
|
+
~(499) 0;
|
387
|
+
default 1;
|
388
|
+
}
|
389
|
+
|
390
|
+
map $status $loggable {
|
391
|
+
~(499) 1;
|
392
|
+
default 0;
|
393
|
+
}
|
394
|
+
|
395
|
+
server {
|
396
|
+
access_log /var/log/nginx/access.kiev.log kiev if=$loggable;
|
397
|
+
access_log /var/log/nginx/access.log simple_log if=$not_loggable;
|
398
|
+
|
399
|
+
location = /50x.html {
|
400
|
+
access_log /var/log/nginx/access.kiev.log kiev;
|
401
|
+
}
|
402
|
+
}
|
403
|
+
```
|
404
|
+
|
405
|
+
If you'd like to measure nginx queue latency, add the following to your nginx configuration:
|
406
|
+
|
407
|
+
```
|
408
|
+
server {
|
409
|
+
...
|
410
|
+
proxy_set_header X-Request-Start "${msec}";
|
411
|
+
...
|
412
|
+
}
|
413
|
+
```
|
414
|
+
|
415
|
+
Other libs/technologies using `X-Request-Start` are [rack-timeout](https://github.com/heroku/rack-timeout) and [NewRelic](https://docs.newrelic.com/docs/apm/applications-menu/features/request-queue-server-configuration-examples). There's no [support for ELB](https://forums.aws.amazon.com/message.jspa?messageID=396283) :(
|
416
|
+
|
417
|
+
## Logstash, Logrotate, Filebeat
|
418
|
+
|
419
|
+
Kiev does not provide facilities to log directly to ElasticSearch. This is done for simplicity. Instead we recommend using [Filebeat](https://www.elastic.co/products/beats/filebeat) to deliver logs to ElasticSearch.
|
420
|
+
|
421
|
+
When storing logs on disk, we recommend using Logrotate in truncate mode.
|
422
|
+
|
423
|
+
You can use [jq](https://stedolan.github.io/jq/) to traverse JSON log files, when you're not running Kiev in *development mode*.
|
424
|
+
|
425
|
+
## Alternatives
|
426
|
+
|
427
|
+
### Logging
|
428
|
+
|
429
|
+
- [semantic_logger](http://rocketjob.github.io/semantic_logger/)
|
430
|
+
- [lograge](https://github.com/roidrage/lograge)
|
431
|
+
- [logging](https://github.com/TwP/logging)
|
432
|
+
|
433
|
+
### Request-Id
|
434
|
+
|
435
|
+
- [Pliny::Middleware::RequestID](https://github.com/interagent/pliny/blob/master/lib/pliny/middleware/request_id.rb)
|
436
|
+
- [ActionDispatch::RequestId](http://api.rubyonrails.org/classes/ActionDispatch/RequestId.html)
|
437
|
+
- [request_id](https://github.com/remind101/request_id)
|
438
|
+
|
439
|
+
## Development
|
440
|
+
|
441
|
+
Pull the code:
|
442
|
+
|
443
|
+
```
|
444
|
+
git clone git@github.com:blacklane/kiev.git
|
445
|
+
```
|
446
|
+
|
447
|
+
Run tests:
|
448
|
+
|
449
|
+
```sh
|
450
|
+
bundle exec rake
|
451
|
+
```
|
452
|
+
|
453
|
+
Run tests for different rubies, frameworks and framework versions:
|
454
|
+
|
455
|
+
```sh
|
456
|
+
# Create a Postgres test database for Que
|
457
|
+
createdb que_test
|
458
|
+
|
459
|
+
# Run the tests (replace myuser with your username)
|
460
|
+
DATABASE_URL=postgres://myuser:@localhost/que_test bundle exec wwtd
|
461
|
+
```
|