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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fde1c29033040450a05efda38fc80a4ab39647af542de057bf1a51a12ae9c98
4
- data.tar.gz: e02bacca362f4992aa567576d88720c961e3b733e7c9abdba5bdba9487aad0ac
3
+ metadata.gz: 2c6e3aeaaca85e174a1509ef9ac2876b6685f8bae30dbd940ad650ebf9377563
4
+ data.tar.gz: 834f727a97a66ee22bb9abf36594e149f473283ffa8d580435bea402fd600b62
5
5
  SHA512:
6
- metadata.gz: 1bb24a4c08a4429764bd50319d088e342147fbf794ccb908213bd0dc74f010d01acafe9aa2c39f87b3b09396f9d29f072ae3f37a76fd6b2ef2730cd437ba8f0e
7
- data.tar.gz: 65509aff4d33b784ec8576e3e78f2ef6bfe2fb9ffea11f9cf03f2877955eba628b12a7051667c68f679ecaf8381d7ac2142bf6f8b4448bcb5a86acfd6f8fc281
6
+ metadata.gz: b8a66ce8ae9c42fbd211764dea21398fcbdac0bd4fd1142577e02284122bd2a90dcf6632000e8c69743ec4c8082a4f99260beaae1eef64e13b536e53c096274b
7
+ data.tar.gz: 51eb3c154cccab8bc2ac7f1be0d0ae692f9d7c2c764df1eb08208e9fb4b788f46758cde46d54ecc4db32d23f12d1648897f8ce75ae2cd40087809904c9219df2
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  # Specify your gem's dependencies in sonnet.gemspec
data/Gemfile.lock CHANGED
@@ -1,14 +1,22 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sonnet (0.1.5)
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
- rake (12.3.2)
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.0.1
33
+ 2.1.4
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rake/testtask"
3
5
 
@@ -7,4 +9,4 @@ Rake::TestTask.new(:test) do |t|
7
9
  t.test_files = FileList["test/**/*_test.rb"]
8
10
  end
9
11
 
10
- task :default => :test
12
+ task default: :test
data/bin/console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "sonnet"
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, queue, &block)
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)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
- require "time"
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({}, &:merge)
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(data).merge(context).compact
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
- class Rails < ::Rails::Engine
8
+ class Rails < ::Rails::Engine
5
9
  config.before_configuration do
6
- require "sonnet/monkeypatch"
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sonnet
2
- VERSION = "0.1.5"
4
+ VERSION = "0.2.0"
3
5
  end
data/sonnet.gemspec CHANGED
@@ -1,4 +1,4 @@
1
- lib = File.expand_path("../lib", __FILE__)
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 SonnetTest < Minitest::Test
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
- assert_log_line log[0], level: "info", message: "What's the story, morning glory?"
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
- assert_log_line log[0], level: "debug", message: "this should be logged"
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
- assert_log_line log[0], message: "something went wrong"
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
- assert_log_line log[0], color: "blue", message: "What's the story, morning glory?"
28
- assert_log_line log[1], message: "definitely maybe"
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
- $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
- require "minitest/autorun"
3
- require "byebug"
4
- require "logger"
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.1.5
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: 2019-04-09 00:00:00.000000000 Z
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/sonnet_test.rb
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.0.1
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: []