timber 1.0.13 → 1.1.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +278 -121
  3. data/lib/timber.rb +1 -0
  4. data/lib/timber/context.rb +1 -1
  5. data/lib/timber/contexts.rb +29 -2
  6. data/lib/timber/contexts/runtime.rb +24 -0
  7. data/lib/timber/contexts/system.rb +19 -0
  8. data/lib/timber/current_context.rb +14 -5
  9. data/lib/timber/event.rb +1 -1
  10. data/lib/timber/events.rb +11 -6
  11. data/lib/timber/events/controller_call.rb +1 -1
  12. data/lib/timber/events/custom.rb +1 -1
  13. data/lib/timber/events/exception.rb +1 -1
  14. data/lib/timber/events/{http_request.rb → http_server_request.rb} +1 -1
  15. data/lib/timber/events/{http_response.rb → http_server_response.rb} +2 -1
  16. data/lib/timber/events/sql_query.rb +2 -1
  17. data/lib/timber/events/template_render.rb +2 -1
  18. data/lib/timber/frameworks/rails.rb +12 -1
  19. data/lib/timber/log_devices/http.rb +29 -24
  20. data/lib/timber/log_entry.rb +23 -9
  21. data/lib/timber/logger.rb +20 -6
  22. data/lib/timber/probes.rb +1 -3
  23. data/lib/timber/probes/active_support_tagged_logging.rb +0 -43
  24. data/lib/timber/probes/rails_rack_logger.rb +1 -1
  25. data/lib/timber/rack_middlewares.rb +12 -0
  26. data/lib/timber/rack_middlewares/http_context.rb +30 -0
  27. data/lib/timber/util.rb +1 -0
  28. data/lib/timber/util/struct.rb +16 -0
  29. data/lib/timber/version.rb +1 -1
  30. data/spec/README.md +23 -0
  31. data/spec/support/timber.rb +1 -1
  32. data/spec/timber/contexts_spec.rb +49 -0
  33. data/spec/timber/events_spec.rb +1 -1
  34. data/spec/timber/log_devices/http_spec.rb +7 -7
  35. data/spec/timber/log_entry_spec.rb +15 -0
  36. data/spec/timber/logger_spec.rb +14 -10
  37. data/spec/timber/probes/action_controller_log_subscriber_spec.rb +6 -7
  38. data/spec/timber/probes/action_dispatch_debug_exceptions_spec.rb +1 -1
  39. data/spec/timber/probes/action_view_log_subscriber_spec.rb +2 -2
  40. data/spec/timber/probes/rails_rack_logger_spec.rb +3 -3
  41. data/spec/timber/rack_middlewares/http_context_spec.rb +47 -0
  42. data/timber.gemspec +1 -0
  43. metadata +31 -8
  44. data/lib/timber/contexts/tags.rb +0 -22
  45. data/lib/timber/probes/rack_http_context.rb +0 -51
  46. data/spec/timber/probes/rack_http_context_spec.rb +0 -50
@@ -39,7 +39,7 @@ describe Timber::Probes::ActionDispatchDebugExceptions do
39
39
  # Because constantly updating the line numbers sucks :/
40
40
  expect(io.string).to include("RuntimeError (boom):\\n\\n")
41
41
  expect(io.string).to include("@timber.io")
42
- expect(io.string).to include("\"event\":{\"exception\":{\"name\":\"RuntimeError\",\"message\":\"boom\",\"backtrace\":[\"")
42
+ expect(io.string).to include("\"event\":{\"server_side_app\":{\"exception\":{\"name\":\"RuntimeError\",\"message\":\"boom\",\"backtrace\":[\"")
43
43
  end
44
44
 
45
45
  def mock_class
@@ -51,8 +51,8 @@ describe Timber::Probes::ActionViewLogSubscriber do
51
51
  it "should log the controller call event" do
52
52
  allow_any_instance_of(Timber::Probes::ActionViewLogSubscriber::LogSubscriber).to receive(:logger).and_return(logger)
53
53
  dispatch_rails_request("/action_view_log_subscriber")
54
- message = " Rendered spec/support/rails/templates/template.html (0.0ms) @timber.io {\"level\":\"info\",\"dt\":\"2016-09-01T12:00:00.000000Z\",\"event\":{\"template_render\":{\"name\":\"spec/support/rails/templates/template.html\",\"time_ms\":0.0}},\"context\":{\"http\":{\"method\":\"GET\",\"path\":\"/action_view_log_subscriber\",\"remote_addr\":\"123.456.789.10\",\"request_id\":\"unique-request-id-1234\"}}}\n"
55
- expect(io.string).to eq(message)
54
+ expect(io.string).to start_with(" Rendered spec/support/rails/templates/template.html (0.0ms) @timber.io {\"level\":\"info\"")
55
+ expect(io.string).to include("\"event\":{\"server_side_app\":{\"template_render\":{\"name\":\"spec/support/rails/templates/template.html\",\"time_ms\":0.0}}},")
56
56
  end
