sonnet 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []