betterlog 0.1.0 → 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.
@@ -0,0 +1,221 @@
1
+ require 'spec_helper'
2
+
3
+ describe Betterlog::Log do
4
+ around do |example|
5
+ Time.dummy '2011-11-11 11:11:11+01:00' do
6
+ example.run
7
+ end
8
+ end
9
+
10
+ let :instance do
11
+ described_class.instance
12
+ end
13
+
14
+ let :event do
15
+ Log::Event.ify('hello')
16
+ end
17
+
18
+ describe 'Log::Event.ify' do
19
+ it 'can eventify a string' do
20
+ expect(event).to be_a Log::Event
21
+ end
22
+
23
+ it 'can eventify a hash' do
24
+ event = Log::Event.ify(message: 'hallo')
25
+ expect(event).to be_a Log::Event
26
+ end
27
+ end
28
+
29
+ describe '.parse' do
30
+ it 'can parse an event as a JSON document' do
31
+ expect(Log::Event.parse(event.to_json)).to eq event
32
+ end
33
+ end
34
+
35
+ describe "#[severity]" do
36
+ it 'logs freetext, unstructured messages to Rails.logger on used log level' do
37
+ for severity in %i[ debug error fatal info warn ] do
38
+ log_event = Log::Event.new(
39
+ message: 'some freetext message',
40
+ severity: severity
41
+ )
42
+ expect(instance).to receive(:emit).with(log_event)
43
+ Log.instance.send(severity, 'some freetext message')
44
+ end
45
+ end
46
+ end
47
+
48
+ describe '#output' do
49
+ it 'logs freetext, unstructured messages to Rails.logger on given log level' do
50
+ log_event = Log::Event.new(
51
+ message: 'some freetext message',
52
+ severity: :warn
53
+ )
54
+ expect(instance).to receive(:emit).with(log_event)
55
+ Log.output('some freetext message', severity: :warn)
56
+ end
57
+ end
58
+
59
+ describe '#info with internal logging error' do
60
+ it 'should not crash ever, just log the problem to Rails.logger' do
61
+ expect_any_instance_of(instance.logger.class).to receive(:fatal).and_call_original
62
+ expect(Log.info(BasicObject.new)).to eq Log.instance
63
+ end
64
+ end
65
+
66
+ describe '#notify?' do
67
+ let :notifier do
68
+ Class.new do
69
+ def notify(message, hash) end
70
+ end.new
71
+ end
72
+
73
+ around do |example|
74
+ Betterlog::Notifiers.register(notifier)
75
+ example.run
76
+ ensure
77
+ Betterlog::Notifiers.notifiers.clear
78
+ end
79
+
80
+ it 'can send explicit notifications' do
81
+ expect(notifier).to receive(:notify).with(
82
+ 'test',
83
+ hash_including(message: 'test')
84
+ )
85
+ Log.info('test', notify: true)
86
+ end
87
+
88
+ it 'can send explicit notifications with additional hash values' do
89
+ expect(notifier).to receive(:notify).with(
90
+ 'test',
91
+ hash_including(message: 'test', foo: 'bar')
92
+ )
93
+ Log.info({ message: 'test', foo: 'bar' }, notify: true)
94
+ end
95
+
96
+ it 'can send explicit notifications for exceptions' do
97
+ e = raise "foo" rescue $!
98
+ expect(notifier).to receive(:notify).with(
99
+ 'RuntimeError: foo',
100
+ hash_including(
101
+ error_class: 'RuntimeError'
102
+ )
103
+ )
104
+ Log.info(e, notify: true)
105
+ end
106
+ end
107
+
108
+ describe '#output exceptions' do
109
+ it 'logs ruby standard errors' do
110
+ exception = ArgumentError.new('unknown keyword: xyz')
111
+ exception.set_backtrace(Thread.current.backtrace)
112
+ expected_event = Log::Event.new(
113
+ error_class: exception.class.name,
114
+ message: "#{exception.class.name}: #{exception.message}",
115
+ backtrace: exception.backtrace,
116
+ )
117
+ expect(instance).to receive(:emit).with(expected_event)
118
+ Log.output(exception)
119
+ end
120
+
121
+ it 'logs a ruby exception with additional data' do
122
+ exception = ArgumentError.new('unknown keyword: xyz')
123
+ exception.set_backtrace(Thread.current.backtrace)
124
+ expected_event = Log::Event.new(
125
+ foo: 'bar',
126
+ error_class: exception.class.name,
127
+ message: "#{exception.class.name}: #{exception.message}",
128
+ backtrace: exception.backtrace,
129
+ severity: :error,
130
+ )
131
+ expect(instance).to receive(:emit).with(expected_event)
132
+ Log.error(exception, foo: 'bar')
133
+ end
134
+ end
135
+
136
+ describe '#measure' do
137
+ after do
138
+ Time.dummy = nil
139
+ end
140
+
141
+ it 'can be sent after measuring times' do
142
+ expected_event = Log::Event.new(
143
+ message: 'a metric foo of type seconds',
144
+ metric: 'foo',
145
+ type: 'seconds',
146
+ value: 10.0,
147
+ timestamp: "2011-11-11T10:11:21.000Z"
148
+ )
149
+ expect(instance).to receive(:emit).with(expected_event)
150
+ Log.measure(metric: 'foo') do
151
+ Time.dummy = Time.now + 10
152
+ end
153
+ end
154
+
155
+ class MyEx < StandardError
156
+ def backtrace
157
+ []
158
+ end
159
+ end
160
+
161
+ it 'adds exception information if block raises' do
162
+ expected_event = Log::Event.new(
163
+ metric: 'foo',
164
+ type: 'seconds',
165
+ value: 10.0,
166
+ timestamp: "2011-11-11T10:11:21.000Z",
167
+ message: 'MyEx: we were fucked while measuring metric foo',
168
+ error_class: 'MyEx',
169
+ backtrace: [],
170
+ )
171
+ expect(instance).to receive(:emit).with(expected_event)
172
+ raised = false
173
+ begin
174
+ Log.measure(metric: 'foo') do
175
+ Time.dummy = Time.now + 10
176
+ raise MyEx, "we were fucked"
177
+ end
178
+ rescue MyEx
179
+ raised = true
180
+ end
181
+ expect(raised).to eq true
182
+ end
183
+ end
184
+
185
+ describe '#metric' do
186
+ it 'logs metrics with a specific structure on debug log level' do
187
+ expected_event = Log::Event.new(
188
+ message: 'a metric controller.action of type ms',
189
+ metric: 'controller.action',
190
+ type: 'ms',
191
+ value: 0.123,
192
+ )
193
+ expect(instance).to receive(:emit).with(expected_event)
194
+ Log.metric(metric: 'controller.action', type: 'ms', value: 0.123)
195
+ end
196
+
197
+ it 'logs metrics on a given log level' do
198
+ expected_event = Log::Event.new(
199
+ message: 'a metric controller.action of type ms',
200
+ metric: 'controller.action',
201
+ type: 'ms',
202
+ value: 0.123,
203
+ severity: :info,
204
+ )
205
+ expect(instance).to receive(:emit).with(expected_event)
206
+ Log.metric(severity: :info, metric: 'controller.action', type: 'ms', value: 0.123)
207
+ end
208
+
209
+ it 'logs metrics with additional data' do
210
+ expected_event = Log::Event.new(
211
+ message: 'a metric controller.action of type ms',
212
+ foo: 'bar',
213
+ metric: 'controller.action',
214
+ type: 'ms',
215
+ value: 0.123,
216
+ )
217
+ expect(instance).to receive(:emit).with(expected_event)
218
+ Log.metric(metric: 'controller.action', type: 'ms', value: 0.123, foo: 'bar')
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe Betterlog::Logger do
4
+ let :logger do
5
+ described_class.new(Redis.new)
6
+ end
7
+
8
+ describe '#<<' do
9
+ it 'writes to redis' do
10
+ expect(logger.instance_variable_get(:@redis)).to receive(:append).
11
+ with('Betterlog::Logger', 'foo')
12
+ logger << 'foo'
13
+ end
14
+ end
15
+
16
+ describe '#add' do
17
+ it 'writes to redis' do
18
+ expect(logger.instance_variable_get(:@redis)).to receive(:append).
19
+ with('Betterlog::Logger', /INFO -- : foo/)
20
+ logger.info 'foo'
21
+ end
22
+ end
23
+
24
+ describe '#each_chunk' do
25
+ it 'iterates over chunks of data' do
26
+ logger.clear
27
+ logger << "foo" * 23
28
+ expect(logger.each_chunk(chunk_size: 10).to_a).to eq %w[
29
+ foofoofoof
30
+ oofoofoofo
31
+ ofoofoofoo
32
+ foofoofoof
33
+ oofoofoofo
34
+ ofoofoofoo
35
+ foofoofoo
36
+ ]
37
+ end
38
+
39
+ it 'works if no data is there' do
40
+ logger.clear
41
+ expect(logger.each_chunk(chunk_size: 1).to_a).to eq []
42
+ end
43
+
44
+ it 'iterates if chunk_size is 1 and 23' do
45
+ logger.clear
46
+ logger << ?. * 23
47
+ expect(logger.each_chunk(chunk_size: 1).to_a).to eq [ ?. ] * 23
48
+ end
49
+
50
+ it 'iterates if chunk_size is 1 and 22' do
51
+ logger.clear
52
+ logger << ?. * 22
53
+ expect(logger.each_chunk(chunk_size: 1).to_a).to eq [ ?. ] * 22
54
+ end
55
+ end
56
+
57
+ describe '#each' do
58
+ it 'iterates over log lines' do
59
+ logger.clear
60
+ logger << "foo\n"
61
+ logger << "bar\n"
62
+ expect(logger.to_a).to eq [ "foo\n", "bar\n" ]
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,13 @@
1
+ if ENV['START_SIMPLECOV'].to_i == 1
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "#{File.basename(File.dirname(__FILE__))}/"
5
+ end
6
+ end
7
+ require 'rspec'
8
+ begin
9
+ require 'byebug'
10
+ rescue LoadError
11
+ end
12
+ require 'betterlog'
13
+ Betterlog::Log.default_logger = Logger.new(nil)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: betterlog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - betterplace Developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-10 00:00:00.000000000 Z
11
+ date: 2019-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_hadar
@@ -39,45 +39,53 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: tins
42
+ name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '1.3'
48
45
  - - ">="
49
46
  - !ruby/object:Gem::Version
50
- version: 1.3.5
51
- type: :runtime
47
+ version: '0'
48
+ type: :development
52
49
  prerelease: false
53
50
  version_requirements: !ruby/object:Gem::Requirement
54
51
  requirements:
55
- - - "~>"
56
- - !ruby/object:Gem::Version
57
- version: '1.3'
58
52
  - - ">="
59
53
  - !ruby/object:Gem::Version
60
- version: 1.3.5
54
+ version: '0'
61
55
  - !ruby/object:Gem::Dependency
62
- name: rails
56
+ name: simplecov
63
57
  requirement: !ruby/object:Gem::Requirement
64
58
  requirements:
65
59
  - - ">="
66
60
  - !ruby/object:Gem::Version
67
- version: '3'
68
- - - "<"
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'
69
+ - !ruby/object:Gem::Dependency
70
+ name: tins
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
69
74
  - !ruby/object:Gem::Version
70
- version: '6'
75
+ version: '1.3'
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 1.3.5
71
79
  type: :runtime
72
80
  prerelease: false
73
81
  version_requirements: !ruby/object:Gem::Requirement
74
82
  requirements:
75
- - - ">="
83
+ - - "~>"
76
84
  - !ruby/object:Gem::Version