57
57
  end
58
58
  end
@@ -33,13 +33,13 @@ describe Timber::Probes::RailsRackLogger do
33
33
  end
34
34
 
35
35
  describe "#started_request_message" do
36
- it "should set the context" do
36
+ it "should add the request event" do
37
37
  allow(::Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new("production")) # Rails 3.2.X
38
38
  allow(::Rails).to receive(:logger).and_return(logger) # Rails 3.2.X
39
39
  allow_any_instance_of(::Rails::Rack::Logger).to receive(:logger).and_return(logger)
40
40
  dispatch_rails_request("/rails_rack_logger")
41
- message = "Started GET \"/rails_rack_logger\" for 123.456.789.10 @timber.io {\"level\":\"info\",\"dt\":\"2016-09-01T12:00:00.000000Z\",\"event\":{\"http_request\":{\"host\":\"example.org\",\"method\":\"GET\",\"path\":\"/rails_rack_logger\",\"port\":80,\"headers\":{\"remote_addr\":\"123.456.789.10\",\"request_id\":\"unique-request-id-1234\"}}},\"context\":{\"http\":{\"method\":\"GET\",\"path\":\"/rails_rack_logger\",\"remote_addr\":\"123.456.789.10\",\"request_id\":\"unique-request-id-1234\"}}}\n"
42
- expect(io.string).to eq(message)
41
+ expect(io.string).to start_with("Started GET \"/rails_rack_logger\" for 123.456.789.10 @timber.io {\"level\":\"info\",\"dt\":\"2016-09-01T12:00:00.000000Z\"")
42
+ expect(io.string).to include("\"event\":{\"server_side_app\":{\"http_request\":{\"host\":\"example.org\",\"method\":\"GET\",\"path\":\"/rails_rack_logger\",\"port\":80,\"headers\":{\"remote_addr\":\"123.456.789.10\",\"request_id\":\"unique-request-id-1234\"}}}")
43
43
  end
44
44
  end
45
45
  end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe Timber::RackMiddlewares::HTTPContext do
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
11
+
12
+ around(:each) do |example|
13
+ class RackHttpController < ActionController::Base
14
+ layout nil
15
+
16
+ def index
17
+ Thread.current[:_timber_context] = Timber::CurrentContext.instance.snapshot
18
+ render json: {}
19
+ end
20
+
21
+ def method_for_action(action_name)
22
+ action_name
23
+ end
24
+ end
25
+
26
+ ::RailsApp.routes.draw do
27
+ get '/rack_http' => 'rack_http#index'
28
+ end
29
+
30
+ Timecop.freeze(time) { example.run }
31
+
32
+ Object.send(:remove_const, :RackHttpController)
33
+ end
34
+
35
+ describe "#process" do
36
+ it "should set the context" do
37
+ allow(Benchmark).to receive(:ms).and_return(1).and_yield
38
+ allow_any_instance_of(Timber::Probes::ActionControllerLogSubscriber::LogSubscriber).to receive(:logger).and_return(logger)
39
+
40
+ dispatch_rails_request("/rack_http")
41
+ http_context = Thread.current[:_timber_context][:http]
42
+
43
+ expect(http_context).to eq({:method=>"GET", :path=>"/rack_http", :remote_addr=>"123.456.789.10", :request_id=>"unique-request-id-1234"})
44
+ expect(io.string).to include("\"http\":{\"method\":\"GET\",\"path\":\"/rack_http\",\"remote_addr\":\"123.456.789.10\",\"request_id\":\"unique-request-id-1234\"}")
45
+ end
46
+ end
47
+ end
@@ -19,4 +19,5 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  s.add_dependency("msgpack", "~> 1.0")
22
+ s.add_development_dependency("appraisal", "~> 2.1")
22
23
  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.0.13
4
+ version: 1.1.0
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: 2016-12-20 00:00:00.000000000 Z
11
+ date: 2017-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: appraisal
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
27
41
  description:
28
42
  email:
29
43
  - hi@timber.io
@@ -46,7 +60,8 @@ files:
46
60
  - lib/timber/contexts/custom.rb
47
61
  - lib/timber/contexts/http.rb
48
62
  - lib/timber/contexts/organization.rb
