twiglet 2.1.1 → 2.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: 4f97187804f27d00e7b8231880b43c50769b70a1598dcb3eedb42d2afad4fe0c
4
- data.tar.gz: 18f126aef6c1b43bde8b4e343d2c7595e4fc3f1c07608e02214b3bf7ab2e36e4
3
+ metadata.gz: 356d8c7fec6c41823029cc36bef1cc49bacae6157342b251e9b57f49dcb8151f
4
+ data.tar.gz: bd58a67b48daa9bf6108dc78098f46ad0204f98ca600c29bacd713f6cb54ea2e
5
5
  SHA512:
6
- metadata.gz: 2bf3104cbb1e9f4051f58d6969cf7a761f8aac44a50dfee5677ed52b8ddc0679692357b513b0c995f40fe29f9327f339c8491db326bff261e167e1e8bf6d61b1
7
- data.tar.gz: d1ee7cd4c20da132b3cfa8ca88ef117cc93bbb77773671274792cf67746f6b1947ff8c426099a2417ccbc291ff95853adaf1ded2be007f1deb85ebce265567ef
6
+ metadata.gz: 4bc443482b93b1bba853fbe67605d9b0673830726cf1ef89e941860bc7f832d1efb5f82d5890197ae279b9edf97bf19edf8dc2d8bf61d56d082d6e641f94a245
7
+ data.tar.gz: 8d5e178fca01957147dca807aab4117958b18514d568440e72f53cfc8931aad62035a71633646776368f4409d9be48ab8598c66aad4347edd59f79a0bfc281ae
@@ -0,0 +1,68 @@
1
+ require 'logger'
2
+ require_relative '../hash_extensions'
3
+
4
+ module Twiglet
5
+ class Formatter < ::Logger::Formatter
6
+ Hash.include HashExtensions
7
+
8
+ def initialize(service_name,
9
+ default_properties: {},
10
+ now: -> { Time.now.utc })
11
+ @service_name = service_name
12
+ @now = now
13
+ @default_properties = default_properties
14
+
15
+ super()
16
+ end
17
+
18
+ def call(severity, _time, _progname, msg)
19
+ level = severity.downcase
20
+ log(level: level, message: msg)
21
+ end
22
+
23
+ private
24
+
25
+ def log(level:, message:)
26
+ case message
27
+ when String
28
+ log_text(level, message: message)
29
+ when Hash
30
+ log_object(level, message: message)
31
+ else
32
+ raise('Message must be String or Hash')
33
+ end
34
+ end
35
+
36
+ def log_text(level, message:)
37
+ raise('The \'message\' property of log object must not be empty') if message.strip.empty?
38
+
39
+ message = { message: message }
40
+ log_message(level, message: message)
41
+ end
42
+
43
+ def log_object(level, message:)
44
+ message = message.transform_keys(&:to_sym)
45
+ message.key?(:message) || raise('Log object must have a \'message\' property')
46
+ message[:message].strip.empty? && raise('The \'message\' property of log object must not be empty')
47
+
48
+ log_message(level, message: message)
49
+ end
50
+
51
+ def log_message(level, message:)
52
+ base_message = {
53
+ "@timestamp": @now.call.iso8601(3),
54
+ service: {
55
+ name: @service_name
56
+ },
57
+ log: {
58
+ level: level
59
+ }
60
+ }
61
+
62
+ base_message
63
+ .deep_merge(@default_properties.to_nested)
64
+ .deep_merge(message.to_nested)
65
+ .to_json
66
+ end
67
+ end
68
+ end
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'logger'
3
4
  require 'time'
4
5
  require 'json'
6
+ require 'twiglet/formatter'
5
7
  require_relative '../hash_extensions'
6
8
 
7
9
  module Twiglet
8
- class Logger
10
+ class Logger < ::Logger
9
11
  Hash.include HashExtensions
10
12
 
