semantic_logger 4.0.0 → 4.1.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +55 -8
  3. data/lib/semantic_logger.rb +1 -2
  4. data/lib/semantic_logger/ansi_colors.rb +1 -2
  5. data/lib/semantic_logger/appender.rb +17 -15
  6. data/lib/semantic_logger/appender/bugsnag.rb +5 -4
  7. data/lib/semantic_logger/appender/elasticsearch.rb +102 -16
  8. data/lib/semantic_logger/appender/elasticsearch_http.rb +76 -0
  9. data/lib/semantic_logger/appender/file.rb +9 -25
  10. data/lib/semantic_logger/appender/graylog.rb +43 -38
  11. data/lib/semantic_logger/appender/honeybadger.rb +3 -5
  12. data/lib/semantic_logger/appender/http.rb +12 -15
  13. data/lib/semantic_logger/appender/kafka.rb +183 -0
  14. data/lib/semantic_logger/appender/mongodb.rb +3 -3
  15. data/lib/semantic_logger/appender/new_relic.rb +3 -7
  16. data/lib/semantic_logger/appender/sentry.rb +2 -5
  17. data/lib/semantic_logger/appender/splunk.rb +7 -10
  18. data/lib/semantic_logger/appender/splunk_http.rb +16 -16
  19. data/lib/semantic_logger/appender/syslog.rb +43 -122
  20. data/lib/semantic_logger/appender/tcp.rb +28 -9
  21. data/lib/semantic_logger/appender/udp.rb +4 -7
  22. data/lib/semantic_logger/appender/wrapper.rb +3 -7
  23. data/lib/semantic_logger/base.rb +47 -7
  24. data/lib/semantic_logger/formatters/base.rb +29 -10
  25. data/lib/semantic_logger/formatters/color.rb +75 -45
  26. data/lib/semantic_logger/formatters/default.rb +53 -28
  27. data/lib/semantic_logger/formatters/json.rb +7 -8
  28. data/lib/semantic_logger/formatters/raw.rb +97 -1
  29. data/lib/semantic_logger/formatters/syslog.rb +46 -80
  30. data/lib/semantic_logger/formatters/syslog_cee.rb +57 -0
  31. data/lib/semantic_logger/log.rb +17 -67
  32. data/lib/semantic_logger/logger.rb +17 -27
  33. data/lib/semantic_logger/processor.rb +70 -46
  34. data/lib/semantic_logger/semantic_logger.rb +130 -69
  35. data/lib/semantic_logger/subscriber.rb +18 -32
  36. data/lib/semantic_logger/version.rb +1 -1
  37. data/test/appender/elasticsearch_http_test.rb +75 -0
  38. data/test/appender/elasticsearch_test.rb +34 -27
  39. data/test/appender/file_test.rb +2 -2
  40. data/test/appender/honeybadger_test.rb +1 -1
  41. data/test/appender/kafka_test.rb +36 -0
  42. data/test/appender/new_relic_test.rb +1 -1
  43. data/test/appender/sentry_test.rb +1 -1
  44. data/test/appender/syslog_test.rb +2 -2
  45. data/test/appender/wrapper_test.rb +1 -1
  46. data/test/formatters/color_test.rb +154 -0
  47. data/test/formatters/default_test.rb +176 -0
  48. data/test/loggable_test.rb +1 -1
  49. data/test/logger_test.rb +47 -4
  50. data/test/measure_test.rb +2 -2
  51. data/test/semantic_logger_test.rb +34 -6
  52. data/test/test_helper.rb +8 -0
  53. metadata +14 -3
