betterlog 0.1.0 → 0.2.0

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