timber 2.1.0.rc4 → 2.1.0.rc5
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.
- checksums.yaml +4 -4
- data/README.md +8 -2
- data/lib/timber/frameworks/rails.rb +12 -47
- data/lib/timber/integrations/rails/rack_logger.rb +13 -4
- data/lib/timber/logger.rb +19 -0
- data/lib/timber/version.rb +1 -1
- data/spec/timber/logger_spec.rb +75 -45
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bb5abd9ff785281715e45354703c1b9c3f2b25b
|
4
|
+
data.tar.gz: 347d46a12f3880a73e28d595554c5f838bb59eb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 553e015f5deecc539ec6437e7ae661f2e75d0d3bee6e92b095efb05f5ce180a7bc7ba7d710ca5749f022d61e3ed26e1f0b02cb1e778693f1f5553cf15570d9c8
|
7
|
+
data.tar.gz: 979086f4ac6d10bb38276696eed64b3ccf9cb79b2b057c8f83d3e1e045959735e4d9ab0cc47874cd21d2e4ba0bebd87382576436e94aff15204c0d9dcccc2944
|
data/README.md
CHANGED
@@ -59,7 +59,7 @@ Sent 200 in 45.2ms @metadata {"dt": "2017-02-02T01:33:21.154345Z", "level": "inf
|
|
59
59
|
```
|
60
60
|
|
61
61
|
Notice that instead of completely replacing your log messages,
|
62
|
-
Timber _augments_ your logs with structured metadata. Turning
|
62
|
+
Timber _augments_ your logs with structured metadata. Turning them into
|
63
63
|
[rich events with context](https://timber.io/docs/ruby/events-and-context) without sacrificing
|
64
64
|
readability. And you have [complete control over which data is captured](#configuration).
|
65
65
|
|
@@ -213,7 +213,13 @@ logger.info("Processed background job", background_job: {time_ms: timer})
|
|
213
213
|
# => Processed background job in 54.2ms @metadata {"level": "info", "event": {"background_job": {"time_ms": 54.2}}}
|
214
214
|
```
|
215
215
|
|
216
|
-
|
216
|
+
And of course, `time_ms` can also take a `Float`:
|
217
|
+
|
218
|
+
```ruby
|
219
|
+
logger.info("Processed background job", background_job: {time_ms: 45.6})
|
220
|
+
```
|
221
|
+
|
222
|
+
Lastly, metrics aren't limited to timings. You can capture any metric you want:
|
217
223
|
|
218
224
|
```ruby
|
219
225
|
logger = Timber::Logger.new(STDOUT)
|
@@ -3,47 +3,6 @@ module Timber
|
|
3
3
|
# Module for Rails specific code, such as the Railtie and any methods that assist
|
4
4
|
# with Rails setup.
|
5
5
|
module Rails
|
6
|
-
# Because of the crazy way Rails sorts it's initializers, it is
|
7
|
-
# impossible for Timber to be inserted after Devise's omnitauth
|
8
|
-
# middlewares.
|
9
|
-
# See: https://github.com/plataformatec/devise/blob/master/lib/devise/rails.rb#L22
|
10
|
-
# As such, we take a brute force approach here, ensuring we are inserted last
|
11
|
-
# no matter what. This ensures that we come after authentication so that we can
|
12
|
-
# properly set the user context.
|
13
|
-
#
|
14
|
-
# @private
|
15
|
-
module MiddlewareStackProxyFix
|
16
|
-
def self.included(klass)
|
17
|
-
klass.class_eval do
|
18
|
-
attr_accessor :timber_operations
|
19
|
-
|
20
|
-
alias old_merge_into merge_into
|
21
|
-
|
22
|
-
# This method does not exist for older versions of rails
|
23
|
-
begin
|
24
|
-
alias old_plus +
|
25
|
-
rescue NameError
|
26
|
-
end
|
27
|
-
|
28
|
-
def +(*args)
|
29
|
-
result = old_plus(*args)
|
30
|
-
result.timber_operations = timber_operations
|
31
|
-
result
|
32
|
-
end
|
33
|
-
|
34
|
-
def merge_into(*args)
|
35
|
-
if timber_operations
|
36
|
-
@operations -= timber_operations
|
37
|
-
@operations += timber_operations
|
38
|
-
end
|
39
|
-
old_merge_into(*args)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
::Rails::Configuration::MiddlewareStackProxy.send(:include, MiddlewareStackProxyFix)
|
46
|
-
|
47
6
|
# Installs Timber into your Rails app automatically.
|
48
7
|
class Railtie < ::Rails::Railtie
|
49
8
|
config.timber = Config.instance
|
@@ -52,20 +11,26 @@ module Timber
|
|
52
11
|
Timber::Config.instance.logger = Proc.new { ::Rails.logger }
|
53
12
|
end
|
54
13
|
|
14
|
+
after =
|
15
|
+
begin
|
16
|
+
require 'devise'
|
17
|
+
'devise.omniauth'
|
18
|
+
rescue LoadError
|
19
|
+
:load_config_initializers
|
20
|
+
end
|
21
|
+
|
55
22
|
# Must be loaded after initializers so that we respect any Timber configuration
|
56
23
|
# set
|
57
|
-
initializer(:timber, after:
|
24
|
+
initializer(:timber, before: :build_middleware_stack, after: after) do
|
58
25
|
Integrations.integrate!
|
59
26
|
|
60
27
|
# Install the Rack middlewares so that we capture structured data instead of
|
61
28
|
# raw text logs.
|
62
|
-
|
63
|
-
|
29
|
+
Integrations::Rack.middlewares.collect do |middleware_class|
|
30
|
+
config.app_middleware.use middleware_class
|
64
31
|
end
|
65
|
-
|
66
|
-
config.app_middleware.timber_operations = timber_operations
|
67
32
|
end
|
68
33
|
end
|
69
34
|
end
|
70
35
|
end
|
71
|
-
end
|
36
|
+
end
|
@@ -19,10 +19,19 @@ module Timber
|
|
19
19
|
def self.included(klass)
|
20
20
|
klass.class_eval do
|
21
21
|
private
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
if ::Rails::VERSION::MAJOR == 3
|
23
|
+
# Rails 3.2 calls Rails.logger directly in call_app, so we
|
24
|
+
# will just replace it with a version that doesn't
|
25
|
+
def call_app(_, env)
|
26
|
+
# Put some space between requests in development logs.
|
27
|
+
if ::Rails.env.development?
|
28
|
+
::Rails.logger.info ''
|
29
|
+
::Rails.logger.info ''
|
30
|
+
end
|
31
|
+
@app.call(env)
|
32
|
+
ensure
|
33
|
+
ActiveSupport::LogSubscriber.flush_all!
|
34
|
+
end
|
26
35
|
end
|
27
36
|
|
28
37
|
# Rails > 3.2 uses a logger method. Muting logs is accomplished by
|
data/lib/timber/logger.rb
CHANGED
@@ -232,6 +232,13 @@ module Timber
|
|
232
232
|
super
|
233
233
|
end
|
234
234
|
|
235
|
+
def level=(value)
|
236
|
+
if value.is_a?(Symbol)
|
237
|
+
value = level_from_symbol(value)
|
238
|
+
end
|
239
|
+
super
|
240
|
+
end
|
241
|
+
|
235
242
|
# Convenience method for adding context. Please see {{Timber::CurrentContext.with}} for
|
236
243
|
# a more detailed description and examples.
|
237
244
|
def with_context(context, &block)
|
@@ -270,5 +277,17 @@ module Timber
|
|
270
277
|
level = ([ENV['LOG_LEVEL'].to_s.upcase, "DEBUG"] & %w[DEBUG INFO WARN ERROR FATAL UNKNOWN]).compact.first
|
271
278
|
self.class.const_get(level)
|
272
279
|
end
|
280
|
+
|
281
|
+
def level_from_symbol(value)
|
282
|
+
case value
|
283
|
+
when :debug; DEBUG
|
284
|
+
when :info; INFO
|
285
|
+
when :warn; WARN
|
286
|
+
when :error; ERROR
|
287
|
+
when :fatal; FATAL
|
288
|
+
when :unknown; UNKNOWN
|
289
|
+
else; raise ArgumentError.new("level #{value.inspect} is not a valid logger level")
|
290
|
+
end
|
291
|
+
end
|
273
292
|
end
|
274
293
|
end
|
data/lib/timber/version.rb
CHANGED
data/spec/timber/logger_spec.rb
CHANGED
@@ -15,7 +15,7 @@ describe Timber::Logger, :rails_23 => true do
|
|
15
15
|
Timber::Config.instance.environment = old_env
|
16
16
|
end
|
17
17
|
|
18
|
-
it "shoud select the
|
18
|
+
it "shoud select the message only formatter" do
|
19
19
|
logger = described_class.new(nil)
|
20
20
|
expect(logger.formatter).to be_kind_of(Timber::Logger::MessageOnlyFormatter)
|
21
21
|
end
|
@@ -31,6 +31,32 @@ describe Timber::Logger, :rails_23 => true do
|
|
31
31
|
Timecop.freeze(time) { example.run }
|
32
32
|
end
|
33
33
|
|
34
|
+
it "should respect the level via Logger constants" do
|
35
|
+
logger.formatter = Timber::Logger::MessageOnlyFormatter.new
|
36
|
+
|
37
|
+
logger.level = ::Logger::DEBUG
|
38
|
+
logger.info("message")
|
39
|
+
expect(io.string).to eq("message\n")
|
40
|
+
|
41
|
+
io.string = ""
|
42
|
+
logger.level = ::Logger::WARN
|
43
|
+
logger.info("message")
|
44
|
+
expect(io.string).to eq("")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should respect the level via level symbols" do
|
48
|
+
logger.formatter = Timber::Logger::MessageOnlyFormatter.new
|
49
|
+
|
50
|
+
logger.level = :debug
|
51
|
+
logger.info("message")
|
52
|
+
expect(io.string).to eq("message\n")
|
53
|
+
|
54
|
+
io.string = ""
|
55
|
+
logger.level = :warn
|
56
|
+
logger.info("message")
|
57
|
+
expect(io.string).to eq("")
|
58
|
+
end
|
59
|
+
|
34
60
|
context "with the AugmentedFormatter" do
|
35
61
|
before(:each) { logger.formatter = Timber::Logger::AugmentedFormatter.new }
|
36
62
|
|
@@ -39,7 +65,7 @@ describe Timber::Logger, :rails_23 => true do
|
|
39
65
|
expect(io.string).to start_with("this is a test @metadata {\"level\":\"info\",\"dt\":\"2016-09-01T12:00:00.000000Z\"")
|
40
66
|
end
|
41
67
|
|
42
|
-
it "should non-strings" do
|
68
|
+
it "should accept non-strings" do
|
43
69
|
logger.info(true)
|
44
70
|
expect(io.string).to start_with("true @metadata")
|
45
71
|
end
|
@@ -76,7 +102,7 @@ describe Timber::Logger, :rails_23 => true do
|
|
76
102
|
expect(io.string).to include("\"event\":{\"custom\":{\"payment_rejected\":{\"customer_id\":\"abcde1234\",\"amount\":100}}}")
|
77
103
|
end
|
78
104
|
|
79
|
-
it "should log properly when
|
105
|
+
it "should log properly when a Timber::Event object is passed" do
|
80
106
|
message = Timber::Events::SQLQuery.new(sql: "select * from users", time_ms: 56, message: "select * from users")
|
81
107
|
logger.info(message)
|
82
108
|
expect(io.string).to start_with("select * from users @metadata {\"level\":\"info\",\"dt\":\"2016-09-01T12:00:00.000000Z\",")
|
@@ -94,8 +120,12 @@ describe Timber::Logger, :rails_23 => true do
|
|
94
120
|
end
|
95
121
|
|
96
122
|
it "should allow :tags" do
|
97
|
-
|
123
|
+
tags = ["tag1", "tag2"]
|
124
|
+
logger.info("event complete", tags: tags)
|
98
125
|
expect(io.string).to include("\"tags\":[\"tag1\",\"tag2\"]")
|
126
|
+
|
127
|
+
# Ensure the tags object is not modified
|
128
|
+
expect(tags).to eq(["tag1", "tag2"])
|
99
129
|
end
|
100
130
|
|
101
131
|
it "should allow functions" do
|
@@ -130,6 +160,24 @@ describe Timber::Logger, :rails_23 => true do
|
|
130
160
|
end
|
131
161
|
end
|
132
162
|
|
163
|
+
describe "#error" do
|
164
|
+
let(:io) { StringIO.new }
|
165
|
+
let(:logger) { Timber::Logger.new(io) }
|
166
|
+
|
167
|
+
it "should allow default usage" do
|
168
|
+
logger.error("message")
|
169
|
+
expect(io.string).to start_with("message @metadata")
|
170
|
+
expect(io.string).to include('"level":"error"')
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should allow messages with options" do
|
174
|
+
logger.error("message", tag: "tag")
|
175
|
+
expect(io.string).to start_with("message @metadata")
|
176
|
+
expect(io.string).to include('"level":"error"')
|
177
|
+
expect(io.string).to include('"tags":["tag"]')
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
133
181
|
describe "#formatter=" do
|
134
182
|
it "should not allow changing the formatter when the device is HTTP" do
|
135
183
|
http_device = Timber::LogDevices::HTTP.new("api_key")
|
@@ -145,6 +193,29 @@ describe Timber::Logger, :rails_23 => true do
|
|
145
193
|
end
|
146
194
|
end
|
147
195
|
|
196
|
+
describe "#info" do
|
197
|
+
let(:io) { StringIO.new }
|
198
|
+
let(:logger) { Timber::Logger.new(io) }
|
199
|
+
|
200
|
+
it "should allow default usage" do
|
201
|
+
logger.info("message")
|
202
|
+
expect(io.string).to start_with("message @metadata")
|
203
|
+
expect(io.string).to include('"level":"info"')
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should allow messages with options" do
|
207
|
+
logger.info("message", tag: "tag")
|
208
|
+
expect(io.string).to start_with("message @metadata")
|
209
|
+
expect(io.string).to include('"level":"info"')
|
210
|
+
expect(io.string).to include('"tags":["tag"]')
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should accept non-string messages" do
|
214
|
+
logger.info(true)
|
215
|
+
expect(io.string).to start_with("true @metadata")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
148
219
|
describe "#silence" do
|
149
220
|
let(:io) { StringIO.new }
|
150
221
|
let(:logger) { Timber::Logger.new(io) }
|
@@ -178,45 +249,4 @@ describe Timber::Logger, :rails_23 => true do
|
|
178
249
|
expect(Timber::CurrentContext.instance.send(:hash)[:custom]).to be_nil
|
179
250
|
end
|
180
251
|
end
|
181
|
-
|
182
|
-
describe "#info" do
|
183
|
-
let(:io) { StringIO.new }
|
184
|
-
let(:logger) { Timber::Logger.new(io) }
|
185
|
-
|
186
|
-
it "should allow default usage" do
|
187
|
-
logger.info("message")
|
188
|
-
expect(io.string).to start_with("message @metadata")
|
189
|
-
expect(io.string).to include('"level":"info"')
|
190
|
-
end
|
191
|
-
|
192
|
-
it "should allow messages with options" do
|
193
|
-
logger.info("message", tag: "tag")
|
194
|
-
expect(io.string).to start_with("message @metadata")
|
195
|
-
expect(io.string).to include('"level":"info"')
|
196
|
-
expect(io.string).to include('"tags":["tag"]')
|
197
|
-
end
|
198
|
-
|
199
|
-
it "should accept non-string messages" do
|
200
|
-
logger.info(true)
|
201
|
-
expect(io.string).to start_with("true @metadata")
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
describe "#error" do
|
206
|
-
let(:io) { StringIO.new }
|
207
|
-
let(:logger) { Timber::Logger.new(io) }
|
208
|
-
|
209
|
-
it "should allow default usage" do
|
210
|
-
logger.error("message")
|
211
|
-
expect(io.string).to start_with("message @metadata")
|
212
|
-
expect(io.string).to include('"level":"error"')
|
213
|
-
end
|
214
|
-
|
215
|
-
it "should allow messages with options" do
|
216
|
-
logger.error("message", tag: "tag")
|
217
|
-
expect(io.string).to start_with("message @metadata")
|
218
|
-
expect(io.string).to include('"level":"error"')
|
219
|
-
expect(io.string).to include('"tags":["tag"]')
|
220
|
-
end
|
221
|
-
end
|
222
252
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.0.
|
4
|
+
version: 2.1.0.rc5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Timber Technologies, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|