sonnet 0.1.5 → 0.2.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/Gemfile +2 -0
- data/Gemfile.lock +12 -3
- data/Rakefile +3 -1
- data/bin/console +1 -0
- data/examples/sidekiq.rb +3 -1
- data/lib/sonnet/formatter.rb +13 -7
- data/lib/sonnet/logger.rb +4 -4
- data/lib/sonnet/rails.rb +66 -2
- data/lib/sonnet/{monkeypatch.rb → rails_monkeypatch.rb} +8 -4
- data/lib/sonnet/version.rb +3 -1
- data/sonnet.gemspec +2 -1
- data/test/rails_logger_test.rb +42 -0
- data/test/sonnet/formatter_test.rb +35 -0
- data/test/{sonnet_test.rb → sonnet/logger_test.rb} +12 -22
- data/test/test_helper.rb +35 -4
- metadata +24 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c6e3aeaaca85e174a1509ef9ac2876b6685f8bae30dbd940ad650ebf9377563
|
4
|
+
data.tar.gz: 834f727a97a66ee22bb9abf36594e149f473283ffa8d580435bea402fd600b62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8a66ce8ae9c42fbd211764dea21398fcbdac0bd4fd1142577e02284122bd2a90dcf6632000e8c69743ec4c8082a4f99260beaae1eef64e13b536e53c096274b
|
7
|
+
data.tar.gz: 51eb3c154cccab8bc2ac7f1be0d0ae692f9d7c2c764df1eb08208e9fb4b788f46758cde46d54ecc4db32d23f12d1648897f8ce75ae2cd40087809904c9219df2
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,22 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
sonnet (0.
|
4
|
+
sonnet (0.2.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
ansi (1.5.0)
|
10
|
+
builder (3.2.3)
|
9
11
|
byebug (11.0.1)
|
10
12
|
minitest (5.11.3)
|
11
|
-
|
13
|
+
minitest-reporters (1.3.6)
|
14
|
+
ansi
|
15
|
+
builder
|
16
|
+
minitest (>= 5.0)
|
17
|
+
ruby-progressbar
|
18
|
+
rake (13.0.1)
|
19
|
+
ruby-progressbar (1.10.0)
|
12
20
|
|
13
21
|
PLATFORMS
|
14
22
|
ruby
|
@@ -17,8 +25,9 @@ DEPENDENCIES
|
|
17
25
|
bundler
|
18
26
|
byebug
|
19
27
|
minitest
|
28
|
+
minitest-reporters
|
20
29
|
rake
|
21
30
|
sonnet!
|
22
31
|
|
23
32
|
BUNDLED WITH
|
24
|
-
2.
|
33
|
+
2.1.4
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/examples/sidekiq.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "sidekiq/job_logger"
|
2
4
|
|
3
5
|
module SidekiqLogging
|
@@ -9,7 +11,7 @@ module SidekiqLogging
|
|
9
11
|
end
|
10
12
|
|
11
13
|
class JobLogger < Sidekiq::JobLogger
|
12
|
-
def call(job_hash,
|
14
|
+
def call(job_hash, _queue, &_block)
|
13
15
|
Sidekiq.logger.with_context(SidekiqLogging.job_context(job_hash)) do
|
14
16
|
begin
|
15
17
|
start = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
data/lib/sonnet/formatter.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'json'
|
4
|
+
require 'time'
|
5
5
|
|
6
6
|
module Sonnet
|
7
7
|
class Formatter
|
@@ -18,10 +18,11 @@ module Sonnet
|
|
18
18
|
@time = time
|
19
19
|
@progname = progname
|
20
20
|
@data = data
|
21
|
+
@tags = []
|
21
22
|
end
|
22
23
|
|
23
24
|
def program
|
24
|
-
@progname || File.basename($0)
|
25
|
+
@progname || File.basename($0, '.rb').split(' ')[0]
|
25
26
|
end
|
26
27
|
|
27
28
|
def timestamp
|
@@ -52,7 +53,12 @@ module Sonnet
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def context
|
55
|
-
self.class.current_context.inject({},
|
56
|
+
self.class.current_context.inject({}) do |memo, context|
|
57
|
+
context = context.dup
|
58
|
+
tags = memo.fetch(:tags, []) + [*context.delete(:tags)].flatten.compact
|
59
|
+
tag_context = tags.empty? ? {} : { tags: tags }
|
60
|
+
memo.merge(context).merge(tag_context)
|
61
|
+
end
|
56
62
|
end
|
57
63
|
|
58
64
|
def level
|
@@ -74,11 +80,11 @@ module Sonnet
|
|
74
80
|
level: level,
|
75
81
|
timestamp: timestamp,
|
76
82
|
pid: pid
|
77
|
-
}.merge(
|
83
|
+
}.merge(context).merge(data).compact
|
78
84
|
end
|
79
85
|
|
80
|
-
def to_json
|
81
|
-
as_json.to_json + "\n"
|
86
|
+
def to_json(opts = nil)
|
87
|
+
as_json.to_json(opts) + "\n"
|
82
88
|
end
|
83
89
|
end
|
84
90
|
end
|
data/lib/sonnet/logger.rb
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
module Sonnet
|
4
4
|
module Logger
|
5
|
+
def self.new(logger)
|
6
|
+
logger.extend self
|
7
|
+
end
|
8
|
+
|
5
9
|
def self.extended(logger)
|
6
10
|
logger.formatter = Formatter
|
7
11
|
logger.level = log_level
|
@@ -11,10 +15,6 @@ module Sonnet
|
|
11
15
|
::Logger.const_get((ENV["LOG_LEVEL"] || "INFO").upcase)
|
12
16
|
end
|
13
17
|
|
14
|
-
def self.new(logger)
|
15
|
-
logger.extend(self)
|
16
|
-
end
|
17
|
-
|
18
18
|
def with_context(context = {})
|
19
19
|
formatter.current_context.push(context)
|
20
20
|
yield self
|
data/lib/sonnet/rails.rb
CHANGED
@@ -1,9 +1,73 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'sonnet'
|
4
|
+
require 'concurrent'
|
5
|
+
require 'fiber'
|
6
|
+
|
3
7
|
module Sonnet
|
4
|
-
|
8
|
+
class Rails < ::Rails::Engine
|
5
9
|
config.before_configuration do
|
6
|
-
require "sonnet/
|
10
|
+
require "sonnet/rails_monkeypatch"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module RailsLogger
|
15
|
+
def self.included(base)
|
16
|
+
|
17
|
+
base.singleton_class.prepend (Module.new do
|
18
|
+
def extended(logger)
|
19
|
+
super(logger)
|
20
|
+
logger.after_initialize if logger.respond_to?(:after_initialize)
|
21
|
+
end
|
22
|
+
end)
|
23
|
+
end
|
24
|
+
|
25
|
+
def after_initialize
|
26
|
+
@local_levels = Concurrent::Map.new(initial_capacity: 2)
|
27
|
+
end
|
28
|
+
|
29
|
+
def tagged(*tags, &block)
|
30
|
+
if tags.present?
|
31
|
+
with_context(tags: tags.flatten, &block)
|
32
|
+
else
|
33
|
+
yield self
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def local_log_id
|
38
|
+
Fiber.current.__id__
|
39
|
+
end
|
40
|
+
|
41
|
+
def local_level
|
42
|
+
@local_levels[local_log_id]
|
43
|
+
end
|
44
|
+
|
45
|
+
def local_level=(level)
|
46
|
+
if level
|
47
|
+
@local_levels[local_log_id] = level
|
48
|
+
else
|
49
|
+
@local_levels.delete(local_log_id)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def level
|
54
|
+
local_level || super
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module RailsFormatter
|
59
|
+
def current_tags
|
60
|
+
current_context.inject([]) do |memo, context|
|
61
|
+
memo + [*context[:tags]].flatten.compact
|
62
|
+
end
|
7
63
|
end
|
8
64
|
end
|
65
|
+
|
66
|
+
module Logger
|
67
|
+
include RailsLogger
|
68
|
+
end
|
69
|
+
|
70
|
+
class Formatter
|
71
|
+
extend RailsFormatter
|
72
|
+
end
|
9
73
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
if ActiveSupport::VERSION::MAJOR < 6
|
2
4
|
# Monkeypatch in Rails 6 ActiveSupport::TaggedLogging initializer.
|
3
5
|
# Solves problem in which the TaggedLogging initializer modifies an existing logger
|
@@ -32,8 +34,10 @@ if ActiveSupport::VERSION::MAJOR < 6
|
|
32
34
|
end
|
33
35
|
end
|
34
36
|
end
|
35
|
-
else
|
36
|
-
ActiveSupport::Deprecation.warn('No longer need to monkeypatch ActiveSupport::TaggedLogging!')
|
37
|
-
ActiveSupport::Deprecation.warn('No longer need to monkeypatch ActionDispatch::DebugExceptions!')
|
38
|
-
end
|
39
37
|
|
38
|
+
module Sonnet
|
39
|
+
module RailsLogger
|
40
|
+
include LoggerSilence
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/sonnet/version.rb
CHANGED
data/sonnet.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
lib = File.expand_path(
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
|
4
4
|
require "sonnet/version"
|
@@ -21,5 +21,6 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler"
|
22
22
|
spec.add_development_dependency "byebug"
|
23
23
|
spec.add_development_dependency "minitest"
|
24
|
+
spec.add_development_dependency "minitest-reporters"
|
24
25
|
spec.add_development_dependency "rake"
|
25
26
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
# Stub out some Rails constants and methods
|
6
|
+
Rails = Module.new
|
7
|
+
Rails::Engine = Class.new do
|
8
|
+
def self.config
|
9
|
+
OpenStruct.new
|
10
|
+
end
|
11
|
+
end
|
12
|
+
ActiveSupport = Module.new
|
13
|
+
ActiveSupport::LoggerThreadSafeLevel = Module.new
|
14
|
+
LoggerSilence = Module.new
|
15
|
+
|
16
|
+
class Array
|
17
|
+
def present?
|
18
|
+
length > 0
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'sonnet/rails'
|
23
|
+
|
24
|
+
class RailsLoggerTest < Minitest::Test
|
25
|
+
def setup
|
26
|
+
logger.extend(Sonnet::Logger)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_tagged_string
|
30
|
+
logger.tagged('request_id') do
|
31
|
+
logger.info("What's the story, morning glory?")
|
32
|
+
end
|
33
|
+
assert_equal log[0][:tags], ['request_id']
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_tagged_array
|
37
|
+
logger.tagged(['request_id']) do
|
38
|
+
logger.info("What's the story, morning glory?")
|
39
|
+
end
|
40
|
+
assert_equal log[0][:tags], ['request_id']
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
module Sonnet
|
6
|
+
class FormatterTest < Minitest::Test
|
7
|
+
def test_call
|
8
|
+
now = Time.now
|
9
|
+
with_program_name("sidekiq 5.2.5 diaco [0 of 10 busy]") do
|
10
|
+
log_line = JSON.parse(formatter.call("INFO", now, nil, "some message"), symbolize_names: true)
|
11
|
+
assert_equal log_line, {
|
12
|
+
program: "sidekiq",
|
13
|
+
level: "info",
|
14
|
+
timestamp: now.iso8601(3),
|
15
|
+
pid: $$,
|
16
|
+
message: "some message"
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def formatter
|
24
|
+
Formatter
|
25
|
+
end
|
26
|
+
|
27
|
+
def with_program_name(name)
|
28
|
+
original_program_name = $0
|
29
|
+
$0 = name
|
30
|
+
yield if block_given?
|
31
|
+
ensure
|
32
|
+
$0 = original_program_name
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,11 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "test_helper"
|
2
4
|
|
3
|
-
class
|
5
|
+
class LoggerTest < Minitest::Test
|
4
6
|
Error = Class.new(StandardError)
|
5
7
|
|
8
|
+
def setup
|
9
|
+
logger.extend(Sonnet::Logger)
|
10
|
+
end
|
11
|
+
|
6
12
|
def test_log_info
|
7
13
|
logger.info("What's the story, morning glory?")
|
8
|
-
|
14
|
+
assert_equal log[0].slice(:level, :message), level: "info", message: "What's the story, morning glory?"
|
9
15
|
end
|
10
16
|
|
11
17
|
def test_log_debug
|
@@ -13,19 +19,19 @@ class SonnetTest < Minitest::Test
|
|
13
19
|
assert_nil log[0]
|
14
20
|
logger.level = Logger::DEBUG
|
15
21
|
logger.debug("this should be logged")
|
16
|
-
|
22
|
+
assert_equal log[0].slice(:level, :message), level: "debug", message: "this should be logged"
|
17
23
|
end
|
18
24
|
|
19
25
|
def test_log_exception
|
20
26
|
logger.error(Error.new("something went wrong"))
|
21
|
-
|
27
|
+
assert_equal messages(log), ["something went wrong"]
|
22
28
|
end
|
23
29
|
|
24
30
|
def test_log_with_context
|
25
31
|
logger.with_context(color: "blue") { logger.info("What's the story, morning glory?") }
|
26
32
|
logger.info("definitely maybe")
|
27
|
-
|
28
|
-
|
33
|
+
assert_equal log[0].slice(:color, :message), color: "blue", message: "What's the story, morning glory?"
|
34
|
+
assert_equal log[1].slice(:color, :message), message: "definitely maybe"
|
29
35
|
end
|
30
36
|
|
31
37
|
def test_new
|
@@ -34,20 +40,4 @@ class SonnetTest < Minitest::Test
|
|
34
40
|
logger.info("What's the story, morning glory?")
|
35
41
|
assert_log_line log[0], level: "info", message: "What's the story, morning glory?"
|
36
42
|
end
|
37
|
-
|
38
|
-
def assert_log_line(actual, expected)
|
39
|
-
assert_equal expected, actual.slice(*expected.keys)
|
40
|
-
end
|
41
|
-
|
42
|
-
def logger
|
43
|
-
@logger ||= Logger.new(io).tap { |logger| logger.extend(Sonnet::Logger) }
|
44
|
-
end
|
45
|
-
|
46
|
-
def io
|
47
|
-
@io ||= StringIO.new
|
48
|
-
end
|
49
|
-
|
50
|
-
def log
|
51
|
-
io.string.each_line.map { |line| JSON.parse(line, symbolize_names: true) }
|
52
|
-
end
|
53
43
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,6 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require 'minitest/reporters'
|
6
|
+
require 'byebug'
|
7
|
+
require 'logger'
|
8
|
+
|
9
|
+
Minitest::Reporters.use! [Minitest::Reporters::ProgressReporter.new]
|
5
10
|
|
6
11
|
require "sonnet"
|
12
|
+
|
13
|
+
module LoggingHelpers
|
14
|
+
def logger
|
15
|
+
@logger ||= Logger.new(io)
|
16
|
+
end
|
17
|
+
|
18
|
+
def io
|
19
|
+
@io ||= StringIO.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def assert_log_line(actual, expected)
|
23
|
+
assert_equal expected, actual.slice(*expected.keys)
|
24
|
+
end
|
25
|
+
|
26
|
+
def log
|
27
|
+
io.string.each_line.map { |line| JSON.parse(line, symbolize_names: true) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def messages(lines)
|
31
|
+
lines.map { |line| line[:message] }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Minitest::Test
|
36
|
+
include LoggingHelpers
|
37
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sonnet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cory Kaufman-Schofield
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rake
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,18 +99,20 @@ files:
|
|
85
99
|
- lib/sonnet.rb
|
86
100
|
- lib/sonnet/formatter.rb
|
87
101
|
- lib/sonnet/logger.rb
|
88
|
-
- lib/sonnet/monkeypatch.rb
|
89
102
|
- lib/sonnet/rails.rb
|
103
|
+
- lib/sonnet/rails_monkeypatch.rb
|
90
104
|
- lib/sonnet/version.rb
|
91
105
|
- sonnet.gemspec
|
92
|
-
- test/
|
106
|
+
- test/rails_logger_test.rb
|
107
|
+
- test/sonnet/formatter_test.rb
|
108
|
+
- test/sonnet/logger_test.rb
|
93
109
|
- test/test_helper.rb
|
94
110
|
homepage: https://github.com/allspiritseve/sonnet
|
95
111
|
licenses:
|
96
112
|
- MIT
|
97
113
|
metadata:
|
98
114
|
allowed_push_host: https://rubygems.org
|
99
|
-
post_install_message:
|
115
|
+
post_install_message:
|
100
116
|
rdoc_options: []
|
101
117
|
require_paths:
|
102
118
|
- lib
|
@@ -111,8 +127,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
127
|
- !ruby/object:Gem::Version
|
112
128
|
version: '0'
|
113
129
|
requirements: []
|
114
|
-
rubygems_version: 3.
|
115
|
-
signing_key:
|
130
|
+
rubygems_version: 3.1.6
|
131
|
+
signing_key:
|
116
132
|
specification_version: 4
|
117
133
|
summary: Structured logging for Ruby applications
|
118
134
|
test_files: []
|