logcraft 2.0.0 → 2.1
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 +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +36 -20
- data/lib/logcraft/log_layout.rb +6 -2
- data/lib/logcraft/rails/request_logger.rb +11 -19
- data/lib/logcraft/railtie.rb +1 -1
- data/lib/logcraft/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e77bb5b3fd57a71991d2d62ad60b405d3aec4c204e9aca74d5b8aad73938fbce
|
4
|
+
data.tar.gz: ef7f87bcb528b05c9d2a0499a50d00184a949f1d018091fe25e7b5fcacea535d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eae1d4bfb0b539d0850fb306562244e73da2ff4a1745bdd378b9d10cb00dbedfa87938209327a8188bb9ca775827ba09ba1091f2a7a097417d85378cecabe2d0
|
7
|
+
data.tar.gz: beb08ae116067d4feed050d8049cbbf97579fa00e905e669709ca0eb433ebfd1a13bef5dbdfbbed5ac85937704f5aa0b5671038f818a45165f29b7d51379393a
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [2.1] - 2023-06-13
|
8
|
+
### Added
|
9
|
+
- Added support for custom log formatters.
|
10
|
+
|
11
|
+
## [2.0.1] - 2022-10-07
|
12
|
+
### Fixed
|
13
|
+
- Fixed a bug where request log tracing didn't work with the DataDog integration. Had to move up logging
|
14
|
+
the request to the point where the middleware is done processing instead of where we originally had it;
|
15
|
+
at the time when the response body was closed. We lost some precision in terms of measuring request duration
|
16
|
+
but some context (e.g. DataDog active trace) would not be available otherwise.
|
17
|
+
|
7
18
|
## [2.0.0] - 2022-07-31
|
8
19
|
### Added
|
9
20
|
- Added the option to change the log level or suppress logging of unhandled errors which are, in fact,
|
data/README.md
CHANGED
@@ -27,17 +27,17 @@ structured logging solution.
|
|
27
27
|
## Table of contents
|
28
28
|
|
29
29
|
* [Installation](#installation)
|
30
|
-
|
31
|
-
|
30
|
+
* [Rails](#rails)
|
31
|
+
* [Non-Rails applications](#non-rails-applications)
|
32
32
|
* [Usage](#usage)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
* [Structured logging](#structured-logging)
|
34
|
+
* [Adding context information to log messages](#adding-context-information-to-log-messages)
|
35
|
+
* [Rails logging](#rails-logging)
|
36
|
+
* [The log level](#the-log-level)
|
37
|
+
* [JSON serialization](#json-serialization)
|
38
38
|
* [Configuration options](#configuration-options)
|
39
|
-
|
40
|
-
|
39
|
+
* [Rails configuration](#rails-configuration)
|
40
|
+
* [Non-Rails configuration](#non-rails-configuration)
|
41
41
|
* [Integration with DataDog](#integration-with-datadog)
|
42
42
|
* [RSpec support](#rspec-support)
|
43
43
|
* [Development](#development)
|
@@ -190,7 +190,7 @@ In more detail:
|
|
190
190
|
|
191
191
|
* The `Rails.logger` is set up to be a Logcraft logger with the name `Application`.
|
192
192
|
* Rails's default logging of uncaught errors is modified and instead of spreading the error message across several
|
193
|
-
lines, Logcraft
|
193
|
+
lines, Logcraft logs every uncaught error in 1 line (per error), including the error's name and context (stack trace,
|
194
194
|
etc.).
|
195
195
|
* Most importantly, Rails's default request logging - which logs several lines per event during the processing of an
|
196
196
|
action - is replaced by Logcraft's own access log middleware. The end result is an access log that
|
@@ -215,7 +215,7 @@ Processing by PagesController#welcome as HTML
|
|
215
215
|
Completed 200 OK in 31ms (Views: 27.3ms | ActiveRecord: 0.0ms)
|
216
216
|
|
217
217
|
With Logcraft:
|
218
|
-
{"timestamp":"2022-06-26T18:07:08.103+02:00","level":"INFO","logger":"AccessLog","hostname":"MacbookPro.local","pid":80908,"request_id":"9a43631b-284c-4677-9d08-9c1cc5c7d3a7","message":"GET /welcome?subsession_id=34ea8596f9764f475f81158667bc2654 - 200 (OK)","remote_ip":"127.0.0.1","method":"GET","path":"/welcome?subsession_id=34ea8596f9764f475f81158667bc2654","params":{"subsession_id":"34ea8596f9764f475f81158667bc2654","controller":"pages","action":"welcome"},"response_status_code":200,"duration":
|
218
|
+
{"timestamp":"2022-06-26T18:07:08.103+02:00","level":"INFO","logger":"AccessLog","hostname":"MacbookPro.local","pid":80908,"request_id":"9a43631b-284c-4677-9d08-9c1cc5c7d3a7","message":"GET /welcome?subsession_id=34ea8596f9764f475f81158667bc2654 - 200 (OK)","remote_ip":"127.0.0.1","method":"GET","path":"/welcome?subsession_id=34ea8596f9764f475f81158667bc2654","params":{"subsession_id":"34ea8596f9764f475f81158667bc2654","controller":"pages","action":"welcome"},"response_status_code":200,"duration":31,"duration_sec":0.031}
|
219
219
|
|
220
220
|
Formatted for readability:
|
221
221
|
{
|
@@ -235,8 +235,8 @@ Formatted for readability:
|
|
235
235
|
"action": "welcome"
|
236
236
|
},
|
237
237
|
"response_status_code": 200,
|
238
|
-
"duration":
|
239
|
-
"duration_sec": 0.
|
238
|
+
"duration": 31,
|
239
|
+
"duration_sec": 0.031
|
240
240
|
}
|
241
241
|
```
|
242
242
|
|
@@ -274,6 +274,18 @@ ActiveSupport::JSON.encode test: 'foo > bar'
|
|
274
274
|
I highly recommend using the [Oj](https://github.com/ohler55/oj) gem which - if present - will be automatically
|
275
275
|
picked up by Logcraft, as it is significantly faster and will serialize your messages as you would expect.
|
276
276
|
|
277
|
+
In a nutshell:
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
# With default ActiveSupport serialization
|
281
|
+
Rails.logger.info 'foo > bar'
|
282
|
+
#=> {...,"message":"foo \u003e bar"}
|
283
|
+
|
284
|
+
# With Oj
|
285
|
+
Rails.logger.info 'foo > bar'
|
286
|
+
#=> {...,"message":"foo > bar"}
|
287
|
+
```
|
288
|
+
|
277
289
|
## Configuration options
|
278
290
|
|
279
291
|
### Rails configuration
|
@@ -282,8 +294,9 @@ Logcraft provides the following configuration options for Rails:
|
|
282
294
|
|
283
295
|
| Option | Default value | Description |
|
284
296
|
|-------------------------------------------------------|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
285
|
-
| logcraft.global_context | `{}`
|
286
|
-
| logcraft.layout_options
|
297
|
+
| logcraft.global_context | `{} \| lambda \| proc` | A global log context that will be included in every log message. Must be either a Hash or a lambda/proc returning a Hash. |
|
298
|
+
| logcraft.layout_options.formatter | `lambda \| proc` | A custom formatter for the entire log event. Must return a single string (see examples for usage). |
|
299
|
+
| logcraft.layout_options.level_formatter | `lambda \| proc` | A custom formatter for the log level specifically (see examples for usage). |
|
287
300
|
| logcraft.access_log.logger_name | `'AccessLog'` | The name of the logger emitting access log messages. |
|
288
301
|
| logcraft.access_log.exclude_paths | `[]` | A list of paths (array of strings or RegExps) not to include in the access log. |
|
289
302
|
| logcraft.access_log.log_only_whitelisted_params | `false` | If `true`, the access log will only contain whitelisted parameters. |
|
@@ -294,7 +307,7 @@ Logcraft provides the following configuration options for Rails:
|
|
294
307
|
Examples:
|
295
308
|
|
296
309
|
```ruby
|
297
|
-
# Use these options in your Rails configuration files (e.g. application.rb)
|
310
|
+
# Use these options in your Rails configuration files (e.g. config/application.rb or config/environments/*.rb)
|
298
311
|
|
299
312
|
# Set up a global context you want to see in every log message
|
300
313
|
config.logcraft.global_context = -> do
|
@@ -304,10 +317,13 @@ config.logcraft.global_context = -> do
|
|
304
317
|
}
|
305
318
|
end
|
306
319
|
|
320
|
+
# Set up a custom log formatter (e.g. output logs in YAML format in the development environment - config/environments/development.rb)
|
321
|
+
config.logcraft.layout_options.formatter = ->(event) { YAML.dump event }
|
322
|
+
# or just make the JSON more readable
|
323
|
+
config.logcraft.layout_options.formatter = ->(event) { JSON.pretty_generate(event) + "\n----------------\n" }
|
324
|
+
|
307
325
|
# Set up a custom log level formatter (e.g. Ougai-like numbers)
|
308
|
-
config.logcraft.layout_options = {
|
309
|
-
level_formatter: ->(level_number) { (level_number + 2) * 10 }
|
310
|
-
}
|
326
|
+
config.logcraft.layout_options.level_formatter = ->(level_number) { (level_number + 2) * 10 }
|
311
327
|
Rails.logger.error('Boom!')
|
312
328
|
# => {...,"level":50,"message":"Boom!"}
|
313
329
|
|
@@ -345,7 +361,7 @@ config.logcraft.global_context = -> do
|
|
345
361
|
service: correlation.service.to_s,
|
346
362
|
version: correlation.version.to_s
|
347
363
|
},
|
348
|
-
ddsource:
|
364
|
+
ddsource: 'ruby'
|
349
365
|
}
|
350
366
|
end
|
351
367
|
```
|
data/lib/logcraft/log_layout.rb
CHANGED
@@ -4,16 +4,20 @@ require 'time'
|
|
4
4
|
|
5
5
|
module Logcraft
|
6
6
|
class LogLayout < Logging::Layout
|
7
|
+
JSON_FORMATTER = ->(event) { MultiJson.dump(event) + "\n" }.freeze
|
8
|
+
LOGGING_LEVEL_FORMATTER = ->(level) { Logging::LNAMES[level] }.freeze
|
9
|
+
|
7
10
|
def initialize(global_context = {}, options = {})
|
8
11
|
@global_context = global_context
|
9
|
-
@
|
12
|
+
@formatter = options.fetch :formatter, JSON_FORMATTER
|
13
|
+
@level_formatter = options.fetch :level_formatter, LOGGING_LEVEL_FORMATTER
|
10
14
|
end
|
11
15
|
|
12
16
|
def format(event)
|
13
17
|
log_entry = background_of(event).merge evaluated_global_context,
|
14
18
|
dynamic_log_context,
|
15
19
|
message_from(event.data)
|
16
|
-
|
20
|
+
@formatter.call log_entry
|
17
21
|
end
|
18
22
|
|
19
23
|
private
|
@@ -14,13 +14,9 @@ module Logcraft
|
|
14
14
|
request = ActionDispatch::Request.new env
|
15
15
|
|
16
16
|
instrumentation_start request
|
17
|
-
|
18
17
|
status, headers, body = @app.call env
|
19
|
-
|
20
|
-
|
21
|
-
instrumentation_finish request
|
22
|
-
log_request request, status, start_time, request_id
|
23
|
-
end
|
18
|
+
body = ::Rack::BodyProxy.new(body) { instrumentation_finish request }
|
19
|
+
log_request request, status, start_time
|
24
20
|
|
25
21
|
[status, headers, body]
|
26
22
|
rescue Exception => ex
|
@@ -47,22 +43,18 @@ module Logcraft
|
|
47
43
|
instrumenter.finish 'request.action_dispatch', request: request
|
48
44
|
end
|
49
45
|
|
50
|
-
def log_request(request, status, start_time
|
46
|
+
def log_request(request, status, start_time)
|
51
47
|
return if path_ignored? request
|
52
48
|
|
53
49
|
end_time = current_time_in_milliseconds
|
54
|
-
message
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
duration_sec: (end_time - start_time) / 1000.0
|
63
|
-
}
|
64
|
-
message[:request_id] = request_id if request_id
|
65
|
-
@logger.info message
|
50
|
+
@logger.info message: '%s %s - %i (%s)' % [request.method, request.filtered_path, status, Rack::Utils::HTTP_STATUS_CODES[status]],
|
51
|
+
remote_ip: request.remote_ip,
|
52
|
+
method: request.method,
|
53
|
+
path: request.filtered_path,
|
54
|
+
params: params_to_log(request),
|
55
|
+
response_status_code: status,
|
56
|
+
duration: end_time - start_time,
|
57
|
+
duration_sec: (end_time - start_time) / 1000.0
|
66
58
|
end
|
67
59
|
|
68
60
|
def path_ignored?(request)
|
data/lib/logcraft/railtie.rb
CHANGED
@@ -6,7 +6,7 @@ module Logcraft
|
|
6
6
|
class Railtie < ::Rails::Railtie
|
7
7
|
config.logcraft = ActiveSupport::OrderedOptions.new
|
8
8
|
config.logcraft.global_context = {}
|
9
|
-
config.logcraft.layout_options =
|
9
|
+
config.logcraft.layout_options = ActiveSupport::OrderedOptions.new
|
10
10
|
|
11
11
|
config.logcraft.access_log = ActiveSupport::OrderedOptions.new
|
12
12
|
config.logcraft.access_log.logger_name = 'AccessLog'
|
data/lib/logcraft/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logcraft
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: '2.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zoltan Ormandi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logging
|