json_tagged_logger 0.2.0 → 0.2.1

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: 3ddcb4231cfc04738123f81259ad35a28fe118f920dd5ab256f24b8edd76d4ac
4
- data.tar.gz: b44b6ee19cd6e763e9065aaa919145217025dcdc72408b38d577d4630017eb7e
3
+ metadata.gz: 5d6a91dae71312da17de8ad46580f46a3a5d7c6c20d8e1444107734cb7775c49
4
+ data.tar.gz: 159b9a61bf557b8324c2d1c1f3dd03e4fc2f37625996046e7de29fd2b2f05a0f
5
5
  SHA512:
6
- metadata.gz: 8183f8c49929f51528b940e8111a68cc66762cd85d058f40fc0b5af21797e92439967442232dee6db8ce0937571b749a09cfc891f0cbc2f74f407648b6d4097d
7
- data.tar.gz: d81145bcdee2da86974f5c234aed2e033b63da4a2a80d1492ffa1f749a8cbd44b2e0d9c35e1b3b66f628adbfadbc68302072545cf341cd79cf23c30652d24285
6
+ metadata.gz: 43d1c8b1d1905f04271bdb538618e4b24d6b1eefc1d2864d01c38949ae5b1f6dcfccc0af60254136667cef7dd345becf52cf65169030818f911d4d56c7abdf4f
7
+ data.tar.gz: 06fd82f28251e33f49a31273d415f76d4d9a5b1fc085b05a707722b3be9046f96148731f64324c9a44f6cbc86c2a3769d44652c893713f7fd4553173e35df1d9
data/README.md CHANGED
@@ -1,89 +1,139 @@
1
1
  # JsonTaggedLogger
2
2
 
3
- JsonTaggedLogger provides a log formatter that works in conjunction with ActiveSupport::TaggedLogging to product JSON-formatted log output.
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
- config.log_tags = JsonTaggedLogger::LogTagsConfig.generate(:request_id, :host, ->(request) { { example: "proc" }.to_json })
14
- logger = ActiveSupport::Logger.new(STDOUT)
15
- config.logger = JsonTaggedLogger::Logger.new(logger)
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
- [tag1] [tag2] : Foo bar
37
+ curl -H "X-Custom-Header: some header value" 'http://127.0.0.1:3000/?my_param=param%20value'
28
38
  ```
29
39
 
30
- This is fine as far as it goes, but if you wish to use tagged logging with something like [Lograge](https://github.com/roidrage/lograge) to format your logs as JSON, there's no good way to get the tags into that json output, specially if any of your tags are generated by procs.
31
-
32
- ## How does it work?
40
+ will get you something like
33
41
 
34
- First, JsonTaggedLogger::LogTags helps you generate an array lof log tags suitable for passing to Rails.application.config.log_tags to produce JSON logs. For example, given
35
-
36
- ```
37
- Rails.application.config.log_tags = JsonTaggedLogger::LogTags.generate_config(:request_id, :host)
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
- ActiveSupport::TaggedLogging will see the following log tags
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
- -> (request) { { request_id: request.send(:request_id) }.to_json },
45
- -> (request) { { host: request.send(:host) }.to_json }
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
- Why is this an improvement over `Rails.application.config.log_tags = [:request_id, :host]`? Well, with the JsonTaggedLogger version, your logs will now contain
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
- which `JsonTaggedLogger::Formatter` will turn into
91
+ those will be added to the `tags` key in the JSON document
56
92
 
57
93
  ```json
58
- {"request_id":"c31c3658-5b76-40cd-b583-d0fcbdee0710","host":"127.0.0.1","msg":"log message"}
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
- Lovely, eh?
109
+ ## Why?
62
110
 
63
- The real advantage comes when you have more complicated procs that generage your log tags. So long as your proc produces a JSON string, `JsonTaggedLogger::Formatter` will be able to extract it from the tag and add it to the log hash.
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
- class UserInfoLogTag
67
- def self.user_info
68
- lambda do |request|
69
- user_info = build_user_info_from_session(request) # build user info from request by inspecting session, etc
70
- { user_info: user_info }.to_json
71
- end
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
- That will get you
123
+ will get you logs like
85
124
 
86
125
  ```
87
- {"request_id":"c31c3658-5b76-40cd-b583-d0fcbdee0710","host":"127.0.0.1","user_info":{"user_id":"1234","user_email":"user@example.com"},"msg":"log message"}
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
+ ```
@@ -1,3 +1,3 @@
1
1
  module JsonTaggedLogger
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_tagged_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Santry