twiglet 2.3.6 → 2.3.7
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/Rakefile +1 -1
- data/examples/rack/example_rack_app.rb +17 -0
- data/examples/rack/request_logger.rb +49 -0
- data/examples/rack/request_logger_test.rb +66 -0
- data/lib/twiglet/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc5514d2c3e51632a86e09ee38aab95d2b32c3d9337b8ce5d0677d9de8b41899
|
4
|
+
data.tar.gz: bd223470da816efcea468f339042986bc62ad76f348607ee76bd12829d9a8b5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 346e3c5209e5a6b785eac0535920b5f09ad18ac02f8db7b2027fe3d13e6f89e9f300bfe02be1eebbf97bb39e723e6fd21f2ec053d91690aa31a1d3f059c96c40
|
7
|
+
data.tar.gz: 2f516abc83aaa75ff8389eb9560380cf88cdad547773b63429716f985e120433fcf55c188bd023ef0413829ccd14c498cc150ca748632ee5b1ddcad6a3d7b36b
|
data/Rakefile
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'twiglet/logger'
|
2
|
+
require 'request_logger'
|
3
|
+
|
4
|
+
# basic rack application
|
5
|
+
class Application
|
6
|
+
def call(_env)
|
7
|
+
status = 200
|
8
|
+
headers = { "Content-Type" => "text/json" }
|
9
|
+
body = ["Example rack app"]
|
10
|
+
|
11
|
+
[status, headers, body]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
use RequestLogger, Twiglet::Logger.new('example_app')
|
16
|
+
|
17
|
+
run Application.new
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Middleware for logging request logs
|
2
|
+
class RequestLogger
|
3
|
+
def initialize(app, logger)
|
4
|
+
@app = app
|
5
|
+
@logger = logger
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
status, headers, body = @app.call(env)
|
10
|
+
log(env, status)
|
11
|
+
[status, headers, body]
|
12
|
+
rescue StandardError => e
|
13
|
+
log_error(env, 500, e)
|
14
|
+
[500, {}, body]
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def log(env, status)
|
20
|
+
fields = get_fields(env, status)
|
21
|
+
@logger.info(fields)
|
22
|
+
end
|
23
|
+
|
24
|
+
def log_error(env, status, error)
|
25
|
+
fields = get_fields(env, status)
|
26
|
+
@logger.error(fields, error)
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_fields(env, status)
|
30
|
+
message = "#{env['REQUEST_METHOD']}: #{env['PATH_INFO']}"
|
31
|
+
|
32
|
+
{
|
33
|
+
http: {
|
34
|
+
request: {
|
35
|
+
method: env['REQUEST_METHOD'],
|
36
|
+
server: env['SERVER_NAME'],
|
37
|
+
https_enabled: env['HTTPS'],
|
38
|
+
path: env['PATH_INFO'],
|
39
|
+
query: env['QUERY_STRING'] # Don't log PII query params
|
40
|
+
},
|
41
|
+
response: {
|
42
|
+
status: status,
|
43
|
+
body: { bytes: env['CONTENT_LENGTH'] }
|
44
|
+
}
|
45
|
+
},
|
46
|
+
message: message
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require_relative './request_logger'
|
3
|
+
require 'rack'
|
4
|
+
|
5
|
+
describe RequestLogger do
|
6
|
+
let(:output) { StringIO.new }
|
7
|
+
|
8
|
+
before { output.rewind }
|
9
|
+
|
10
|
+
it 'log should not be empty' do
|
11
|
+
request.get("/some/path")
|
12
|
+
log = output.string
|
13
|
+
refute_empty log
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'logs the request data' do
|
17
|
+
request.get("/some/path?some_var=1")
|
18
|
+
log = JSON.parse(output.string)
|
19
|
+
http_body = {
|
20
|
+
"request" => {
|
21
|
+
"https_enabled" => "off",
|
22
|
+
"method" => "GET",
|
23
|
+
"path" => "/some/path",
|
24
|
+
"query" => "some_var=1",
|
25
|
+
"server" => "example.org"
|
26
|
+
},
|
27
|
+
"response" => {
|
28
|
+
"status" => 200,
|
29
|
+
"body" => { "bytes" => "0" }
|
30
|
+
}
|
31
|
+
}
|
32
|
+
assert_equal http_body, log["http"]
|
33
|
+
assert_equal "GET: /some/path", log["message"]
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'does not log PII' do
|
37
|
+
request.post("/user/info", input_data: {credit_card_no: '1234'})
|
38
|
+
log = output.string
|
39
|
+
assert_includes log, "POST: /user/info"
|
40
|
+
refute_includes log, 'credit_card_no'
|
41
|
+
refute_includes log, '1234'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'logs an error message when a request is bad' do
|
45
|
+
bad_request.get("/some/path")
|
46
|
+
log = JSON.parse(output.string)
|
47
|
+
assert_equal 'error', log['log']['level']
|
48
|
+
assert_equal 'some exception', log['error']['message']
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def request
|
53
|
+
app = ->(env) { [200, env, "app"] }
|
54
|
+
base_request(app)
|
55
|
+
end
|
56
|
+
|
57
|
+
def bad_request
|
58
|
+
app = Rack::Lint.new ->(_env) { raise StandardError, 'some exception' }
|
59
|
+
base_request(app)
|
60
|
+
end
|
61
|
+
|
62
|
+
def base_request(app)
|
63
|
+
logger = Twiglet::Logger.new('example', output: output)
|
64
|
+
req_logger = RequestLogger.new(app, logger)
|
65
|
+
Rack::MockRequest.new(req_logger)
|
66
|
+
end
|
data/lib/twiglet/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twiglet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simply Business
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Like a log, only smaller.
|
14
14
|
email:
|
@@ -30,6 +30,9 @@ files:
|
|
30
30
|
- README.md
|
31
31
|
- Rakefile
|
32
32
|
- example_app.rb
|
33
|
+
- examples/rack/example_rack_app.rb
|
34
|
+
- examples/rack/request_logger.rb
|
35
|
+
- examples/rack/request_logger_test.rb
|
33
36
|
- lib/hash_extensions.rb
|
34
37
|
- lib/twiglet/formatter.rb
|
35
38
|
- lib/twiglet/logger.rb
|