77
- version: '3'
78
- - - "<"
85
+ version: '1.3'
86
+ - - ">="
79
87
  - !ruby/object:Gem::Version
80
- version: '6'
88
+ version: 1.3.5
81
89
  - !ruby/object:Gem::Dependency
82
90
  name: complex_config
83
91
  requirement: !ruby/object:Gem::Requirement
@@ -134,44 +142,86 @@ dependencies:
134
142
  - - "~>"
135
143
  - !ruby/object:Gem::Version
136
144
  version: '1.3'
145
+ - !ruby/object:Gem::Dependency
146
+ name: redis
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '2.4'
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '2.4'
159
+ - !ruby/object:Gem::Dependency
160
+ name: excon
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
137
173
  description: This library provides structure json logging for our rails projects
138
174
  email: developers@betterplace.org
139
175
  executables:
140
176
  - betterlog
177
+ - betterlog_pusher
141
178
  extensions: []
142
179
  extra_rdoc_files:
143
180
  - README.md
144
- - lib/betterdocs/version.rb
145
181
  - lib/betterlog.rb
146
- - lib/betterlog/betterlog_railtie.rb
147
182
  - lib/betterlog/global_metadata.rb
148
183
  - lib/betterlog/log.rb
149
184
  - lib/betterlog/log/event.rb
