superlogger 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|