@@ -0,0 +1,176 @@
1
+ require_relative '../test_helper'
2
+
3
+ module SemanticLogger
4
+ module Formatters
5
+ class DefaultTest < Minitest::Test
6
+ describe Default do
7
+ let(:log_time) do
8
+ Time.utc(2017, 1, 14, 8, 32, 5.375276)
9
+ end
10
+
11
+ let(:level) do
12
+ :debug
13
+ end
14
+
15
+ let(:log) do
16
+ # :level, :thread_name, :name, :message, :payload, :time, :duration, :tags, :level_index, :exception, :metric, :backtrace, :metric_amount, :named_tags
17
+ log = SemanticLogger::Log.new('DefaultTest', level)
18
+ log.time = log_time
19
+ log
20
+ end
21
+
22
+ let(:expected_time) do
23
+ SemanticLogger::Formatters::Base::PRECISION == 3 ? '2017-01-14 08:32:05.375' : '2017-01-14 08:32:05.375276'
24
+ end
25
+
26
+ let(:set_exception) do
27
+ begin
28
+ raise 'Oh no'
29
+ rescue Exception => exc
30
+ log.exception = exc
31
+ end
32
+ end
33
+
34
+ let(:backtrace) do
35
+ [
36
+ "test/formatters/default_test.rb:99:in `block (2 levels) in <class:DefaultTest>'",
37
+ "gems/ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/spec.rb:247:in `instance_eval'",
38
+ "gems/ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/spec.rb:247:in `block (2 levels) in let'",
39
+ "gems/ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/spec.rb:247:in `fetch'",
40
+ "ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/spec.rb:247:in `block in let'",
41
+ "test/formatters/default_test.rb:65:in `block (3 levels) in <class:DefaultTest>'",
42
+ "ruby-2.3.3/gems/minitest-5.10.1/lib/minitest/test.rb:105:in `block (3 levels) in run'"
43
+ ]
44
+ end
45
+
46
+ let(:formatter) do
47
+ formatter = SemanticLogger::Formatters::Default.new
48
+ # Does not use the logger instance for formatting purposes
49
+ formatter.call(log, nil)
50
+ formatter
51
+ end
52
+
53
+ describe 'time' do
54
+ it 'logs time' do
55
+ assert_equal expected_time, formatter.time
56
+ end
57
+
58
+ it 'supports time_format' do
59
+ formatter = SemanticLogger::Formatters::Default.new(time_format: "%H:%M:%S")
60
+ formatter.call(log, nil)
61
+ assert_equal '08:32:05', formatter.time
62
+ end
63
+ end
64
+
65
+ describe 'level' do
66
+ it 'logs single character' do
67
+ assert_equal 'D', formatter.level
68
+ end
69
+ end
70
+
71
+ describe 'process_info' do
72
+ it 'logs pid and thread name' do
73
+ assert_equal "[#{$$}:#{Thread.current.name}]", formatter.process_info
74
+ end
75
+
76
+ it 'logs pid, thread name, and file name' do
77
+ set_exception
78
+ log.backtrace = backtrace
79
+ assert_equal "[#{$$}:#{Thread.current.name} default_test.rb:99]", formatter.process_info
80
+ end
81
+ end
82
+
83
+ describe 'tags' do
84
+ it 'logs tags' do
85
+ log.tags = %w(first second third)
86
+ assert_equal "[first] [second] [third]", formatter.tags
87
+ end
88
+ end
89
+
90
+ describe 'named_tags' do
91
+ it 'logs named tags' do
92
+ log.named_tags = {first: 1, second: 2, third: 3}
93
+ assert_equal "{first: 1, second: 2, third: 3}", formatter.named_tags
94
+ end
95
+ end
96
+
97
+ describe 'duration' do
98
+ it 'logs long duration' do
99
+ log.duration = 1_000_000.34567
100
+ assert_equal "(16m 40s)", formatter.duration
101
+ end
102
+
103
+ it 'logs short duration' do
104
+ log.duration = 1.34567
105
+ duration = SemanticLogger::Formatters::Base::PRECISION == 3 ? "(1ms)" : "(1.346ms)"
106
+ assert_equal duration, formatter.duration
107
+ end
108
+ end
109
+
110
+ describe 'name' do
111
+ it 'logs name' do
112
+ assert_equal "DefaultTest", formatter.name
113
+ end
114
+ end
115
+
116
+ describe 'message' do
117
+ it 'logs message' do
118
+ log.message = "Hello World"
119
+ assert_equal "-- Hello World", formatter.message
120
+ end
121
+
122
+ it 'skips empty message' do
123
+ refute formatter.message
124
+ end
125
+ end
126
+
127
+ describe 'payload' do
128
+ it 'logs hash payload' do
129
+ log.payload = {first: 1, second: 2, third: 3}
130
+ assert_equal "-- {:first=>1, :second=>2, :third=>3}", formatter.payload
131
+ end
132
+
133
+ it 'skips nil payload' do
134
+ refute formatter.payload
135
+ end
136
+
137
+ it 'skips empty payload' do
138
+ log.payload = {}
139
+ refute formatter.payload
140
+ end
141
+ end
142
+
143
+ describe 'exception' do
144
+ it 'logs exception' do
145
+ set_exception
146
+ assert_match /-- Exception: RuntimeError: Oh no/, formatter.exception
147
+ end
148
+
149
+ it 'skips nil exception' do
150
+ refute formatter.exception
151
+ end
152
+ end
153
+
154
+ describe 'call' do
155
+ it 'returns minimal elements' do
156
+ assert_equal "#{expected_time} D [#{$$}:#{Thread.current.name}] DefaultTest", formatter.call(log, nil)
157
+ end
158
+
159
+ it 'retuns all elements' do
160
+ log.tags = %w(first second third)
161
+ log.named_tags = {first: 1, second: 2, third: 3}
162
+ log.duration = 1.34567
163
+ log.message = "Hello World"
164
+ log.payload = {first: 1, second: 2, third: 3}
165
+ log.backtrace = backtrace
166
+ set_exception
167
+ duration = SemanticLogger::Formatters::Base::PRECISION == 3 ? '1' : '1.346'
168
+ str = "#{expected_time} D [#{$$}:#{Thread.current.name} default_test.rb:99] [first] [second] [third] {first: 1, second: 2, third: 3} (#{duration}ms) DefaultTest -- Hello World -- {:first=>1, :second=>2, :third=>3} -- Exception: RuntimeError: Oh no\n"
169
+ assert_equal str, formatter.call(log, nil).lines.first
170
+ end
171
+ end
172
+
173
+ end
174
+ end
175
+ end
176
+ end
@@ -76,7 +76,7 @@ class AppenderFileTest < Minitest::Test
76
76
  before do
