twiglet 2.3.3 → 2.3.8
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/.github/CODEOWNERS +2 -1
- data/.github/workflows/ruby.yml +15 -1
- data/.github/workflows/version-forget-me-not.yml +27 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -1
- data/Dockerfile +7 -0
- data/Gemfile +1 -0
- data/Makefile +9 -0
- data/README.md +1 -1
- 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/formatter.rb +3 -0
- data/lib/twiglet/version.rb +1 -1
- data/test/formatter_test.rb +3 -0
- data/test/logger_test.rb +8 -2
- data/test/test_coverage.rb +13 -0
- data/twiglet.gemspec +1 -1
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb67641cb96b209f76dff9715a469edd7cd78661ec606bfa2b229f8d5e124b01
|
4
|
+
data.tar.gz: 37d1f21d56ce96c099edefe3cbb93a7bedb14e6496fcf3aef9fa71cd09f1bb40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04aeb0f52a59d136d56d2839094e2d3c113bf396204d772c0dc2097ef2c2181f5755dd5b2e4ffbc4643b66b0da1885937ff015f15b90834676526a1d2537ec53
|
7
|
+
data.tar.gz: 5e7bd5396bab68ab3f1aef5859753382774aad7ed5c5dd25a41dfe56aa9af97e8e08eece2515ca033ce2c5f9c342bda7b288ce9171a94f59cd151cad77cf3151
|
data/.github/CODEOWNERS
CHANGED
data/.github/workflows/ruby.yml
CHANGED
@@ -4,6 +4,9 @@ on:
|
|
4
4
|
push:
|
5
5
|
branches:
|
6
6
|
|
7
|
+
env:
|
8
|
+
CI: true
|
9
|
+
|
7
10
|
jobs:
|
8
11
|
build:
|
9
12
|
runs-on: ubuntu-latest
|
@@ -13,7 +16,7 @@ jobs:
|
|
13
16
|
|
14
17
|
strategy:
|
15
18
|
matrix:
|
16
|
-
ruby-version: [2.6, 2.7]
|
19
|
+
ruby-version: [2.5, 2.6, 2.7]
|
17
20
|
|
18
21
|
steps:
|
19
22
|
- uses: actions/checkout@v2
|
@@ -23,11 +26,22 @@ jobs:
|
|
23
26
|
ruby-version: ${{ matrix.ruby-version }}
|
24
27
|
- name: Install dependencies
|
25
28
|
run: bundle install
|
29
|
+
- name: install cc-test-reporter
|
30
|
+
env:
|
31
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
32
|
+
run: |
|
33
|
+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-0.6.3-linux-amd64 > ./cc-test-reporter
|
34
|
+
chmod +x ./cc-test-reporter
|
35
|
+
./cc-test-reporter before-build
|
26
36
|
- name: Rubocop Check
|
27
37
|
run: bundle exec rubocop
|
28
38
|
- name: Run all tests
|
29
39
|
run: bundle exec rake test
|
30
40
|
shell: bash
|
41
|
+
- name: upload test coverage to CodeClimate
|
42
|
+
env:
|
43
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
44
|
+
run: ./cc-test-reporter after-build
|
31
45
|
- name: Run example_app
|
32
46
|
run: bundle exec ruby example_app.rb
|
33
47
|
shell: bash
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: Check version
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
branches:
|
6
|
+
- master # default branch
|
7
|
+
types: [opened, synchronize]
|
8
|
+
jobs:
|
9
|
+
build:
|
10
|
+
runs-on: ubuntu-18.04
|
11
|
+
|
12
|
+
steps:
|
13
|
+
# For private action we need to checkout the action repo.
|
14
|
+
# We can remove this once we make the action public.
|
15
|
+
- uses: actions/checkout@v1
|
16
|
+
with:
|
17
|
+
repository: simplybusiness/version-forget-me-not
|
18
|
+
ref: refs/tags/v1.0
|
19
|
+
# Do not put the actual secret here- only the name of the secret in your repo
|
20
|
+
token: ${{ secrets.BOT_TOKEN }}
|
21
|
+
path: './twiglet-ruby'
|
22
|
+
- uses: ./
|
23
|
+
env:
|
24
|
+
ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
25
|
+
# It is the file path where you keep the version of gem.
|
26
|
+
# It usually in the `lib/<gem name>/version.rb` or in the gemspec file.
|
27
|
+
VERSION_FILE_PATH: "lib/twiglet/version.rb"
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/Dockerfile
ADDED
data/Gemfile
CHANGED
data/Makefile
ADDED
data/README.md
CHANGED
@@ -117,7 +117,7 @@ which will print:
|
|
117
117
|
{"service":{"name":"service name"},"@timestamp":"2020-05-14T10:58:30.780+01:00","log":{"level":"error"},"event":{"action":"HTTP request"},"trace":{"id":"126bb6fa-28a2-470f-b013-eefbf9182b2d"},"message":"Error 500 in /pets/buy","http":{"request":{"method":"post","url.path":"/pet/buy"},"response":{"status_code":500}}}
|
118
118
|
```
|
119
119
|
|
120
|
-
## Use of dotted keys
|
120
|
+
## Use of dotted keys (DEPRECATED)
|
121
121
|
|
122
122
|
Writing nested json objects could be confusing. This library has a built-in feature to convert dotted keys into nested objects, so if you log like this:
|
123
123
|
|
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/formatter.rb
CHANGED
data/lib/twiglet/version.rb
CHANGED
data/test/formatter_test.rb
CHANGED
@@ -17,6 +17,9 @@ describe Twiglet::Formatter do
|
|
17
17
|
it 'returns a formatted log from a string message' do
|
18
18
|
msg = @formatter.call('warn', nil, nil, 'shop is running low on dog food')
|
19
19
|
expected_log = {
|
20
|
+
"ecs" => {
|
21
|
+
"version" => '1.5.0'
|
22
|
+
},
|
20
23
|
"@timestamp" => '2020-05-11T15:01:01.000Z',
|
21
24
|
"service" => {
|
22
25
|
"name" => 'petshop'
|
data/test/logger_test.rb
CHANGED
@@ -49,6 +49,9 @@ describe Twiglet::Logger do
|
|
49
49
|
|
50
50
|
expected_log = {
|
51
51
|
message: 'Out of pets exception',
|
52
|
+
ecs: {
|
53
|
+
version: '1.5.0'
|
54
|
+
},
|
52
55
|
"@timestamp": '2020-05-11T15:01:01.000Z',
|
53
56
|
service: {
|
54
57
|
name: 'petshop'
|
@@ -136,10 +139,10 @@ describe Twiglet::Logger do
|
|
136
139
|
@logger.info({message: 'there'})
|
137
140
|
|
138
141
|
expected_output =
|
139
|
-
'{"@timestamp":"2020-05-11T15:01:01.000Z",'\
|
142
|
+
'{"ecs":{"version":"1.5.0"},"@timestamp":"2020-05-11T15:01:01.000Z",'\
|
140
143
|
'"service":{"name":"petshop"},"log":{"level":"debug"},"message":"hi"}'\
|
141
144
|
"\n"\
|
142
|
-
'{"@timestamp":"2020-05-11T15:01:01.000Z",'\
|
145
|
+
'{"ecs":{"version":"1.5.0"},"@timestamp":"2020-05-11T15:01:01.000Z",'\
|
143
146
|
'"service":{"name":"petshop"},"log":{"level":"info"},"message":"there"}'\
|
144
147
|
"\n"\
|
145
148
|
|
@@ -251,6 +254,9 @@ describe Twiglet::Logger do
|
|
251
254
|
|
252
255
|
expected_log = {
|
253
256
|
message: 'Out of pets exception',
|
257
|
+
ecs: {
|
258
|
+
version: '1.5.0'
|
259
|
+
},
|
254
260
|
"@timestamp": '2020-05-11T15:01:01.000Z',
|
255
261
|
service: {
|
256
262
|
name: 'petshop'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter "/test/"
|
5
|
+
add_filter "examples/rack/request_logger_test.rb"
|
6
|
+
|
7
|
+
if ENV['CI']
|
8
|
+
formatter SimpleCov::Formatter::SimpleFormatter
|
9
|
+
else
|
10
|
+
formatter SimpleCov::Formatter::MultiFormatter.new([SimpleCov::Formatter::SimpleFormatter,
|
11
|
+
SimpleCov::Formatter::HTMLFormatter])
|
12
|
+
end
|
13
|
+
end
|
data/twiglet.gemspec
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.8
|
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-
|
11
|
+
date: 2020-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Like a log, only smaller.
|
14
14
|
email:
|
@@ -20,16 +20,22 @@ files:
|
|
20
20
|
- ".github/CODEOWNERS"
|
21
21
|
- ".github/workflows/gem-publish.yml"
|
22
22
|
- ".github/workflows/ruby.yml"
|
23
|
+
- ".github/workflows/version-forget-me-not.yml"
|
23
24
|
- ".gitignore"
|
24
25
|
- ".rubocop.yml"
|
25
26
|
- ".ruby-version"
|
26
27
|
- CODE_OF_CONDUCT.md
|
28
|
+
- Dockerfile
|
27
29
|
- Gemfile
|
28
30
|
- LICENSE
|
31
|
+
- Makefile
|
29
32
|
- RATIONALE.md
|
30
33
|
- README.md
|
31
34
|
- Rakefile
|
32
35
|
- example_app.rb
|
36
|
+
- examples/rack/example_rack_app.rb
|
37
|
+
- examples/rack/request_logger.rb
|
38
|
+
- examples/rack/request_logger_test.rb
|
33
39
|
- lib/hash_extensions.rb
|
34
40
|
- lib/twiglet/formatter.rb
|
35
41
|
- lib/twiglet/logger.rb
|
@@ -37,6 +43,7 @@ files:
|
|
37
43
|
- test/formatter_test.rb
|
38
44
|
- test/hash_extensions_test.rb
|
39
45
|
- test/logger_test.rb
|
46
|
+
- test/test_coverage.rb
|
40
47
|
- twiglet.gemspec
|
41
48
|
homepage: https://github.com/simplybusiness/twiglet-ruby
|
42
49
|
licenses:
|
@@ -50,7 +57,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
50
57
|
requirements:
|
51
58
|
- - ">="
|
52
59
|
- !ruby/object:Gem::Version
|
53
|
-
version: '2.
|
60
|
+
version: '2.5'
|
54
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
62
|
requirements:
|
56
63
|
- - ">="
|