49
- - lib/timber/contexts/tags.rb
63
+ - lib/timber/contexts/runtime.rb
64
+ - lib/timber/contexts/system.rb
50
65
  - lib/timber/contexts/user.rb
51
66
  - lib/timber/current_context.rb
52
67
  - lib/timber/event.rb
@@ -54,8 +69,8 @@ files:
54
69
  - lib/timber/events/controller_call.rb
55
70
  - lib/timber/events/custom.rb
56
71
  - lib/timber/events/exception.rb
57
- - lib/timber/events/http_request.rb
58
- - lib/timber/events/http_response.rb
72
+ - lib/timber/events/http_server_request.rb
73
+ - lib/timber/events/http_server_response.rb
59
74
  - lib/timber/events/sql_query.rb
60
75
  - lib/timber/events/template_render.rb
61
76
  - lib/timber/frameworks.rb
@@ -74,12 +89,15 @@ files:
74
89
  - lib/timber/probes/active_record_log_subscriber.rb
75
90
  - lib/timber/probes/active_record_log_subscriber/log_subscriber.rb
76
91
  - lib/timber/probes/active_support_tagged_logging.rb
77
- - lib/timber/probes/rack_http_context.rb
78
92
  - lib/timber/probes/rails_rack_logger.rb
93
+ - lib/timber/rack_middlewares.rb
94
+ - lib/timber/rack_middlewares/http_context.rb
79
95
  - lib/timber/util.rb
80
96
  - lib/timber/util/active_support_log_subscriber.rb
81
97
  - lib/timber/util/hash.rb
98
+ - lib/timber/util/struct.rb
82
99
  - lib/timber/version.rb
100
+ - spec/README.md
83
101
  - spec/spec_helper.rb
84
102
  - spec/support/action_controller.rb
85
103
  - spec/support/action_view.rb
@@ -93,15 +111,17 @@ files:
93
111
  - spec/support/timber.rb
94
112
  - spec/support/timecop.rb
95
113
  - spec/support/webmock.rb
114
+ - spec/timber/contexts_spec.rb
96
115
  - spec/timber/events_spec.rb
97
116
  - spec/timber/log_devices/http_spec.rb
117
+ - spec/timber/log_entry_spec.rb
98
118
  - spec/timber/logger_spec.rb
99
119
  - spec/timber/probes/action_controller_log_subscriber_spec.rb
100
120
  - spec/timber/probes/action_dispatch_debug_exceptions_spec.rb
101
121
  - spec/timber/probes/action_view_log_subscriber_spec.rb
102
122
  - spec/timber/probes/active_record_log_subscriber_spec.rb
103
- - spec/timber/probes/rack_http_context_spec.rb
104
123
  - spec/timber/probes/rails_rack_logger_spec.rb
124
+ - spec/timber/rack_middlewares/http_context_spec.rb
105
125
  - timber.gemspec
106
126
  homepage: https://github.com/timberio/timber-ruby
107
127
  licenses: []
@@ -127,6 +147,7 @@ signing_key:
127
147
  specification_version: 4
128
148
  summary: Instant log gratification.
129
149
  test_files:
150
+ - spec/README.md
130
151
  - spec/spec_helper.rb
131
152
  - spec/support/action_controller.rb
132
153
  - spec/support/action_view.rb
@@ -140,12 +161,14 @@ test_files:
140
161
  - spec/support/timber.rb
141
162
  - spec/support/timecop.rb
142
163
  - spec/support/webmock.rb
164
+ - spec/timber/contexts_spec.rb
143
165
  - spec/timber/events_spec.rb
144
166
  - spec/timber/log_devices/http_spec.rb
167
+ - spec/timber/log_entry_spec.rb
145
168
  - spec/timber/logger_spec.rb
146
169
  - spec/timber/probes/action_controller_log_subscriber_spec.rb
147
170
  - spec/timber/probes/action_dispatch_debug_exceptions_spec.rb
148
171
  - spec/timber/probes/action_view_log_subscriber_spec.rb
149
172
  - spec/timber/probes/active_record_log_subscriber_spec.rb
150
- - spec/timber/probes/rack_http_context_spec.rb
151
173
  - spec/timber/probes/rails_rack_logger_spec.rb