77
77
  @time = Time.new
78
78
  @io = StringIO.new
79
- @appender = SemanticLogger::Appender::File.new(@io)
79
+ @appender = SemanticLogger::Appender::File.new(io: @io)
80
80
  SemanticLogger.default_level = :trace
81
81
  @mock_logger = MockLogger.new
82
82
  @appender = SemanticLogger.add_appender(logger: @mock_logger)
data/test/logger_test.rb CHANGED
@@ -109,11 +109,11 @@ class LoggerTest < Minitest::Test
109
109
  end
110
110
 
111
111
  it 'logs duration' do
112
- @logger.send(level, duration: 123.45, message: 'Hello world', payload: {tracking_number: '123456', even: 2, more: 'data'})
112
+ @logger.send(level, duration: 123.44, message: 'Hello world', payload: {tracking_number: '123456', even: 2, more: 'data'})
113
113
  hash = {tracking_number: '123456', even: 2, more: 'data'}
114
114
  SemanticLogger.flush
115
115
  hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
116
- duration_match = defined?(JRuby) ? '\(123ms\)' : '\(123\.5ms\)'
116
+ duration_match = SemanticLogger::Formatters::Base::PRECISION == 3 ? '\(123ms\)' : '\(123\.4ms\)'
117
117
  assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] #{duration_match} LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
118
118
  end
119
119
 
@@ -131,11 +131,11 @@ class LoggerTest < Minitest::Test
131
131
  end
132
132
 
133
133
  metric_name = '/my/custom/metric'
134
- @logger.send(level, metric: metric_name, duration: 123.45, message: 'Hello world', payload: {tracking_number: '123456', even: 2, more: 'data'})
134
+ @logger.send(level, metric: metric_name, duration: 123.44, message: 'Hello world', payload: {tracking_number: '123456', even: 2, more: 'data'})
135
135
  hash = {tracking_number: '123456', even: 2, more: 'data'}
136
136
  SemanticLogger.flush
137
137
  hash_str = hash.inspect.sub('{', '\{').sub('}', '\}')
138
- duration_match = defined?(JRuby) ? '\(123ms\)' : '\(123\.5ms\)'
138
+ duration_match = SemanticLogger::Formatters::Base::PRECISION == 3 ? '\(123ms\)' : '\(123\.4ms\)'
139
139
  assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] #{duration_match} LoggerTest -- Hello world -- #{hash_str}/, @mock_logger.message)
140
140
  assert metric_name, $last_metric.metric
141
141
  end
@@ -213,5 +213,48 @@ class LoggerTest < Minitest::Test
213
213
  end
214
214
  end
215
215
 