150
185
  - lib/betterlog/log/event_formatter.rb
151
186
  - lib/betterlog/log/severity.rb
152
187
  - lib/betterlog/log_event_formatter.rb
188
+ - lib/betterlog/logger.rb
189
+ - lib/betterlog/notifiers.rb
190
+ - lib/betterlog/railtie.rb
153
191
  - lib/betterlog/version.rb
154
192
  files:
155
193
  - ".gitignore"
194
+ - ".travis.yml"
195
+ - Dockerfile
156
196
  - Gemfile
157
197
  - LICENSE
198
+ - Makefile
158
199
  - README.md
159
200
  - Rakefile
201
+ - TODO.md
160
202
  - VERSION
161
- - betterdocs.gemspec
162
203
  - betterlog.gemspec
204
+ - betterlog/healthz.go
163
205
  - bin/betterlog
164
- - lib/betterdocs/version.rb
206
+ - bin/betterlog_pusher
207
+ - cmd/betterlog-server/LICENSE
208
+ - cmd/betterlog-server/main.go
209
+ - config/log.yml
165
210
  - lib/betterlog.rb
166
- - lib/betterlog/betterlog_railtie.rb
167
211
  - lib/betterlog/global_metadata.rb
168
212
  - lib/betterlog/log.rb
169
213
  - lib/betterlog/log/event.rb
170
214
  - lib/betterlog/log/event_formatter.rb
171
215
  - lib/betterlog/log/severity.rb
172
216
  - lib/betterlog/log_event_formatter.rb
217
+ - lib/betterlog/logger.rb
218
+ - lib/betterlog/notifiers.rb
219
+ - lib/betterlog/railtie.rb
173
220
  - lib/betterlog/version.rb
174
- - log.yml
221
+ - spec/betterlog/global_metadata_spec.rb
222
+ - spec/betterlog/log_spec.rb
223
+ - spec/betterlog/logger_spec.rb
224
+ - spec/spec_helper.rb
175
225
  homepage: http://github.com/betterplace/betterlog
176
226
  licenses: []
177
227
  metadata: {}
@@ -194,8 +244,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
244
  - !ruby/object:Gem::Version
195
245
  version: '0'
196
246
  requirements: []
197
- rubygems_version: 3.0.1
247
+ rubygems_version: 3.0.3
198
248
  signing_key:
199
249
  specification_version: 4
200
250
  summary: Structured logging support for bp