174
+ - spec/timber/rack_middlewares/http_context_spec.rb
@@ -1,22 +0,0 @@
1
- module Timber
2
- module Contexts
3
- # Adds unnamed tags to the context.
4
- #
5
- # **Warning:** It is highly recommend that you use custom contexts instead. As they are
6
- # more descriptive. This module exists primarily to support the ActiveSupport::TaggedLogging
7
- # antipattern.
8
- class Tags < Context
9
- @keyspace = :tags
10
-
11
- attr_reader :values
12
-
13
- def initialize(attributes)
14
- @values = attributes[:values] || raise(ArgumentError.new(":values is required"))
15
- end
16
-
17
- def as_json(_options = {})
18
- values
19
- end
20
- end
21
- end
22
- end
@@ -1,51 +0,0 @@
1
- module Timber
2
- module Probes
3
- # Reponsible for automatically adding the HTTP context for applications that use `Rack`.
4
- class RackHTTPContext < Probe
5
- class Middleware
6
- def initialize(app)
7
- @app = app
8
- end
9
-
10
- def call(env)
11
- request = ::Rack::Request.new(env)
12
- context = Contexts::HTTP.new(
13
- method: request.request_method,
14
- path: request.path,
15
- remote_addr: request.ip,
16
- request_id: request_id(env)
17
- )
18
- CurrentContext.with(context) do
19
- @app.call(env)
20
- end
21
- end
22
-
23
- private
24
- def request_id(env)
25
- env["X-Request-ID"] ||
26
- env["X-Request-Id"] ||
27
- env["action_dispatch.request_id"]
28
- end
29
- end
30
-
31
- attr_reader :middleware, :insert_before
32
-
33
- def initialize(middleware, insert_before)
34
- if middleware.nil?
35
- raise RequirementNotMetError.new("The middleware class attribute is not set. " +
36
- "We need a middleware to insert the probe.")
37
- end
38
- @middleware = middleware
39
- @insert_before = insert_before
40
- end
41
-
42
- def insert!
43
- var_name = :"@_timber_rack_http_inserted"
44
- return true if middleware.instance_variable_defined?(var_name) && middleware.instance_variable_get(var_name) == true
45
- # Rails uses a proxy :/, so we need to do this instance variable hack
46
- middleware.instance_variable_set(var_name, true)
47
- middleware.insert_before insert_before, Middleware
48
- end
49
- end
50
- end
51
- end
@@ -1,50 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Timber::Probes::RackHTTPContext do
4
- describe described_class::Middleware do
5
- let(:time) { Time.utc(2016, 9, 1, 12, 0, 0) }
6
- let(:io) { StringIO.new }
7
- let(:logger) do
8
- logger = Timber::Logger.new(io)
9
- logger.level = ::Logger::INFO
10
- logger
11
- end
12
-
13
- around(:each) do |example|
14
- class RackHttpController < ActionController::Base
15
- layout nil
16
-
17
- def index
18
- Thread.current[:_timber_context] = Timber::CurrentContext.instance.snapshot
19
- render json: {}
20
- end
21
-
22
- def method_for_action(action_name)
23
- action_name
24
- end
25
- end
26
-
27
- ::RailsApp.routes.draw do
28
- get '/rack_http' => 'rack_http#index'
29
- end
30
-
31
- Timecop.freeze(time) { example.run }
32
-
33
- Object.send(:remove_const, :RackHttpController)
34
- end
35
-
36
- describe "#process" do
37
- it "should set the context" do
38
- allow(Benchmark).to receive(:ms).and_return(1).and_yield
39
- allow_any_instance_of(Timber::Probes::ActionControllerLogSubscriber::LogSubscriber).to receive(:logger).and_return(logger)
40
-
41
- dispatch_rails_request("/rack_http")
42
- http_context = Thread.current[:_timber_context][:http]
43
-
44
- expect(http_context).to eq({:method=>"GET", :path=>"/rack_http", :remote_addr=>"123.456.789.10", :request_id=>"unique-request-id-1234"})
45
- message = "Processing by RackHttpController#index as HTML @timber.io {\"level\":\"info\",\"dt\":\"2016-09-01T12:00:00.000000Z\",\"event\":{\"controller_call\":{\"controller\":\"RackHttpController\",\"action\":\"index\"}},\"context\":{\"http\":{\"method\":\"GET\",\"path\":\"/rack_http\",\"remote_addr\":\"123.456.789.10\",\"request_id\":\"unique-request-id-1234\"}}}\nCompleted 200 OK in 0.0ms (Views: 1.0ms) @timber.io {\"level\":\"info\",\"dt\":\"2016-09-01T12:00:00.000000Z\",\"event\":{\"http_response\":{\"status\":200,\"time_ms\":0.0}},\"context\":{\"http\":{\"method\":\"GET\",\"path\":\"/rack_http\",\"remote_addr\":\"123.456.789.10\",\"request_id\":\"unique-request-id-1234\"}}}\n"
46
- expect(io.string).to eq(message)
47
- end
48
- end
49
- end
50
- end