216
+ describe '.tagged' do
217
+ it 'add tags to log entries' do
218
+ @logger.tagged('12345', 'DJHSFK') do
219
+ @logger.info('Hello world')
220
+ SemanticLogger.flush
221
+ assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \[12345\] \[DJHSFK\] LoggerTest -- Hello world/, @mock_logger.message)
222
+ end
223
+ end
224
+
225
+ it 'add embedded tags to log entries' do
226
+ @logger.tagged('First Level', 'tags') do
227
+ @logger.tagged('Second Level') do
228
+ @logger.info('Hello world')
229
+ SemanticLogger.flush
230
+ assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \[First Level\] \[tags\] \[Second Level\] LoggerTest -- Hello world/, @mock_logger.message)
231
+ end
232
+ assert_equal 2, @logger.tags.count, @logger.tags
233
+ assert_equal 'First Level', @logger.tags.first
234
+ assert_equal 'tags', @logger.tags.last
235
+ end
236
+ end
237
+
238
+ it 'also supports named tagging' do
239
+ @logger.tagged(level1: 1) do
240
+ assert_equal({level1: 1}, SemanticLogger.named_tags)
241
+ @logger.tagged(level2: 2, more: 'data') do
242
+ assert_equal({level1: 1, level2: 2, more: 'data'}, SemanticLogger.named_tags)
243
+ @logger.tagged(level3: 3) do
244
+ assert_equal({level1: 1, level2: 2, more: 'data', level3: 3}, SemanticLogger.named_tags)
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+ it 'is compatible with rails logging that uses arrays and nils' do
251
+ @logger.tagged('', ['12345', 'DJHSFK'], nil) do
252
+ @logger.info('Hello world')
253
+ SemanticLogger.flush
254
+ assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \[12345\] \[DJHSFK\] LoggerTest -- Hello world/, @mock_logger.message)
255
+ end
256
+ end
257
+ end
258
+
216
259
  end
217
260
  end
data/test/measure_test.rb CHANGED
@@ -44,7 +44,7 @@ class MeasureTest < Minitest::Test
44
44
 
45
45
  describe ':min_duration' do
46
46
  it 'not log when faster' do
47
- assert_equal 'result', @logger.send(measure_level, 'hello world', min_duration: 1000) { 'result' } # Measure duration of the supplied block
47
+ assert_equal 'result', @logger.send(measure_level, 'hello world', min_duration: 2000) { 'result' } # Measure duration of the supplied block
48
48
  SemanticLogger.flush
49
49
  assert_nil @mock_logger.message
50
50
  end
@@ -156,7 +156,7 @@ class MeasureTest < Minitest::Test
156
156
 
157
157
  describe ':min_duration' do
158
158
  it 'not log when faster' do
159
- assert_equal 'result', @logger.send(measure_level, message: 'hello world', min_duration: 1000) { 'result' } # Measure duration of the supplied block
159
+ assert_equal 'result', @logger.send(measure_level, message: 'hello world', min_duration: 2000) { 'result' } # Measure duration of the supplied block
160
160
  SemanticLogger.flush
161
161
  assert_nil @mock_logger.message
162
162
  end
@@ -156,15 +156,43 @@ class SemanticLoggerTest < Minitest::Test
156
156
  assert_equal 'tags', SemanticLogger.tags.last
157
157
  end
158
158
  end
159
+
160
+ it 'also supports named tagging' do
161
+ SemanticLogger.tagged(level1: 1) do
162
+ assert_equal({level1: 1}, SemanticLogger.named_tags)
163
+ SemanticLogger.tagged(level2: 2, more: 'data') do
164
+ assert_equal({level1: 1, level2: 2, more: 'data'}, SemanticLogger.named_tags)
165
+ SemanticLogger.tagged(level3: 3) do
166
+ assert_equal({level1: 1, level2: 2, more: 'data', level3: 3}, SemanticLogger.named_tags)
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+
173
+ describe '.named_tags' do
174
+ it 'returns named tags in creation order' do
175
+ SemanticLogger.named_tagged(level1: 1) do
176
+ assert_equal({level1: 1}, SemanticLogger.named_tags)
177
+ SemanticLogger.named_tagged(level2: 2, more: 'data') do
178
+ assert_equal({level1: 1, level2: 2, more: 'data'}, SemanticLogger.named_tags)
179
+ SemanticLogger.named_tagged(level3: 3) do
180
+ assert_equal({level1: 1, level2: 2, more: 'data', level3: 3}, SemanticLogger.named_tags)
181
+ end
182
+ end
183
+ end
184
+ end
159
185
  end
160
186
 
161
187
  describe '.named_tagged' do
162
- it 'logs named tags' do
163
- SemanticLogger.named_tagged(tracking_number: '123456') do
164
- SemanticLogger.named_tagged(even: 2, more: 'data') do
165
- @logger.info('Hello world')
166
- SemanticLogger.flush
167
- assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \[even: 2\] \[more: data\] \[tracking_number: 123456\] LoggerTest -- Hello world/, @mock_logger.message)
188
+ it 'logs named tags in creation order' do
189
+ SemanticLogger.named_tagged(level1: 1) do
190
+ SemanticLogger.named_tagged(level2: 2, more: 'data') do
191
+ SemanticLogger.named_tagged(level3: 3) do
192
+ @logger.info('Hello world')
193
+ SemanticLogger.flush
194
+ assert_match(/\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \{level1: 1, level2: 2, more: data, level3: 3\} LoggerTest -- Hello world/, @mock_logger.message)
195
+ end
168
196
  end