201
- test_files: []
251
+ test_files:
252
+ - spec/betterlog/global_metadata_spec.rb
253
+ - spec/betterlog/log_spec.rb
254
+ - spec/betterlog/logger_spec.rb
255
+ - spec/spec_helper.rb
data/betterdocs.gemspec DELETED
@@ -1,53 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- # stub: betterdocs 0.0.1 ruby lib
3
-
4
- Gem::Specification.new do |s|
5
- s.name = "betterdocs".freeze
6
- s.version = "0.0.1"
7
-
8
- s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
- s.require_paths = ["lib".freeze]
10
- s.authors = ["betterplace Developers".freeze]
11
- s.date = "2018-12-05"
12
- s.description = "This library provides structure json logging for our rails projects".freeze
13
- s.email = "developers@betterplace.org".freeze
14
- s.extra_rdoc_files = ["README.md".freeze, "lib/betterlog.rb".freeze, "lib/betterlog/event.rb".freeze, "lib/betterlog/event_formatter.rb".freeze, "lib/betterlog/log.rb".freeze, "lib/betterlog/log_event_formatter.rb".freeze, "lib/betterlog/severity.rb".freeze]
15
- s.files = ["README.md".freeze, "lib/betterlog.rb".freeze, "lib/betterlog/event.rb".freeze, "lib/betterlog/event_formatter.rb".freeze, "lib/betterlog/log.rb".freeze, "lib/betterlog/log_event_formatter.rb".freeze, "lib/betterlog/severity.rb".freeze]
16
- s.homepage = "http://github.com/betterplace/betterdocs".freeze
17
- s.rdoc_options = ["--title".freeze, "Betterdocs".freeze, "--main".freeze, "README.md".freeze]
18
- s.rubygems_version = "2.7.6".freeze
19
- s.summary = "Structured logging support for bp".freeze
20
-
21
- if s.respond_to? :specification_version then
22
- s.specification_version = 4
23
-
24
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
25
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
26
- s.add_development_dependency(%q<rake>.freeze, [">= 0"])
27
- s.add_runtime_dependency(%q<tins>.freeze, [">= 1.3.5", "~> 1.3"])
28
- s.add_runtime_dependency(%q<rails>.freeze, ["< 6", ">= 3"])
29
- s.add_runtime_dependency(%q<complex_config>.freeze, [">= 0"])
30
- s.add_runtime_dependency(%q<file-tail>.freeze, ["~> 1.0"])
31
- s.add_runtime_dependency(%q<json>.freeze, ["~> 2.0"])
32
- s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.3"])
33
- else
34
- s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
35
- s.add_dependency(%q<rake>.freeze, [">= 0"])
36
- s.add_dependency(%q<tins>.freeze, [">= 1.3.5", "~> 1.3"])
37
- s.add_dependency(%q<rails>.freeze, ["< 6", ">= 3"])
38
- s.add_dependency(%q<complex_config>.freeze, [">= 0"])
39
- s.add_dependency(%q<file-tail>.freeze, ["~> 1.0"])
40
- s.add_dependency(%q<json>.freeze, ["~> 2.0"])
41
- s.add_dependency(%q<term-ansicolor>.freeze, ["~> 1.3"])
42
- end
43
- else
44
- s.add_dependency(%q<gem_hadar>.freeze, ["~> 1.9.1"])
45
- s.add_dependency(%q<rake>.freeze, [">= 0"])
46
- s.add_dependency(%q<tins>.freeze, [">= 1.3.5", "~> 1.3"])
47
- s.add_dependency(%q<rails>.freeze, ["< 6", ">= 3"])
48
- s.add_dependency(%q<complex_config>.freeze, [">= 0"])
49
- s.add_dependency(%q<file-tail>.freeze, ["~> 1.0"])
50
- s.add_dependency(%q<json>.freeze, ["~> 2.0"])
51
- s.add_dependency(%q<term-ansicolor>.freeze, ["~> 1.3"])
52
- end
53
- end
@@ -1,8 +0,0 @@
1
- module Betterdocs
2
- # Betterdocs version
3
- VERSION = '0.0.1'
4
- VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
- VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
- VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
7
- VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
8
- end
@@ -1,5 +0,0 @@
1
- class BetterlogRailtie < Rails::Railtie
2
- initializer "betterlog_railtie.configure_rails_initialization" do
3
- Rails.logger.formatter = LogEventFormatter.new
4
- end
5
- end