superlogger 1.0.1 → 1.1.0
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 +31 -0
- data/lib/superlogger/superlogger_middleware.rb +19 -11
- data/lib/superlogger/version.rb +1 -1
- data/lib/superlogger.rb +12 -1
- data/test/dummy/app/controllers/home_controller.rb +6 -0
- data/test/dummy/config/application.rb +8 -0
- data/test/dummy/config/routes.rb +1 -0
- data/test/superlogger_test.rb +62 -7
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31133b660d9663478b8feabfa3bfc2f38431485648ef434230ae56e778b9a65c
|
4
|
+
data.tar.gz: 7c2bf630ad96997d64a6ac7224a3635fe3dd6246b79ab289305498bdf68a5ac8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29ca48eafa2e7e648cb852e6e2142aa4092f95b5e1b86a9cd0eb432ac180616b9af0c2746c6cfa161ec997038fe7e38b3b5552bb8bf01b0a55ae7003211bad0b
|
7
|
+
data.tar.gz: b554d0898a26c4b32936754cec07cc557faafa74c719e918c789d20b7f11110e98915ff62476d2de199d2bc0a0a445011c7531f02642b5acbaf4e1caa5382142
|
data/README.md
CHANGED
@@ -72,3 +72,34 @@ Rails.logger.info "Meatball"
|
|
72
72
|
- `request_id` = 32 characters
|
73
73
|
- `msg` = If values given is not a hash, it is treated as `{"msg":<value>"}`
|
74
74
|
- All duration related fields are in milliseconds
|
75
|
+
|
76
|
+
To log additional fields that are available on the `ActionDispatch::Request` object, set in `config/application.rb`:
|
77
|
+
```ruby
|
78
|
+
Superlogger.include_log_fields = lambda do |request|
|
79
|
+
# Return a hash of extra fields to log.
|
80
|
+
{
|
81
|
+
user_id: request.session[:current_user].id,
|
82
|
+
ip: request.ip
|
83
|
+
}
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
## Testing ##
|
88
|
+
|
89
|
+
To run the tests for Superlogger:
|
90
|
+
|
91
|
+
```sh
|
92
|
+
rake test
|
93
|
+
```
|
94
|
+
|
95
|
+
## Publishing a New Release ##
|
96
|
+
|
97
|
+
1. Bump the version in `lib/superlogger/version.rb`.
|
98
|
+
1. Run `bundle install` to update the version of Superlogger in `Gemfile.lock`.
|
99
|
+
1. Open a pull request with the changes from the above steps.
|
100
|
+
1. After the pull request is merged, publish a new release on GitHub with the same version tag.
|
101
|
+
1. Clear all temporary files to prevent them from being bundled into the gem.
|
102
|
+
This is most easily achieved by building from a new clone of the repository.
|
103
|
+
1. Run `gem build superlogger.gemspec` to build the gem.
|
104
|
+
1. Run `gem push superlogger-x.x.x.gem` to publish the gem to RubyGems.
|
105
|
+
You will be prompted for credentials if this is your first time publishing the gem on your machine.
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module Superlogger
|
2
2
|
class SuperloggerMiddleware
|
3
|
-
def initialize(app)
|
3
|
+
def initialize(app, options = {})
|
4
4
|
@app = app
|
5
|
+
@options = {
|
6
|
+
include_log_fields: ->(_request) { {} }
|
7
|
+
}.merge(options)
|
5
8
|
end
|
6
9
|
|
7
10
|
def call(env)
|
@@ -15,7 +18,8 @@ module Superlogger
|
|
15
18
|
end
|
16
19
|
|
17
20
|
def process_request(request)
|
18
|
-
|
21
|
+
setup_request_id_for_logging(request)
|
22
|
+
setup_session_id_for_logging(request)
|
19
23
|
|
20
24
|
# Start of request
|
21
25
|
Rails.logger.info method: request.method, path: request.fullpath
|
@@ -27,20 +31,24 @@ module Superlogger
|
|
27
31
|
|
28
32
|
# End of request
|
29
33
|
duration = ((t2 - t1) * 1000).to_f.round(2)
|
30
|
-
|
34
|
+
|
35
|
+
# After the request has been processed, the session ID can change from what it was before the request
|
36
|
+
# was processed. As such, we need to setup the session ID again.
|
37
|
+
setup_session_id_for_logging(request)
|
38
|
+
|
39
|
+
Rails.logger.info method: request.method, path: request.fullpath, response_time: duration, status: status, **@options[:include_log_fields].call(request)
|
31
40
|
|
32
41
|
[status, _headers, _response]
|
33
42
|
end
|
34
43
|
|
35
|
-
def
|
36
|
-
if request.env['rack.session']
|
37
|
-
# Store session id before any actual logging is done
|
38
|
-
if request.env['rack.session'].id
|
39
|
-
Superlogger.session_id = request.env['rack.session'].id.to_s
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
44
|
+
def setup_request_id_for_logging(request)
|
43
45
|
Superlogger.request_id = request.uuid.try(:gsub, '-', '')
|
44
46
|
end
|
47
|
+
|
48
|
+
def setup_session_id_for_logging(request)
|
49
|
+
return unless request.env['rack.session']&.id
|
50
|
+
|
51
|
+
Superlogger.session_id = request.env['rack.session'].id.to_s
|
52
|
+
end
|
45
53
|
end
|
46
54
|
end
|
data/lib/superlogger/version.rb
CHANGED
data/lib/superlogger.rb
CHANGED
@@ -3,6 +3,7 @@ require 'superlogger/logger'
|
|
3
3
|
|
4
4
|
module Superlogger
|
5
5
|
@@enabled = false
|
6
|
+
@@include_log_fields = nil
|
6
7
|
|
7
8
|
module_function
|
8
9
|
|
@@ -18,7 +19,9 @@ module Superlogger
|
|
18
19
|
require 'superlogger/superlogger_middleware'
|
19
20
|
|
20
21
|
# important to insert after session middleware so we can get the session id
|
21
|
-
app.middleware.use Superlogger::SuperloggerMiddleware
|
22
|
+
app.middleware.use Superlogger::SuperloggerMiddleware, {
|
23
|
+
include_log_fields: @@include_log_fields
|
24
|
+
}.compact
|
22
25
|
end
|
23
26
|
|
24
27
|
def detach_existing_log_subscribers
|
@@ -74,6 +77,14 @@ module Superlogger
|
|
74
77
|
def enabled
|
75
78
|
@@enabled
|
76
79
|
end
|
80
|
+
|
81
|
+
def include_log_fields=(include_log_fields)
|
82
|
+
@@include_log_fields=include_log_fields
|
83
|
+
end
|
84
|
+
|
85
|
+
def include_log_fields
|
86
|
+
@@include_log_fields
|
87
|
+
end
|
77
88
|
end
|
78
89
|
|
79
90
|
require 'superlogger/railtie' if defined?(Rails)
|
@@ -23,5 +23,13 @@ module Dummy
|
|
23
23
|
|
24
24
|
Superlogger.enabled = true
|
25
25
|
config.logger = Superlogger::Logger.new(STDOUT)
|
26
|
+
|
27
|
+
Superlogger.include_log_fields = lambda do |request|
|
28
|
+
session = request.session
|
29
|
+
{
|
30
|
+
current_time: session[:current_time],
|
31
|
+
hello: 'world'
|
32
|
+
}
|
33
|
+
end
|
26
34
|
end
|
27
35
|
end
|
data/test/dummy/config/routes.rb
CHANGED
data/test/superlogger_test.rb
CHANGED
@@ -33,10 +33,30 @@ class SuperloggerTest < ActiveSupport::TestCase
|
|
33
33
|
assert_not_nil Superlogger::VERSION
|
34
34
|
end
|
35
35
|
|
36
|
-
test 'log format' do
|
36
|
+
test 'log format when session is not loaded' do
|
37
37
|
request('home/index')
|
38
38
|
|
39
|
-
fields = output
|
39
|
+
fields = output[4]
|
40
|
+
assert fields.key?("level")
|
41
|
+
assert fields.key?("ts")
|
42
|
+
assert fields.key?("caller")
|
43
|
+
assert_equal fields.key?("session_id"), false
|
44
|
+
assert fields.key?("request_id")
|
45
|
+
end
|
46
|
+
|
47
|
+
test 'log format when session is loaded' do
|
48
|
+
request('home/index_with_session')
|
49
|
+
|
50
|
+
# Session is not loaded before the request is processed.
|
51
|
+
fields = output[0]
|
52
|
+
assert fields.key?("level")
|
53
|
+
assert fields.key?("ts")
|
54
|
+
assert fields.key?("caller")
|
55
|
+
assert_equal fields.key?("session_id"), false
|
56
|
+
assert fields.key?("request_id")
|
57
|
+
|
58
|
+
# Session is loaded after the request is processed.
|
59
|
+
fields = output[4]
|
40
60
|
assert fields.key?("level")
|
41
61
|
assert fields.key?("ts")
|
42
62
|
assert fields.key?("caller")
|
@@ -44,14 +64,49 @@ class SuperloggerTest < ActiveSupport::TestCase
|
|
44
64
|
assert fields.key?("request_id")
|
45
65
|
end
|
46
66
|
|
67
|
+
# The additional fields to log are defined in `/test/dummy/config/application.rb`.
|
68
|
+
# Unfortunately, because `Superlogger::SuperloggerMiddleware` is initialised
|
69
|
+
# together with the Rails application, and because we cannot programmatically
|
70
|
+
# reinitialise the Rails application or run multiple instances of it, we are
|
71
|
+
# only able to test a single Superlogger configuration. Once the Rails
|
72
|
+
# application is initialised, the middleware stack cannot be changed.
|
73
|
+
#
|
74
|
+
# This effectively means that we are unable to change the Superlogger settings
|
75
|
+
# in the Rails application configuration on a per-test basis. For the sake of
|
76
|
+
# testing, we choose the Superlogger settings that let us test the presence of
|
77
|
+
# behaviours and set the additional fields to log.
|
78
|
+
test 'log format when logging additional fields' do
|
79
|
+
request('home/index_with_session')
|
80
|
+
|
81
|
+
# Additional fields are not logged before the request is processed.
|
82
|
+
fields = output[0]
|
83
|
+
assert fields.key?("level")
|
84
|
+
assert fields.key?("ts")
|
85
|
+
assert fields.key?("caller")
|
86
|
+
assert_equal fields.key?("session_id"), false
|
87
|
+
assert fields.key?("request_id")
|
88
|
+
assert_equal fields.key?("current_time"), false
|
89
|
+
assert_equal fields.key?("hello"), false
|
90
|
+
|
91
|
+
# Additional fields are logged after the request is processed.
|
92
|
+
fields = output[4]
|
93
|
+
assert fields.key?("level")
|
94
|
+
assert fields.key?("ts")
|
95
|
+
assert fields.key?("caller")
|
96
|
+
assert fields.key?("session_id")
|
97
|
+
assert fields.key?("request_id")
|
98
|
+
assert fields.key?("current_time")
|
99
|
+
assert fields.key?("hello")
|
100
|
+
end
|
101
|
+
|
47
102
|
test 'timestamp' do
|
48
103
|
request('home/index')
|
49
104
|
assert_equal Time.at(output[0]["ts"]).to_date, Date.today
|
50
105
|
end
|
51
106
|
|
52
107
|
test 'with session_id' do
|
53
|
-
env = request('home/
|
54
|
-
assert_match env['rack.session'].id.to_s[0..11], output[
|
108
|
+
env = request('home/index_with_session')
|
109
|
+
assert_match env['rack.session'].id.to_s[0..11], output[4]["session_id"]
|
55
110
|
end
|
56
111
|
|
57
112
|
test 'without session_id' do
|
@@ -108,7 +163,7 @@ class SuperloggerTest < ActiveSupport::TestCase
|
|
108
163
|
test 'action_controller_log_subscriber.process_action' do
|
109
164
|
request('home/index')
|
110
165
|
|
111
|
-
fields = output[
|
166
|
+
fields = output[7]
|
112
167
|
assert_operator fields["view_duration"], :>, 0
|
113
168
|
assert_operator fields["db_duration"], :>, 0
|
114
169
|
end
|
@@ -116,11 +171,11 @@ class SuperloggerTest < ActiveSupport::TestCase
|
|
116
171
|
test 'action_view_log_subscriber.render_template.render_partial.render_collection' do
|
117
172
|
request('home/index')
|
118
173
|
|
119
|
-
fields = output[
|
174
|
+
fields = output[4]
|
120
175
|
assert_match 'partial.html.erb', fields["view"]
|
121
176
|
assert fields.key?("duration")
|
122
177
|
|
123
|
-
fields = output[
|
178
|
+
fields = output[5]
|
124
179
|
assert_match 'index.html.erb', fields["view"]
|
125
180
|
assert fields.key?("duration")
|
126
181
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: superlogger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soh Yu Ming
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -117,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: '0'
|
119
119
|
requirements: []
|
120
|
-
rubygems_version: 3.
|
120
|
+
rubygems_version: 3.5.9
|
121
121
|
signing_key:
|
122
122
|
specification_version: 4
|
123
123
|
summary: Machine-readable logging for Rails
|