169
197
  end
170
198
  end
data/test/test_helper.rb CHANGED
@@ -13,3 +13,11 @@ require_relative 'mock_logger'
13
13
  require 'awesome_print'
14
14
 
15
15
  #Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
16
+ Signal.trap('TTIN') do
17
+ Thread.list.each do |thread|
18
+ puts
19
+ puts
20
+ ap thread.name
21
+ ap thread.backtrace
22
+ end
23
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semantic_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-02 00:00:00.000000000 Z
11
+ date: 2017-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -40,10 +40,12 @@ files:
40
40
  - lib/semantic_logger/appender.rb
41
41
  - lib/semantic_logger/appender/bugsnag.rb
42
42
  - lib/semantic_logger/appender/elasticsearch.rb
43
+ - lib/semantic_logger/appender/elasticsearch_http.rb
43
44
  - lib/semantic_logger/appender/file.rb
44
45
  - lib/semantic_logger/appender/graylog.rb
45
46
  - lib/semantic_logger/appender/honeybadger.rb
46
47
  - lib/semantic_logger/appender/http.rb
48
+ - lib/semantic_logger/appender/kafka.rb
47
49
  - lib/semantic_logger/appender/mongodb.rb
48
50
  - lib/semantic_logger/appender/new_relic.rb
49
51
  - lib/semantic_logger/appender/sentry.rb
@@ -63,6 +65,7 @@ files:
63
65
  - lib/semantic_logger/formatters/json.rb
64
66
  - lib/semantic_logger/formatters/raw.rb
65
67
  - lib/semantic_logger/formatters/syslog.rb
68
+ - lib/semantic_logger/formatters/syslog_cee.rb
66
69
  - lib/semantic_logger/jruby/garbage_collection_logger.rb
67
70
  - lib/semantic_logger/log.rb
68
71
  - lib/semantic_logger/loggable.rb
@@ -75,11 +78,13 @@ files:
75
78
  - lib/semantic_logger/subscriber.rb
76
79
  - lib/semantic_logger/version.rb
77
80
  - test/appender/bugsnag_test.rb
81
+ - test/appender/elasticsearch_http_test.rb
78
82
  - test/appender/elasticsearch_test.rb
79
83
  - test/appender/file_test.rb
80
84
  - test/appender/graylog_test.rb
81
85
  - test/appender/honeybadger_test.rb
82
86
  - test/appender/http_test.rb
87
+ - test/appender/kafka_test.rb
83
88
  - test/appender/mongodb_test.rb
84
89
  - test/appender/new_relic_test.rb
85
90
  - test/appender/newrelic_rpm.rb
@@ -92,6 +97,8 @@ files:
92
97
  - test/appender/wrapper_test.rb
93
98
  - test/concerns/compatibility_test.rb
94
99
  - test/debug_as_trace_logger_test.rb
100
+ - test/formatters/color_test.rb
101
+ - test/formatters/default_test.rb
95
102
  - test/loggable_test.rb
96
103
  - test/logger_test.rb
97
104
  - test/measure_test.rb
@@ -118,17 +125,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
125
  version: '0'
119
126
  requirements: []
120
127
  rubyforge_project:
121
- rubygems_version: 2.6.8
128
+ rubygems_version: 2.6.11
122
129
  signing_key:
123
130
  specification_version: 4
124
131
  summary: Scalable, next generation enterprise logging for Ruby
125
132
  test_files:
126
133
  - test/appender/bugsnag_test.rb
134
+ - test/appender/elasticsearch_http_test.rb
127
135
  - test/appender/elasticsearch_test.rb
128
136
  - test/appender/file_test.rb
129
137
  - test/appender/graylog_test.rb
130
138
  - test/appender/honeybadger_test.rb
131
139
  - test/appender/http_test.rb
140
+ - test/appender/kafka_test.rb
132
141
  - test/appender/mongodb_test.rb
133
142
  - test/appender/new_relic_test.rb
134
143
  - test/appender/newrelic_rpm.rb
@@ -141,6 +150,8 @@ test_files:
141
150
  - test/appender/wrapper_test.rb
142
151
  - test/concerns/compatibility_test.rb
143
152
  - test/debug_as_trace_logger_test.rb
153
+ - test/formatters/color_test.rb
154
+ - test/formatters/default_test.rb
144
155
  - test/loggable_test.rb
145
156
  - test/logger_test.rb
146
157
  - test/measure_test.rb