timber 1.1.13 → 1.1.14
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 +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
|