semantic_logger 4.0.0 → 4.1.0

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