11
13
  def initialize(
@@ -19,26 +21,13 @@ module Twiglet
19
21
  @output = output
20
22
 
21
23
  raise 'Service name is mandatory' \
22
- unless @service_name.is_a?(String) && !@service_name.strip.empty?
24
+ unless service_name.is_a?(String) && !service_name.strip.empty?
23
25
 
24
- @default_properties = default_properties
26
+ formatter = Twiglet::Formatter.new(service_name, default_properties: default_properties, now: now)
27
+ super(output, formatter: formatter)
25
28
  end
26
29
 
27
- def debug(message)
28
- log(level: 'debug', message: message)
29
- end
30
-
31
- def info(message)
32
- log(level: 'info', message: message)
33
- end
34
-
35
- def warning(message)
36
- log(level: 'warning', message: message)
37
- end
38
-
39
- alias_method :warn, :warning
40
-
41
- def error(message, error = nil)
30
+ def error(message = {}, error = nil, &block)
42
31
  if error
43
32
  error_fields = {
44
33
  'error': {
@@ -46,18 +35,12 @@ module Twiglet
46
35
  }
47
36
  }
48
37
  add_stack_trace(error_fields, error)
49
- message = message.merge(error_fields)
38
+ message.is_a?(Hash) ? message.merge!(error_fields) : error_fields.merge!(message: message)
50
39
  end
51
40
 
52
- log(level: 'error', message: message)
53
- end
54
-
55
- def critical(message)
56
- log(level: 'critical', message: message)
41
+ super(message, &block)
57
42
  end
58
43
 
59
- alias_method :fatal, :critical
60
-
61
44
  def with(default_properties)
62
45
  Logger.new(@service_name,
63
46
  default_properties: default_properties,
@@ -65,50 +48,10 @@ module Twiglet
65
48
  output: @output)
66
49
  end
67
50
 
68
- private
69
-
70
- def log(level:, message:)
71
- case message
72
- when String
73
- log_text(level, message: message)
74
- when Hash
75
- log_object(level, message: message)
76
- else
77
- raise('Message must be String or Hash')
78
- end
79
- end
80
-
81
- def log_text(level, message:)
82
- raise('The \'message\' property of log object must not be empty') if message.strip.empty?
83
-
84
- message = { message: message }
85
- log_message(level, message: message)
86
- end
87
-
88
- def log_object(level, message:)
89
- message = message.transform_keys(&:to_sym)
90
- message.key?(:message) || raise('Log object must have a \'message\' property')
91
- message[:message].strip.empty? && raise('The \'message\' property of log object must not be empty')
51
+ alias_method :warning, :warn
52
+ alias_method :critical, :fatal
92
53
 
93
- log_message(level, message: message)
94
- end
95
-
96
- def log_message(level, message:)
97
- base_message = {
98
- "@timestamp": @now.call.iso8601(3),
99
- service: {
100
- name: @service_name
101
- },
102
- log: {
103
- level: level
104
- }
105
- }
106
-
107
- @output.puts base_message
108
- .deep_merge(@default_properties.to_nested)
109
- .deep_merge(message.to_nested)
110
- .to_json
111
- end
54
+ private
112
55
 
113
56
  def add_stack_trace(hash_to_add_to, error)
114
57
  hash_to_add_to[:error][:stack_trace] = error.backtrace.join("\n") if error.backtrace
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Twiglet
4
- VERSION = '2.1.1'
4
+ VERSION = '2.2.0'
5
5
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+ require 'json'
5
+ require_relative '../lib/twiglet/formatter'
6
+
7
+ describe Twiglet::Formatter do
8
+ before do
9
+ @now = -> { Time.utc(2020, 5, 11, 15, 1, 1) }
10
+ @formatter = Twiglet::Formatter.new('petshop', now: @now)
11
+ end
12
+
13
+ it 'initializes an instance of a Ruby Logger Formatter' do
14
+ assert @formatter.is_a?(::Logger::Formatter)
15
+ end
16
+
17
+ it 'returns a formatted log from a string message' do
18
+ msg = @formatter.call('warn', nil, nil, 'shop is running low on dog food')
19
+ expected_log = {
20
+ "@timestamp" => '2020-05-11T15:01:01.000Z',
21
+ "service" => {
22
+ "name" => 'petshop'
23
+ },
24
+ "log" => {
25
+ "level" => 'warn'
26
+ },
27
+ "message" => 'shop is running low on dog food'
28
+ }
29
+ assert_equal JSON.parse(msg), expected_log
30
+ end
31
+ end
@@ -15,10 +15,10 @@ describe Twiglet::Logger do
15
15
  LEVELS = [
16
16
  { method: :debug, level: 'debug' },
17
17
  { method: :info, level: 'info' },
18
- { method: :warning, level: 'warning' },
19
- { method: :warn, level: 'warning' },
20
- { method: :critical, level: 'critical' },
21
- { method: :fatal, level: 'critical' },
18
+ { method: :warning, level: 'warn' },
19
+ { method: :warn, level: 'warn' },
20
+ { method: :critical, level: 'fatal' },
21
+ { method: :fatal, level: 'fatal' },
22
22
  { method: :error, level: 'error' }
23
23
  ].freeze
24
24
 
@@ -28,6 +28,13 @@ describe Twiglet::Logger do
28
28
  end
29
29
  end
30
30
 
31
+ it 'conforms to the standard Ruby Logger API' do
32
+ [:debug, :debug?, :info, :info?, :warn, :warn?, :fatal, :fatal?, :error, :error?,
33
+ :level, :level=, :sev_threshold=].each do |call|
34
+ assert @logger.respond_to?(call), "Logger does not respond to #{call}"
35
+ end
36
+ end
37
+
31
38
  describe 'JSON logging' do
32
39
  it 'should throw an error with an empty message' do
33
40
  assert_raises RuntimeError do
@@ -258,6 +265,32 @@ describe Twiglet::Logger do
258
265
  end
259
266
  end
260
267
 
268
+ describe 'logging with a block' do
269
+ LEVELS.each do |attrs|
270
+ it "should correctly log the block when calling #{attrs[:method]}" do
271
+ block = proc { 'a block log message' }
272
+ @logger.public_send(attrs[:method], &block)
273
+ actual_log = read_json(@buffer)
274
+
275
+ assert_equal attrs[:level], actual_log[:log][:level]
276
+ assert_equal 'a block log message', actual_log[:message]
277
+ end
278
+ end
279
+ end
280
+
281
+ describe 'logger level' do
282
+ [
283
+ { expression: :info, level: 1 },
284
+ { expression: 'warn', level: 2 },
285
+ { expression: Logger::DEBUG, level: 0 }
286
+ ].each do |args|
287
+ it "sets the severity threshold to level #{args[:level]}" do
288
+ @logger.level = args[:expression]
289
+ assert_equal args[:level], @logger.level
290
+ end
291
+ end
292
+ end
293
+
261
294
  private
262
295
 
263
296
  def read_json(buffer)
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.1.1
4
+ version: 2.2.0
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-06-11 00:00:00.000000000 Z
11
+ date: 2020-06-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Like a log, only smaller.
14
14
  email:
@@ -31,8 +31,10 @@ files:
31
31
  - Rakefile
32
32
  - example_app.rb
33
33
  - lib/hash_extensions.rb
34
+ - lib/twiglet/formatter.rb
34
35
  - lib/twiglet/logger.rb
35
36
  - lib/twiglet/version.rb
37
+ - test/formatter_test.rb
36
38
  - test/hash_extensions_test.rb
37
39
  - test/logger_test.rb
38
40
  - twiglet.gemspec
@@ -55,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
57
  - !ruby/object:Gem::Version
56
58
  version: '0'
57
59
  requirements: []
58
- rubygems_version: 3.1.2
60
+ rubygems_version: 3.0.8
59
61
  signing_key:
60
62
  specification_version: 4
61
63
  summary: Twiglet