timber 2.0.24 → 2.1.0.rc1
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/.travis.yml +2 -2
- data/CHANGELOG +3 -0
- data/README.md +314 -59
- data/bin/timber +11 -2
- data/lib/timber.rb +2 -7
- data/lib/timber/cli.rb +16 -28
- data/lib/timber/cli/api.rb +80 -14
- data/lib/timber/cli/api/application.rb +30 -0
- data/lib/timber/cli/config_file.rb +66 -0
- data/lib/timber/cli/file_helper.rb +43 -0
- data/lib/timber/cli/installer.rb +58 -0
- data/lib/timber/cli/installers.rb +37 -0
- data/lib/timber/cli/installers/other.rb +47 -0
- data/lib/timber/cli/installers/rails.rb +255 -0
- data/lib/timber/cli/installers/root.rb +189 -0
- data/lib/timber/cli/io.rb +97 -0
- data/lib/timber/cli/io/ansi.rb +22 -0
- data/lib/timber/cli/io/messages.rb +213 -0
- data/lib/timber/cli/os_helper.rb +53 -0
- data/lib/timber/config.rb +97 -43
- data/lib/timber/config/integrations.rb +63 -0
- data/lib/timber/config/integrations/rack.rb +74 -0
- data/lib/timber/context.rb +13 -10
- data/lib/timber/contexts.rb +1 -0
- data/lib/timber/contexts/custom.rb +16 -3
- data/lib/timber/contexts/http.rb +10 -3
- data/lib/timber/contexts/organization.rb +4 -0
- data/lib/timber/contexts/release.rb +46 -0
- data/lib/timber/contexts/runtime.rb +7 -1
- data/lib/timber/contexts/session.rb +8 -1
- data/lib/timber/contexts/system.rb +5 -1
- data/lib/timber/contexts/user.rb +9 -2
- data/lib/timber/current_context.rb +43 -11
- data/lib/timber/events/controller_call.rb +4 -0
- data/lib/timber/events/custom.rb +13 -5
- data/lib/timber/events/exception.rb +4 -0
- data/lib/timber/events/http_client_request.rb +4 -0
- data/lib/timber/events/http_client_response.rb +4 -0
- data/lib/timber/events/http_server_request.rb +5 -0
- data/lib/timber/events/http_server_response.rb +15 -3
- data/lib/timber/events/sql_query.rb +3 -0
- data/lib/timber/events/template_render.rb +3 -0
- data/lib/timber/integration.rb +40 -0
- data/lib/timber/integrations.rb +21 -14
- data/lib/timber/integrations/action_controller.rb +18 -0
- data/lib/timber/integrations/action_controller/log_subscriber.rb +2 -0
- data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +6 -0
- data/lib/timber/integrations/action_dispatch.rb +23 -0
- data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +2 -0
- data/lib/timber/integrations/action_view.rb +18 -0
- data/lib/timber/integrations/action_view/log_subscriber.rb +2 -0
- data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +10 -0
- data/lib/timber/integrations/active_record.rb +18 -0
- data/lib/timber/integrations/active_record/log_subscriber.rb +2 -0
- data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +8 -0
- data/lib/timber/integrations/rack.rb +12 -2
- data/lib/timber/integrations/rack/exception_event.rb +38 -5
- data/lib/timber/integrations/rack/http_context.rb +4 -6
- data/lib/timber/integrations/rack/http_events.rb +177 -27
- data/lib/timber/integrations/rack/middleware.rb +28 -0
- data/lib/timber/integrations/rack/session_context.rb +5 -6
- data/lib/timber/integrations/rack/user_context.rb +90 -43
- data/lib/timber/integrations/rails.rb +22 -0
- data/lib/timber/integrations/rails/rack_logger.rb +2 -0
- data/lib/timber/integrator.rb +18 -3
- data/lib/timber/log_devices/http.rb +107 -99
- data/lib/timber/log_devices/http/dropping_sized_queue.rb +26 -0
- data/lib/timber/log_devices/http/flushable_sized_queue.rb +42 -0
- data/lib/timber/log_entry.rb +14 -2
- data/lib/timber/logger.rb +51 -36
- data/lib/timber/overrides.rb +2 -0
- data/lib/timber/overrides/active_support_3_tagged_logging.rb +103 -0
- data/lib/timber/overrides/active_support_tagged_logging.rb +53 -90
- data/lib/timber/timer.rb +21 -0
- data/lib/timber/util/hash.rb +1 -1
- data/lib/timber/util/http_event.rb +16 -3
- data/lib/timber/version.rb +1 -1
- data/spec/support/timber.rb +2 -3
- data/spec/timber/cli/installers/rails_spec.rb +160 -0
- data/spec/timber/cli/installers/root_spec.rb +100 -0
- data/spec/timber/config_spec.rb +28 -0
- data/spec/timber/current_context_spec.rb +61 -12
- data/spec/timber/events/custom_spec.rb +13 -2
- data/spec/timber/events/exception_spec.rb +15 -0
- data/spec/timber/events/http_server_request_spec.rb +3 -3
- data/spec/timber/integrations/rack/http_events_spec.rb +101 -0
- data/spec/timber/log_devices/http_spec.rb +20 -4
- data/spec/timber/log_entry_spec.rb +2 -1
- data/spec/timber/logger_spec.rb +8 -8
- metadata +40 -9
- data/benchmarks/rails.rb +0 -122
- data/lib/timber/cli/application.rb +0 -28
- data/lib/timber/cli/install.rb +0 -196
- data/lib/timber/cli/io_helper.rb +0 -65
- data/lib/timber/cli/messages.rb +0 -180
- data/lib/timber/integrations/active_support/tagged_logging.rb +0 -71
@@ -1,3 +1,6 @@
|
|
1
|
+
require "timber/event"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Events
|
3
6
|
# The controller call event tracks controller invocations. For example, this line in Rails:
|
@@ -23,6 +26,7 @@ module Timber
|
|
23
26
|
end
|
24
27
|
alias to_h to_hash
|
25
28
|
|
29
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
26
30
|
def as_json(_options = {})
|
27
31
|
{:controller_call => to_hash}
|
28
32
|
end
|
data/lib/timber/events/custom.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require "timber/event"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Events
|
3
6
|
# Allows for custom events that aren't covered elsewhere.
|
@@ -22,7 +25,15 @@ module Timber
|
|
22
25
|
def initialize(attributes)
|
23
26
|
@type = attributes[:type] || raise(ArgumentError.new(":type is required"))
|
24
27
|
@message = attributes[:message] || raise(ArgumentError.new(":message is required"))
|
25
|
-
|
28
|
+
|
29
|
+
data = attributes[:data]
|
30
|
+
|
31
|
+
if data.is_a?(Hash) && data[:time_ms].is_a?(Time)
|
32
|
+
data[:time_ms] = Timer.duration_ms(data[:time_ms])
|
33
|
+
@message << " in #{data[:time_ms]}ms"
|
34
|
+
end
|
35
|
+
|
36
|
+
@data = data
|
26
37
|
end
|
27
38
|
|
28
39
|
def to_hash
|
@@ -30,13 +41,10 @@ module Timber
|
|
30
41
|
end
|
31
42
|
alias to_h to_hash
|
32
43
|
|
44
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
33
45
|
def as_json(_options = {})
|
34
46
|
{:custom => to_hash}
|
35
47
|
end
|
36
|
-
|
37
|
-
def to_json(options = {})
|
38
|
-
as_json().to_json(options)
|
39
|
-
end
|
40
48
|
end
|
41
49
|
end
|
42
50
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require "timber/event"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Events
|
3
6
|
# The exception event is used to track exceptions.
|
@@ -25,6 +28,7 @@ module Timber
|
|
25
28
|
end
|
26
29
|
alias to_h to_hash
|
27
30
|
|
31
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
28
32
|
def as_json(_options = {})
|
29
33
|
{:exception => to_hash}
|
30
34
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require "timber/event"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Events
|
3
6
|
# The HTTP client request event tracks *outgoing* HTTP requests giving you structured insight
|
@@ -30,6 +33,7 @@ module Timber
|
|
30
33
|
end
|
31
34
|
alias to_h to_hash
|
32
35
|
|
36
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
33
37
|
def as_json(_options = {})
|
34
38
|
{:http_client_request => to_hash}
|
35
39
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require "timber/event"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Events
|
3
6
|
# The HTTP client response event tracks responses for *outgoing* HTTP *requests*.
|
@@ -25,6 +28,7 @@ module Timber
|
|
25
28
|
end
|
26
29
|
alias to_h to_hash
|
27
30
|
|
31
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
28
32
|
def as_json(_options = {})
|
29
33
|
{:http_client_response => to_hash}
|
30
34
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require "timber/event"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Events
|
3
6
|
# The HTTP server request event tracks incoming HTTP requests to your HTTP server.
|
@@ -10,6 +13,7 @@ module Timber
|
|
10
13
|
:scheme
|
11
14
|
|
12
15
|
def initialize(attributes)
|
16
|
+
@body = attributes[:body] && Util::HTTPEvent.normalize_body(attributes[:body])
|
13
17
|
@headers = Util::HTTPEvent.normalize_headers(attributes[:headers])
|
14
18
|
@host = attributes[:host] || raise(ArgumentError.new(":host is required"))
|
15
19
|
@method = Util::HTTPEvent.normalize_method(attributes[:method]) || raise(ArgumentError.new(":method is required"))
|
@@ -26,6 +30,7 @@ module Timber
|
|
26
30
|
end
|
27
31
|
alias to_h to_hash
|
28
32
|
|
33
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
29
34
|
def as_json(_options = {})
|
30
35
|
{:http_server_request => to_hash}
|
31
36
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require "timber/event"
|
2
|
+
require "timber/util"
|
3
|
+
|
1
4
|
module Timber
|
2
5
|
module Events
|
3
6
|
# The HTTP server response event tracks outgoing HTTP responses that you send
|
@@ -6,10 +9,12 @@ module Timber
|
|
6
9
|
# @note This event should be installed automatically through integrations,
|
7
10
|
# such as the {Integrations::ActionController::LogSubscriber} integration.
|
8
11
|
class HTTPServerResponse < Timber::Event
|
9
|
-
attr_reader :headers, :request_id, :status, :time_ms
|
12
|
+
attr_reader :body, :headers, :http_context, :request_id, :status, :time_ms
|
10
13
|
|
11
14
|
def initialize(attributes)
|
15
|
+
@body = attributes[:body] && Util::HTTPEvent.normalize_body(attributes[:body])
|
12
16
|
@headers = Util::HTTPEvent.normalize_headers(attributes[:headers])
|
17
|
+
@http_context = attributes[:http_context]
|
13
18
|
@request_id = attributes[:request_id]
|
14
19
|
@status = attributes[:status] || raise(ArgumentError.new(":status is required"))
|
15
20
|
@time_ms = attributes[:time_ms] || raise(ArgumentError.new(":time_ms is required"))
|
@@ -17,16 +22,23 @@ module Timber
|
|
17
22
|
end
|
18
23
|
|
19
24
|
def to_hash
|
20
|
-
{headers: headers, request_id: request_id, status: status, time_ms: time_ms}
|
25
|
+
{body: body, headers: headers, request_id: request_id, status: status, time_ms: time_ms}
|
21
26
|
end
|
22
27
|
alias to_h to_hash
|
23
28
|
|
29
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
24
30
|
def as_json(_options = {})
|
25
31
|
{:http_server_response => to_hash}
|
26
32
|
end
|
27
33
|
|
34
|
+
# Returns the human readable log message for this event.
|
28
35
|
def message
|
29
|
-
|
36
|
+
if http_context
|
37
|
+
"#{http_context[:method]} #{http_context[:path]} sent #{status} #{status_description} " \
|
38
|
+
"in #{time_ms}ms"
|
39
|
+
else
|
40
|
+
"Completed #{status} #{status_description} in #{time_ms}ms"
|
41
|
+
end
|
30
42
|
end
|
31
43
|
|
32
44
|
def status_description
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "timber/event"
|
2
|
+
|
1
3
|
module Timber
|
2
4
|
module Events
|
3
5
|
# The SQL query event tracks sql queries to your database.
|
@@ -19,6 +21,7 @@ module Timber
|
|
19
21
|
end
|
20
22
|
alias to_h to_hash
|
21
23
|
|
24
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
22
25
|
def as_json(_options = {})
|
23
26
|
{:sql_query => to_hash}
|
24
27
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "timber/event"
|
2
|
+
|
1
3
|
module Timber
|
2
4
|
module Events
|
3
5
|
# The template render event track template renderings and their performance.
|
@@ -19,6 +21,7 @@ module Timber
|
|
19
21
|
end
|
20
22
|
alias to_h to_hash
|
21
23
|
|
24
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
22
25
|
def as_json(_options = {})
|
23
26
|
{:template_render => to_hash}
|
24
27
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Timber
|
2
|
+
# An integration represent an integration for an entire library. For example, `Rack`.
|
3
|
+
# While the Timber `Rack` integration is comprised of multiple middlewares, the
|
4
|
+
# `Timber::Integrations::Rack` module is an entire integration that extends this module.
|
5
|
+
module Integration
|
6
|
+
# Easily sisable entire library integrations. This is like removing the code from
|
7
|
+
# Timber. It will not touch this library and the library will function as it would
|
8
|
+
# without Timber.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# Timber::Integrations::ActiveRecord.enabled = false
|
12
|
+
def enabled=(value)
|
13
|
+
@enabled = value
|
14
|
+
end
|
15
|
+
|
16
|
+
# Accessor method for {#enabled=}
|
17
|
+
def enabled?
|
18
|
+
@enabled != false
|
19
|
+
end
|
20
|
+
|
21
|
+
# Silences a library's logs. This ensures that logs are not generated at all
|
22
|
+
# from this library.
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# Timber::Integrations::ActiveRecord.silence = true
|
26
|
+
def silence=(value)
|
27
|
+
@silence = value
|
28
|
+
end
|
29
|
+
|
30
|
+
# Accessor method for {#silence=}
|
31
|
+
def silence?
|
32
|
+
@silence == true
|
33
|
+
end
|
34
|
+
|
35
|
+
# Abstract method that each integration must implement.
|
36
|
+
def integrate!
|
37
|
+
raise NotImplementedError.new
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/timber/integrations.rb
CHANGED
@@ -1,22 +1,29 @@
|
|
1
|
-
require "timber/integrations/action_controller
|
2
|
-
require "timber/integrations/action_dispatch
|
3
|
-
require "timber/integrations/action_view
|
4
|
-
require "timber/integrations/active_record
|
5
|
-
require "timber/integrations/active_support/tagged_logging"
|
1
|
+
require "timber/integrations/action_controller"
|
2
|
+
require "timber/integrations/action_dispatch"
|
3
|
+
require "timber/integrations/action_view"
|
4
|
+
require "timber/integrations/active_record"
|
6
5
|
require "timber/integrations/rack"
|
7
|
-
require "timber/integrations/rails
|
6
|
+
require "timber/integrations/rails"
|
8
7
|
|
9
8
|
module Timber
|
10
|
-
# Namespace for all integrations.
|
11
|
-
#
|
9
|
+
# Namespace for all integrations. Each integration provides it's own settings.
|
10
|
+
# And all integrations can be disabled with the {.enabled=} class method.
|
12
11
|
module Integrations
|
12
|
+
# Disable / enable _all_ integrations with one setting.
|
13
|
+
def self.enabled=(value)
|
14
|
+
ActionController.enabled = value
|
15
|
+
ActionView.enabled = value
|
16
|
+
ActiveRecord.enabled = value
|
17
|
+
Rack.enabled = value
|
18
|
+
end
|
19
|
+
|
20
|
+
# Integrates all enabled integrations in one call.
|
13
21
|
def self.integrate!
|
14
|
-
ActionController
|
15
|
-
ActionDispatch
|
16
|
-
ActionView
|
17
|
-
ActiveRecord
|
18
|
-
|
19
|
-
Rails::RackLogger.integrate!
|
22
|
+
ActionController.integrate!
|
23
|
+
ActionDispatch.integrate!
|
24
|
+
ActionView.integrate!
|
25
|
+
ActiveRecord.integrate!
|
26
|
+
Rails.integrate!
|
20
27
|
end
|
21
28
|
end
|
22
29
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "timber/integration"
|
2
|
+
require "timber/integrations/action_controller/log_subscriber"
|
3
|
+
|
4
|
+
module Timber
|
5
|
+
module Integrations
|
6
|
+
# Module for holding *all* ActionController integrations. See {Integration} for
|
7
|
+
# configuration details for all integrations.
|
8
|
+
module ActionController
|
9
|
+
extend Integration
|
10
|
+
|
11
|
+
def self.integrate!
|
12
|
+
return false if !enabled?
|
13
|
+
|
14
|
+
LogSubscriber.integrate!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -10,6 +10,8 @@ module Timber
|
|
10
10
|
# @private
|
11
11
|
class TimberLogSubscriber < ::ActionController::LogSubscriber
|
12
12
|
def start_processing(event)
|
13
|
+
return true if silence?
|
14
|
+
|
13
15
|
info do
|
14
16
|
payload = event.payload
|
15
17
|
params = payload[:params].except(*INTERNAL_PARAMS)
|
@@ -33,6 +35,10 @@ module Timber
|
|
33
35
|
payload[:formats].first # rails 3.X
|
34
36
|
end
|
35
37
|
end
|
38
|
+
|
39
|
+
def silence?
|
40
|
+
ActionController.silence?
|
41
|
+
end
|
36
42
|
end
|
37
43
|
end
|
38
44
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "timber/integration"
|
2
|
+
require "timber/integrations/rack/exception_event"
|
3
|
+
require "timber/integrations/action_dispatch/debug_exceptions"
|
4
|
+
|
5
|
+
module Timber
|
6
|
+
module Integrations
|
7
|
+
# Module for holding *all* ActionDispatch integrations. This module does *not*
|
8
|
+
# extend {Integration} because it's dependent on {Rack::ExceptionEvent}. This
|
9
|
+
# module simply disables the exception tracking middleware so that our middleware
|
10
|
+
# works as expected.
|
11
|
+
module ActionDispatch
|
12
|
+
def self.enabled?
|
13
|
+
Rack::ExceptionEvent.enabled?
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.integrate!
|
17
|
+
return false if !enabled?
|
18
|
+
|
19
|
+
DebugExceptions.integrate!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "timber/integration"
|
2
|
+
require "timber/integrations/action_view/log_subscriber"
|
3
|
+
|
4
|
+
module Timber
|
5
|
+
module Integrations
|
6
|
+
# Module for holding *all* ActionView integrations. See {Integration} for
|
7
|
+
# configuration details for all integrations.
|
8
|
+
module ActionView
|
9
|
+
extend Integration
|
10
|
+
|
11
|
+
def self.integrate!
|
12
|
+
return false if !enabled?
|
13
|
+
|
14
|
+
LogSubscriber.integrate!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -10,6 +10,8 @@ module Timber
|
|
10
10
|
# @private
|
11
11
|
class TimberLogSubscriber < ::ActionView::LogSubscriber
|
12
12
|
def render_template(event)
|
13
|
+
return true if silence?
|
14
|
+
|
13
15
|
info do
|
14
16
|
full_name = from_rails_root(event.payload[:identifier])
|
15
17
|
message = " Rendered #{full_name}"
|
@@ -25,6 +27,8 @@ module Timber
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def render_partial(event)
|
30
|
+
return true if silence?
|
31
|
+
|
28
32
|
info do
|
29
33
|
full_name = from_rails_root(event.payload[:identifier])
|
30
34
|
message = " Rendered #{full_name}"
|
@@ -41,6 +45,8 @@ module Timber
|
|
41
45
|
end
|
42
46
|
|
43
47
|
def render_collection(event)
|
48
|
+
return true if silence?
|
49
|
+
|
44
50
|
if respond_to?(:render_count, true)
|
45
51
|
info do
|
46
52
|
identifier = event.payload[:identifier] || "templates"
|
@@ -66,6 +72,10 @@ module Timber
|
|
66
72
|
# rendering a template. If you disagree, please feel free to open a PR and we
|
67
73
|
# can make this an option.
|
68
74
|
end
|
75
|
+
|
76
|
+
def silence?
|
77
|
+
ActionView.silence?
|
78
|
+
end
|
69
79
|
end
|
70
80
|
end
|
71
81
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "timber/integration"
|
2
|
+
require "timber/integrations/active_record/log_subscriber"
|
3
|
+
|
4
|
+
module Timber
|
5
|
+
module Integrations
|
6
|
+
# Module for holding *all* ActiveRecord integrations. See {Integration} for
|
7
|
+
# configuration details for all integrations.
|
8
|
+
module ActiveRecord
|
9
|
+
extend Integration
|
10
|
+
|
11
|
+
def self.integrate!
|
12
|
+
return false if !enabled?
|
13
|
+
|
14
|
+
LogSubscriber.integrate!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|