json_tagged_logger 0.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/README.md +99 -49
- data/lib/json_tagged_logger/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d6a91dae71312da17de8ad46580f46a3a5d7c6c20d8e1444107734cb7775c49
|
4
|
+
data.tar.gz: 159b9a61bf557b8324c2d1c1f3dd03e4fc2f37625996046e7de29fd2b2f05a0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43d1c8b1d1905f04271bdb538618e4b24d6b1eefc1d2864d01c38949ae5b1f6dcfccc0af60254136667cef7dd345becf52cf65169030818f911d4d56c7abdf4f
|
7
|
+
data.tar.gz: 06fd82f28251e33f49a31273d415f76d4d9a5b1fc085b05a707722b3be9046f96148731f64324c9a44f6cbc86c2a3769d44652c893713f7fd4553173e35df1d9
|
data/README.md
CHANGED
@@ -1,89 +1,139 @@
|
|
1
1
|
# JsonTaggedLogger
|
2
2
|
|
3
|
-
JsonTaggedLogger
|
3
|
+
`JsonTaggedLogger` works in conjunction with [`ActiveSupport::TaggedLogging`](https://api.rubyonrails.org/classes/ActiveSupport/TaggedLogging.html) and (optionally) [Lograge](https://github.com/roidrage/lograge) to produce JSON-formatted log output. By itself, `ActiveSupport::TaggedLogging` supports simple tagging. With `JsonTaggedLogger`, you can compose key/value pairs, simple tags, and the log message itself into a single JSON document for easy consumption and parsing in log aggregators.
|
4
4
|
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
Given the following configuration,
|
5
8
|
|
6
9
|
```ruby
|
7
10
|
# Gemfile
|
8
11
|
gem 'json_tagged_logger'
|
12
|
+
gem 'lograge' # since you probably want all your request logs in JSON
|
9
13
|
|
10
14
|
# config/environments/production.rb
|
11
15
|
Rails.application.configure do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
# …
|
17
|
+
config.log_tags = JsonTaggedLogger::LogTagsConfig.generate(
|
18
|
+
:request_id,
|
19
|
+
:host,
|
20
|
+
->(request) { { my_param: request.query_parameters["my_param"] }.to_json },
|
21
|
+
JsonTaggedLogger::TagFromSession.get(:user_id),
|
22
|
+
JsonTaggedLogger::TagFromHeaders.get(:my_custom_header, "X-Custom-Header"),
|
23
|
+
)
|
24
|
+
|
25
|
+
logger = ActiveSupport::Logger.new(STDOUT)
|
26
|
+
config.logger = JsonTaggedLogger::Logger.new(logger)
|
27
|
+
|
28
|
+
config.lograge.enabled = true
|
29
|
+
config.lograge.formatter = Lograge::Formatters::Json.new
|
30
|
+
# …
|
17
31
|
end
|
18
|
-
|
19
32
|
```
|
20
33
|
|
21
|
-
|
22
|
-
## Why?
|
23
|
-
|
24
|
-
On its own, ActiveSupport::TaggedLogging adds individual tags wrapped in squre brackets at the start of each line of log output, like so
|
34
|
+
A request like
|
25
35
|
|
26
36
|
```
|
27
|
-
|
37
|
+
curl -H "X-Custom-Header: some header value" 'http://127.0.0.1:3000/?my_param=param%20value'
|
28
38
|
```
|
29
39
|
|
30
|
-
|
31
|
-
|
32
|
-
## How does it work?
|
40
|
+
will get you something like
|
33
41
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
```json
|
43
|
+
{
|
44
|
+
"level": "INFO",
|
45
|
+
"request_id": "914f6104-538d-4ddc-beef-37bfe06ca1c7",
|
46
|
+
"host": "127.0.0.1",
|
47
|
+
"my_param": "param value",
|
48
|
+
"user_id": "99",
|
49
|
+
"my_custom_header": "some header value",
|
50
|
+
"method": "GET",
|
51
|
+
"path": "/",
|
52
|
+
"format": "*/*",
|
53
|
+
"controller": "SessionsController",
|
54
|
+
"action": "new",
|
55
|
+
"status": 302,
|
56
|
+
"duration": 0.51,
|
57
|
+
"view": 0,
|
58
|
+
"db": 0,
|
59
|
+
"location": "http://127.0.0.1:3000/profile"
|
60
|
+
}
|
38
61
|
```
|
39
62
|
|
40
|
-
|
63
|
+
[Note: I've pretty-printed the output in these examples for easier reading. The actual log output will be on a single line without extra whitespace.]
|
41
64
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
65
|
+
Importantly, if the controller action (or any code it calls along the way) has an explicit call to `Rails.logger.tagged("TAG").info("tagged log message")`, you'll get the same key/value tags (`request_id`, `host`, `my_param`, &c.) in the JSON document along with a `tags` key:
|
66
|
+
|
67
|
+
```json
|
68
|
+
{
|
69
|
+
"level": "INFO",
|
70
|
+
"request_id": "914f6104-538d-4ddc-beef-37bfe06ca1c7",
|
71
|
+
"host": "127.0.0.1",
|
72
|
+
"my_param": "param value",
|
73
|
+
"user_id": "99",
|
74
|
+
"my_custom_header": "some header value",
|
75
|
+
"tags": [
|
76
|
+
"TAG"
|
77
|
+
],
|
78
|
+
"msg": "tagged log message"
|
79
|
+
}
|
47
80
|
```
|
48
81
|
|
49
|
-
|
82
|
+
If you have nested calls to the tagged logger, like
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
Rails.logger.tagged("TAG") do
|
86
|
+
Rails.logger.tagged("NESTED").info("nested tagged log message")
|
87
|
+
end
|
50
88
|
|
51
|
-
```
|
52
|
-
[{"request_id":"c31c3658-5b76-40cd-b583-d0fcbdee0710"}] [{"host":"127.0.0.1"}] log message
|
53
89
|
```
|
54
90
|
|
55
|
-
|
91
|
+
those will be added to the `tags` key in the JSON document
|
56
92
|
|
57
93
|
```json
|
58
|
-
{
|
94
|
+
{
|
95
|
+
"level": "INFO",
|
96
|
+
"request_id": "914f6104-538d-4ddc-beef-37bfe06ca1c7",
|
97
|
+
"host": "127.0.0.1",
|
98
|
+
"my_param": "param value",
|
99
|
+
"user_id": "99",
|
100
|
+
"my_custom_header": "some header value",
|
101
|
+
"tags": [
|
102
|
+
"TAG",
|
103
|
+
"NESTED"
|
104
|
+
],
|
105
|
+
"msg": "nested tagged log message"
|
106
|
+
}
|
59
107
|
```
|
60
108
|
|
61
|
-
|
109
|
+
## Why?
|
62
110
|
|
63
|
-
|
111
|
+
On its own, `ActiveSupport::TaggedLogging` adds individual tags wrapped in squre brackets at the start of each line of log output. A configuration like
|
64
112
|
|
65
113
|
```ruby
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
|
76
|
-
def self.build_user_info_from_session(request)
|
77
|
-
# left as an exercise for the reader
|
78
|
-
end
|
114
|
+
Rails.application.configure do
|
115
|
+
# …
|
116
|
+
config.log_tags = [ :request_id, :host, ->(request) { request.query_parameters["my_param"] } ]
|
117
|
+
logger = ActiveSupport::Logger.new(STDOUT)
|
118
|
+
config.logger = ActiveSupport::TaggedLogging.new(logger)
|
119
|
+
# …
|
79
120
|
end
|
80
|
-
|
81
|
-
Rails.application.config.log_tags = [ :request_id, :host, UserInfoLogTag.user_info ]
|
82
121
|
```
|
83
122
|
|
84
|
-
|
123
|
+
will get you logs like
|
85
124
|
|
86
125
|
```
|
87
|
-
|
126
|
+
[22a03298-5fd9-4b28-bbe2-1d4c0d7f74f0] [127.0.0.1] [param value] Started GET "/?my_param=param%20value" for 127.0.0.1 at 2023-01-15 00:13:21 -0500
|
127
|
+
[22a03298-5fd9-4b28-bbe2-1d4c0d7f74f0] [127.0.0.1] [param value] Processing by SessionsController#new as */*
|
128
|
+
[22a03298-5fd9-4b28-bbe2-1d4c0d7f74f0] [127.0.0.1] [param value] Parameters: {"my_param"=>"param value"}
|
129
|
+
[22a03298-5fd9-4b28-bbe2-1d4c0d7f74f0] [127.0.0.1] [param value] [TAG] [NESTED] nested tagged log message
|
130
|
+
[22a03298-5fd9-4b28-bbe2-1d4c0d7f74f0] [127.0.0.1] [param value] Redirected to http://127.0.0.1:3000/sign_in
|
131
|
+
[22a03298-5fd9-4b28-bbe2-1d4c0d7f74f0] [127.0.0.1] [param value] Completed 302 Found in 1ms (ActiveRecord: 0.0ms | Allocations: 1070)
|
88
132
|
```
|
89
133
|
|
134
|
+
This is fine as far as it goes, but if you use tagged logging with something like [Lograge](https://github.com/roidrage/lograge) to format your request logs as JSON, the list of square-bracketed tags will still just be prepended to the log line, followed by the JSON. Also, any calls to `Rails.logger.tagged` will be logged as plain text:
|
135
|
+
|
136
|
+
```
|
137
|
+
[d4fac896-f916-48d7-9d32-d35a39cfb7d8] [127.0.0.1] [param value] [TAG] [NESTED] nested tagged log message
|
138
|
+
[d4fac896-f916-48d7-9d32-d35a39cfb7d8] [127.0.0.1] [param value] {"method":"GET","path":"/","format":"*/*","controller":"SessionsController","action":"new","status":302,"duration":1.2,"view":0.0,"db":0.0,"location":"http://127.0.0.1:3000/sign_in"}
|
139
|
+
```
|