timber 1.1.13 → 1.1.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/lib/timber/current_context.rb +39 -22
- data/lib/timber/log_devices/http.rb +0 -2
- data/lib/timber/overrides/logger_add.rb +0 -3
- data/lib/timber/probes/action_view_log_subscriber/log_subscriber.rb +19 -12
- data/lib/timber/version.rb +1 -1
- data/spec/timber/current_context_spec.rb +57 -0
- data/spec/timber/log_devices/http_spec.rb +0 -1
- data/spec/timber/probes/action_controller_log_subscriber_spec.rb +47 -51
- data/spec/timber/probes/action_controller_user_context_spec.rb +11 -13
- data/spec/timber/probes/action_dispatch_debug_exceptions_spec.rb +33 -35
- data/spec/timber/probes/action_view_log_subscriber_spec.rb +84 -38
- data/spec/timber/probes/active_record_log_subscriber_spec.rb +34 -38
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 423710eb07f5ddad12eebd5cdb105a4557aba07e
|
4
|
+
data.tar.gz: 5c4c3c0303a09157b032b3d8fccc1fd86fe72814
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88662c0e6a31886e9a20f4782db1b2bca3b44ae0d8ad501fb4457f1ec8a7aaaf67fd756c25486dfd722a93726153119abba56ca99edbdec5bb9b50db45a574ac
|
7
|
+
data.tar.gz: 676c3525de6505c9e9e514508c10113d27950dc0d597a4a29b78bafe2bc2d546c5456077aa558a62cf3727c0bc31c95f9fa15a9f707a74a86a37096bc850bbce
|
data/README.md
CHANGED
@@ -99,15 +99,15 @@ The recommended strategy for Heroku is to setup a
|
|
99
99
|
|
100
100
|
<details><summary><strong>Or, all other platforms (Network / HTTP)</strong></summary><p>
|
101
101
|
|
102
|
-
1. *Specify* the Timber
|
102
|
+
1. *Specify* the Timber HTTP logger backend in `config/environments/production.rb`:
|
103
103
|
|
104
104
|
Replace any existing `config.logger =` calls with:
|
105
105
|
|
106
106
|
```ruby
|
107
107
|
# config/environments/production.rb (or staging, etc)
|
108
108
|
|
109
|
-
|
110
|
-
config.logger = ActiveSupport::TaggedLogging.new(Timber::Logger.new(
|
109
|
+
http_log_device = Timber::LogDevices::HTTP.new(ENV['TIMBER_LOGS_KEY'])
|
110
|
+
config.logger = ActiveSupport::TaggedLogging.new(Timber::Logger.new(http_log_device))
|
111
111
|
```
|
112
112
|
|
113
113
|
2. Obtain your Timber API :key: by **[adding your app in Timber](https://app.timber.io)**.
|
@@ -23,13 +23,17 @@ module Timber
|
|
23
23
|
instance.add(*args)
|
24
24
|
end
|
25
25
|
|
26
|
+
def hash(*args)
|
27
|
+
instance.hash(*args)
|
28
|
+
end
|
29
|
+
|
26
30
|
# Convenience method for {#remove}. See {#remove} for full details and examples.
|
27
31
|
def remove(*args)
|
28
32
|
instance.remove(*args)
|
29
33
|
end
|
30
34
|
|
31
|
-
def
|
32
|
-
instance.
|
35
|
+
def reset(*args)
|
36
|
+
instance.reset(*args)
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
@@ -56,18 +60,11 @@ module Timber
|
|
56
60
|
#
|
57
61
|
# @example Adding multiple contexts
|
58
62
|
# Timber::CurrentContext.with(context1, context2) { ... }
|
59
|
-
def with(*
|
60
|
-
add(*
|
63
|
+
def with(*objects)
|
64
|
+
add(*objects)
|
61
65
|
yield
|
62
66
|
ensure
|
63
|
-
|
64
|
-
if context.keyspace == :custom
|
65
|
-
# Custom contexts are merged and should be removed the same
|
66
|
-
hash[context.keyspace].delete(context.type)
|
67
|
-
else
|
68
|
-
remove(context)
|
69
|
-
end
|
70
|
-
end
|
67
|
+
remove(*objects)
|
71
68
|
end
|
72
69
|
|
73
70
|
# Adds contexts but does not remove them. See {#with} for automatic maintenance and {#remove}
|
@@ -83,31 +80,51 @@ module Timber
|
|
83
80
|
if key == :custom
|
84
81
|
# Custom contexts are merged into the space
|
85
82
|
hash[key] ||= {}
|
86
|
-
hash[key].merge(json)
|
83
|
+
hash[key].merge!(json)
|
87
84
|
else
|
88
85
|
hash[key] = json
|
89
86
|
end
|
90
87
|
end
|
91
88
|
end
|
92
89
|
|
93
|
-
# Removes a context. This must be a {Timber::Context} type. See {Timber::Contexts} for a list.
|
94
|
-
# If you wish to remove by key, or some other way, use {#hash} and modify the hash accordingly.
|
95
|
-
def remove(*contexts)
|
96
|
-
contexts.each do |context|
|
97
|
-
hash.delete(context.keyspace)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
90
|
# The internal hash that is maintained. It is recommended that you use {#with} and {#add}
|
102
91
|
# for hash maintenance.
|
103
92
|
def hash
|
104
93
|
Thread.current[THREAD_NAMESPACE] ||= {}
|
105
94
|
end
|
106
95
|
|
96
|
+
# Removes a context. If you wish to remove by key, or some other way, use {#hash} and
|
97
|
+
# modify the hash accordingly.
|
98
|
+
def remove(*objects)
|
99
|
+
objects.each do |object|
|
100
|
+
if object.is_a?(Symbol)
|
101
|
+
hash.delete(object)
|
102
|
+
else
|
103
|
+
context = Contexts.build(object)
|
104
|
+
|
105
|
+
if context.keyspace == :custom
|
106
|
+
# Custom contexts are merged and should be removed the same
|
107
|
+
hash[context.keyspace].delete(context.type)
|
108
|
+
if hash[context.keyspace] == {}
|
109
|
+
hash.delete(context.keyspace)
|
110
|
+
end
|
111
|
+
else
|
112
|
+
hash.delete(context.keyspace)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Resets the context to be blank. Use this carefully! This will remove *any* context,
|
119
|
+
# include context that is automatically included with Timber.
|
120
|
+
def reset
|
121
|
+
hash.clear
|
122
|
+
end
|
123
|
+
|
107
124
|
# Snapshots the current context so that you get a moment in time representation of the context,
|
108
125
|
# since the context can change as execution proceeds.
|
109
126
|
def snapshot
|
110
127
|
hash.clone
|
111
128
|
end
|
112
129
|
end
|
113
|
-
end
|
130
|
+
end
|
@@ -59,7 +59,6 @@ module Timber
|
|
59
59
|
end
|
60
60
|
|
61
61
|
TIMBER_URL = "https://logs.timber.io/frames".freeze
|
62
|
-
ACCEPT = "application/json".freeze
|
63
62
|
CONTENT_TYPE = "application/msgpack".freeze
|
64
63
|
USER_AGENT = "Timber Ruby/#{Timber::VERSION} (HTTP)".freeze
|
65
64
|
|
@@ -151,7 +150,6 @@ module Timber
|
|
151
150
|
return if msgs.empty?
|
152
151
|
|
153
152
|
req = Net::HTTP::Post.new(@timber_url.path)
|
154
|
-
req['Accept'] = ACCEPT
|
155
153
|
req['Authorization'] = authorization_payload
|
156
154
|
req['Content-Type'] = CONTENT_TYPE
|
157
155
|
req['User-Agent'] = USER_AGENT
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Timber
|
1
|
+
module Timber
|
2
2
|
module Probes
|
3
3
|
class ActionViewLogSubscriber < Probe
|
4
4
|
# The log subscriber that replaces the default `ActionView::LogSubscriber`.
|
@@ -38,23 +38,30 @@ module Timber
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def render_collection(event)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
"
|
41
|
+
if respond_to?(:render_count, true)
|
42
|
+
info do
|
43
|
+
identifier = event.payload[:identifier] || "templates"
|
44
|
+
full_name = from_rails_root(identifier)
|
45
|
+
message = " Rendered collection of #{full_name}" \
|
46
|
+
" #{render_count(event.payload)} (#{event.duration.round(1)}ms)"
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
Events::TemplateRender.new(
|
49
|
+
name: full_name,
|
50
|
+
time_ms: event.duration,
|
51
|
+
message: message
|
52
|
+
)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
# Older versions of rails delegate this method to #render_template
|
56
|
+
render_template(event)
|
52
57
|
end
|
53
58
|
end
|
54
59
|
|
55
60
|
private
|
56
61
|
def log_rendering_start(payload)
|
57
|
-
#
|
62
|
+
# Consolidates 2 template rendering events into 1. We don't need 2 events for
|
63
|
+
# rendering a template. If you disagree, please feel free to open a PR and we
|
64
|
+
# can make this an option.
|
58
65
|
end
|
59
66
|
end
|
60
67
|
end
|
data/lib/timber/version.rb
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Timber::CurrentContext, :rails_23 => true do
|
4
|
+
describe ".add" do
|
5
|
+
after(:each) do
|
6
|
+
described_class.reset
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should add the context" do
|
10
|
+
expect(described_class.hash).to eq({})
|
11
|
+
|
12
|
+
described_class.add({build: {version: "1.0.0"}})
|
13
|
+
expect(described_class.hash).to eq({:custom=>{:build=>{:version=>"1.0.0"}}})
|
14
|
+
|
15
|
+
described_class.add({testing: {key: "value"}})
|
16
|
+
expect(described_class.hash).to eq({:custom=>{:build=>{:version=>"1.0.0"}, :testing=>{:key=>"value"}}})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".remove" do
|
21
|
+
it "should remove the context by object" do
|
22
|
+
context = {:build=>{:version=>"1.0.0"}}
|
23
|
+
described_class.add(context)
|
24
|
+
expect(described_class.hash).to eq({:custom => context})
|
25
|
+
|
26
|
+
described_class.remove(context)
|
27
|
+
expect(described_class.hash).to eq({})
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should remove context by key" do
|
31
|
+
context = {:build=>{:version=>"1.0.0"}}
|
32
|
+
described_class.add(context)
|
33
|
+
expect(described_class.hash).to eq({:custom => context})
|
34
|
+
|
35
|
+
described_class.remove(:custom)
|
36
|
+
expect(described_class.hash).to eq({})
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe ".with" do
|
41
|
+
it "should merge the context and cleanup on block exit" do
|
42
|
+
expect(described_class.hash).to eq({})
|
43
|
+
|
44
|
+
described_class.with({build: {version: "1.0.0"}}) do
|
45
|
+
expect(described_class.hash).to eq({:custom=>{:build=>{:version=>"1.0.0"}}})
|
46
|
+
|
47
|
+
described_class.with({testing: {key: "value"}}) do
|
48
|
+
expect(described_class.hash).to eq({:custom=>{:build=>{:version=>"1.0.0"}, :testing=>{:key=>"value"}}})
|
49
|
+
end
|
50
|
+
|
51
|
+
expect(described_class.hash).to eq({:custom=>{:build=>{:version=>"1.0.0"}}})
|
52
|
+
end
|
53
|
+
|
54
|
+
expect(described_class.hash).to eq({})
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -100,7 +100,6 @@ describe Timber::LogDevices::HTTP do
|
|
100
100
|
with(
|
101
101
|
:body => start_with("\x92\x85\xA5level\xA4INFO\xA2dt\xBB2016-09-01T12:00:00.000000Z\xA7message\xB2test log message 1\xA7context\x81\xA6system".force_encoding("ASCII-8BIT")),
|
102
102
|
:headers => {
|
103
|
-
'Accept' => 'application/json',
|
104
103
|
'Authorization' => 'Basic TVlLRVk=',
|
105
104
|
'Content-Type' => 'application/msgpack',
|
106
105
|
'User-Agent' => "Timber Ruby/#{Timber::VERSION} (HTTP)"
|
@@ -1,68 +1,64 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Timber::Probes::ActionControllerLogSubscriber do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
logger
|
12
|
-
end
|
13
|
-
|
14
|
-
around(:each) do |example|
|
15
|
-
class LogSubscriberController < ActionController::Base
|
16
|
-
layout nil
|
4
|
+
let(:time) { Time.utc(2016, 9, 1, 12, 0, 0) }
|
5
|
+
let(:io) { StringIO.new }
|
6
|
+
let(:logger) do
|
7
|
+
logger = Timber::Logger.new(io)
|
8
|
+
logger.level = ::Logger::WARN
|
9
|
+
logger
|
10
|
+
end
|
17
11
|
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
describe "#insert!" do
|
13
|
+
around(:each) do |example|
|
14
|
+
class LogSubscriberController < ActionController::Base
|
15
|
+
layout nil
|
21
16
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
17
|
+
def index
|
18
|
+
render json: {}
|
25
19
|
end
|
26
20
|
|
27
|
-
|
28
|
-
|
21
|
+
def method_for_action(action_name)
|
22
|
+
action_name
|
29
23
|
end
|
24
|
+
end
|
30
25
|
|
31
|
-
|
32
|
-
|
26
|
+
::RailsApp.routes.draw do
|
27
|
+
get 'log_subscriber' => 'log_subscriber#index'
|
28
|
+
end
|
33
29
|
|
34
|
-
|
30
|
+
old_logger = ::ActionController::Base.logger
|
31
|
+
::ActionController::Base.logger = logger
|
35
32
|
|
36
|
-
|
37
|
-
::ActionController::Base.logger = old_logger
|
38
|
-
end
|
33
|
+
Timecop.freeze(time) { example.run }
|
39
34
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
expect(io.string).to eq("")
|
44
|
-
end
|
35
|
+
Object.send(:remove_const, :LogSubscriberController)
|
36
|
+
::ActionController::Base.logger = old_logger
|
37
|
+
end
|
45
38
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
example.run
|
51
|
-
logger.level = old_level
|
52
|
-
end
|
39
|
+
it "should not log if the level is not sufficient" do
|
40
|
+
dispatch_rails_request("/log_subscriber")
|
41
|
+
expect(io.string).to eq("")
|
42
|
+
end
|
53
43
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
44
|
+
context "with an info level" do
|
45
|
+
around(:each) do |example|
|
46
|
+
old_level = logger.level
|
47
|
+
logger.level = ::Logger::INFO
|
48
|
+
example.run
|
49
|
+
logger.level = old_level
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should log the controller call event" do
|
53
|
+
# Rails uses this to calculate the view runtime below
|
54
|
+
allow(Benchmark).to receive(:ms).and_return(1).and_yield
|
55
|
+
dispatch_rails_request("/log_subscriber")
|
56
|
+
lines = io.string.split("\n")
|
57
|
+
expect(lines.length).to eq(2)
|
58
|
+
expect(lines[0]).to start_with('Processing by LogSubscriberController#index as HTML @metadata {"level":"info","dt":"2016-09-01T12:00:00.000000Z"')
|
59
|
+
expect(lines[0]).to include('"event":{"server_side_app":{"controller_call":{"controller":"LogSubscriberController","action":"index"}}}')
|
60
|
+
expect(lines[1]).to start_with('Completed 200 OK in 0.0ms (Views: 1.0ms) @metadata {"level":"info","dt":"2016-09-01T12:00:00.000000Z"')
|
61
|
+
expect(lines[1]).to include('"event":{"server_side_app":{"http_server_response":{"status":200,"time_ms":0.0}}}')
|
66
62
|
end
|
67
63
|
end
|
68
64
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Timber::Probes::ActionControllerUserContext do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
4
|
+
let(:time) { Time.utc(2016, 9, 1, 12, 0, 0) }
|
5
|
+
let(:io) { StringIO.new }
|
6
|
+
let(:logger) do
|
7
|
+
logger = Timber::Logger.new(io)
|
8
|
+
logger.level = ::Logger::WARN
|
9
|
+
logger
|
10
|
+
end
|
12
11
|
|
12
|
+
describe "#insert!" do
|
13
13
|
around(:each) do |example|
|
14
14
|
class UserContextController < ActionController::Base
|
15
15
|
layout nil
|
@@ -45,11 +45,9 @@ describe Timber::Probes::ActionControllerUserContext do
|
|
45
45
|
::ActionController::Base.logger = old_logger
|
46
46
|
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
expect(io.string).to include("\"user\":{\"id\":\"1\",\"name\":\"Ben Johnson\",\"email\":\"hi@timber.io\"}")
|
52
|
-
end
|
48
|
+
it "should capture the user context" do
|
49
|
+
dispatch_rails_request("/user_context")
|
50
|
+
expect(io.string).to include("\"user\":{\"id\":\"1\",\"name\":\"Ben Johnson\",\"email\":\"hi@timber.io\"}")
|
53
51
|
end
|
54
52
|
end
|
55
53
|
end
|
@@ -1,50 +1,48 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Timber::Probes::ActionDispatchDebugExceptions do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
logger
|
12
|
-
end
|
13
|
-
|
14
|
-
around(:each) do |example|
|
15
|
-
class ExceptionController < ActionController::Base
|
16
|
-
layout nil
|
4
|
+
let(:time) { Time.utc(2016, 9, 1, 12, 0, 0) }
|
5
|
+
let(:io) { StringIO.new }
|
6
|
+
let(:logger) do
|
7
|
+
logger = Timber::Logger.new(io)
|
8
|
+
logger.level = ::Logger::DEBUG
|
9
|
+
logger
|
10
|
+
end
|
17
11
|
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
describe "#insert!" do
|
13
|
+
around(:each) do |example|
|
14
|
+
class ExceptionController < ActionController::Base
|
15
|
+
layout nil
|
21
16
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
17
|
+
def index
|
18
|
+
raise "boom"
|
25
19
|
end
|
26
20
|
|
27
|
-
|
28
|
-
|
21
|
+
def method_for_action(action_name)
|
22
|
+
action_name
|
29
23
|
end
|
30
|
-
|
31
|
-
Timecop.freeze(time) { example.run }
|
32
|
-
|
33
|
-
Object.send(:remove_const, :ExceptionController)
|
34
24
|
end
|
35
25
|
|
36
|
-
|
37
|
-
|
38
|
-
dispatch_rails_request("/exception")
|
39
|
-
# Because constantly updating the line numbers sucks :/
|
40
|
-
expect(io.string).to include("RuntimeError (boom) @metadata")
|
41
|
-
expect(io.string).to include("\"event\":{\"server_side_app\":{\"exception\":{\"name\":\"RuntimeError\",\"message\":\"boom\",\"backtrace\":[{\"file\":\"lib/timber/probes/action_controller_user_context.rb\",\"line\":33,\"function\":\"_timber_capture_user_context\"},")
|
26
|
+
::RailsApp.routes.draw do
|
27
|
+
get 'exception' => 'exception#index'
|
42
28
|
end
|
43
29
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
30
|
+
Timecop.freeze(time) { example.run }
|
31
|
+
|
32
|
+
Object.send(:remove_const, :ExceptionController)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should set the context" do
|
36
|
+
mock_class
|
37
|
+
dispatch_rails_request("/exception")
|
38
|
+
# Because constantly updating the line numbers sucks :/
|
39
|
+
expect(io.string).to include("RuntimeError (boom) @metadata")
|
40
|
+
expect(io.string).to include("\"event\":{\"server_side_app\":{\"exception\":{\"name\":\"RuntimeError\",\"message\":\"boom\",\"backtrace\":[{\"file\":\"lib/timber/probes/action_controller_user_context.rb\",\"line\":33,\"function\":\"_timber_capture_user_context\"},")
|
41
|
+
end
|
42
|
+
|
43
|
+
def mock_class
|
44
|
+
klass = defined?(::ActionDispatch::DebugExceptions) ? ::ActionDispatch::DebugExceptions : ::ActionDispatch::ShowExceptions
|
45
|
+
allow_any_instance_of(klass).to receive(:logger).and_return(logger)
|
48
46
|
end
|
49
47
|
end
|
50
48
|
end
|
@@ -1,58 +1,104 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Timber::Probes::ActionViewLogSubscriber do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
logger
|
12
|
-
end
|
13
|
-
|
14
|
-
around(:each) do |example|
|
15
|
-
class ActionViewLogSubscriberController < ActionController::Base
|
16
|
-
layout nil
|
4
|
+
let(:time) { Time.utc(2016, 9, 1, 12, 0, 0) }
|
5
|
+
let(:io) { StringIO.new }
|
6
|
+
let(:logger) do
|
7
|
+
logger = Timber::Logger.new(io)
|
8
|
+
logger.level = ::Logger::WARN
|
9
|
+
logger
|
10
|
+
end
|
17
11
|
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
describe "insert!" do
|
13
|
+
around(:each) do |example|
|
14
|
+
class ActionViewLogSubscriberController < ActionController::Base
|
15
|
+
layout nil
|
21
16
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
17
|
+
def index
|
18
|
+
render template: "template"
|
25
19
|
end
|
26
20
|
|
27
|
-
|
28
|
-
|
21
|
+
def method_for_action(action_name)
|
22
|
+
action_name
|
29
23
|
end
|
24
|
+
end
|
25
|
+
|
26
|
+
::RailsApp.routes.draw do
|
27
|
+
get 'action_view_log_subscriber' => 'action_view_log_subscriber#index'
|
28
|
+
end
|
29
|
+
|
30
|
+
Timecop.freeze(time) { example.run }
|
30
31
|
|
31
|
-
|
32
|
+
Object.send(:remove_const, :ActionViewLogSubscriberController)
|
33
|
+
end
|
32
34
|
|
33
|
-
|
35
|
+
describe "#render_template" do
|
36
|
+
it "should not log if the level is not sufficient" do
|
37
|
+
allow_any_instance_of(Timber::Probes::ActionViewLogSubscriber::LogSubscriber).to receive(:logger).and_return(logger)
|
38
|
+
dispatch_rails_request("/action_view_log_subscriber")
|
39
|
+
expect(io.string).to eq("")
|
34
40
|
end
|
35
41
|
|
36
|
-
|
37
|
-
|
42
|
+
context "with an info level" do
|
43
|
+
around(:each) do |example|
|
44
|
+
old_level = logger.level
|
45
|
+
logger.level = ::Logger::INFO
|
46
|
+
example.run
|
47
|
+
logger.level = old_level
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should log the controller call event" do
|
38
51
|
allow_any_instance_of(Timber::Probes::ActionViewLogSubscriber::LogSubscriber).to receive(:logger).and_return(logger)
|
39
52
|
dispatch_rails_request("/action_view_log_subscriber")
|
40
|
-
expect(io.string).to
|
53
|
+
expect(io.string).to start_with(" Rendered spec/support/rails/templates/template.html (0.0ms) @metadata {\"level\":\"info\"")
|
54
|
+
expect(io.string).to include("\"event\":{\"server_side_app\":{\"template_render\":{\"name\":\"spec/support/rails/templates/template.html\",\"time_ms\":0.0}}},")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if defined?(described_class::LogSubscriber)
|
61
|
+
describe described_class::LogSubscriber do
|
62
|
+
let(:event) do
|
63
|
+
event = Struct.new(:duration, :payload)
|
64
|
+
event.new(2, identifier: "path/to/template.html")
|
65
|
+
end
|
66
|
+
|
67
|
+
around(:each) do |example|
|
68
|
+
old_level = logger.level
|
69
|
+
logger.level = ::Logger::INFO
|
70
|
+
example.run
|
71
|
+
logger.level = old_level
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#render_template" do
|
75
|
+
it "should render the collection" do
|
76
|
+
log_subscriber = described_class.new
|
77
|
+
log_subscriber.stub(:logger) { logger }
|
78
|
+
log_subscriber.render_template(event)
|
79
|
+
expect(io.string).to start_with(" Rendered path/to/template.html (2.0ms) @metadata")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#render_partial" do
|
84
|
+
it "should render the collection" do
|
85
|
+
log_subscriber = described_class.new
|
86
|
+
log_subscriber.stub(:logger) { logger }
|
87
|
+
log_subscriber.render_partial(event)
|
88
|
+
expect(io.string).to start_with(" Rendered path/to/template.html (2.0ms) @metadata")
|
41
89
|
end
|
90
|
+
end
|
42
91
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
logger.level = old_level
|
49
|
-
end
|
92
|
+
describe "#render_collection" do
|
93
|
+
it "should render the collection" do
|
94
|
+
log_subscriber = described_class.new
|
95
|
+
log_subscriber.stub(:logger) { logger }
|
96
|
+
log_subscriber.render_collection(event)
|
50
97
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
expect(io.string).to start_with(" Rendered
|
55
|
-
expect(io.string).to include("\"event\":{\"server_side_app\":{\"template_render\":{\"name\":\"spec/support/rails/templates/template.html\",\"time_ms\":0.0}}},")
|
98
|
+
if log_subscriber.respond_to?(:render_count, true)
|
99
|
+
expect(io.string).to start_with(" Rendered collection of path/to/template.html [ times] (2.0ms) @metadata ")
|
100
|
+
else
|
101
|
+
expect(io.string).to start_with(" Rendered path/to/template.html (2.0ms) @metadata")
|
56
102
|
end
|
57
103
|
end
|
58
104
|
end
|
@@ -1,50 +1,46 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Timber::Probes::ActiveRecordLogSubscriber do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
logger
|
12
|
-
end
|
4
|
+
let(:time) { Time.utc(2016, 9, 1, 12, 0, 0) }
|
5
|
+
let(:io) { StringIO.new }
|
6
|
+
let(:logger) do
|
7
|
+
logger = Timber::Logger.new(io)
|
8
|
+
logger.level = ::Logger::INFO
|
9
|
+
logger
|
10
|
+
end
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
describe "#insert!" do
|
13
|
+
around(:each) do |example|
|
14
|
+
old_logger = ::ActiveRecord::Base.logger
|
15
|
+
::ActiveRecord::Base.logger = logger
|
17
16
|
|
18
|
-
|
17
|
+
Timecop.freeze(time) { example.run }
|
19
18
|
|
20
|
-
|
21
|
-
|
19
|
+
::ActiveRecord::Base.logger = old_logger
|
20
|
+
end
|
22
21
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
22
|
+
it "should not log if the level is not sufficient" do
|
23
|
+
User.order("users.id DESC").all.collect # collect kicks the sql because it is lazily executed
|
24
|
+
expect(io.string).to eq("")
|
25
|
+
end
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
context "with an info level" do
|
28
|
+
around(:each) do |example|
|
29
|
+
old_level = logger.level
|
30
|
+
logger.level = ::Logger::DEBUG
|
31
|
+
example.run
|
32
|
+
logger.level = old_level
|
33
|
+
end
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
35
|
+
it "should log the sql query" do
|
36
|
+
User.order("users.id DESC").all.collect # collect kicks the sql because it is lazily executed
|
37
|
+
# Rails 4.X adds random spaces :/
|
38
|
+
string = io.string.gsub(" ORDER BY", " ORDER BY")
|
39
|
+
string = string.gsub(" ORDER BY", " ORDER BY")
|
40
|
+
expect(string).to include("users.id DESC")
|
41
|
+
expect(string).to include("@metadata")
|
42
|
+
expect(string).to include("\"level\":\"debug\"")
|
43
|
+
expect(string).to include("\"event\":{\"server_side_app\":{\"sql_query\"")
|
48
44
|
end
|
49
45
|
end
|
50
46
|
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: 1.1.
|
4
|
+
version: 1.1.14
|
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-03-
|
11
|
+
date: 2017-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -120,6 +120,7 @@ files:
|
|
120
120
|
- spec/timber/contexts/system_spec.rb
|
121
121
|
- spec/timber/contexts/user_spec.rb
|
122
122
|
- spec/timber/contexts_spec.rb
|
123
|
+
- spec/timber/current_context_spec.rb
|
123
124
|
- spec/timber/event_spec.rb
|
124
125
|
- spec/timber/events/custom_spec.rb
|
125
126
|
- spec/timber/events_spec.rb
|
@@ -178,6 +179,7 @@ test_files:
|
|
178
179
|
- spec/timber/contexts/system_spec.rb
|
179
180
|
- spec/timber/contexts/user_spec.rb
|
180
181
|
- spec/timber/contexts_spec.rb
|
182
|
+
- spec/timber/current_context_spec.rb
|
181
183
|
- spec/timber/event_spec.rb
|
182
184
|
- spec/timber/events/custom_spec.rb
|
183
185
|
- spec/timber/events_spec.rb
|