timber 2.6.2 → 3.0.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.
- checksums.yaml +5 -5
- data/.travis.yml +8 -38
- data/CHANGELOG.md +9 -0
- data/README.md +30 -284
- data/Rakefile +78 -0
- data/lib/timber.rb +6 -6
- data/lib/timber/config.rb +1 -83
- data/lib/timber/config/integrations.rb +1 -47
- data/lib/timber/context.rb +3 -24
- data/lib/timber/contexts.rb +2 -30
- data/lib/timber/contexts/http.rb +16 -36
- data/lib/timber/contexts/release.rb +12 -23
- data/lib/timber/contexts/runtime.rb +9 -36
- data/lib/timber/contexts/session.rb +8 -21
- data/lib/timber/contexts/system.rb +9 -16
- data/lib/timber/contexts/user.rb +13 -33
- data/lib/timber/current_context.rb +16 -78
- data/lib/timber/event.rb +12 -9
- data/lib/timber/events.rb +1 -33
- data/lib/timber/events/controller_call.rb +20 -31
- data/lib/timber/events/error.rb +18 -26
- data/lib/timber/events/exception.rb +1 -0
- data/lib/timber/events/sql_query.rb +14 -24
- data/lib/timber/events/template_render.rb +13 -24
- data/lib/timber/integration.rb +1 -1
- data/lib/timber/integrator.rb +1 -1
- data/lib/timber/log_devices/http.rb +98 -19
- data/lib/timber/log_entry.rb +6 -24
- data/lib/timber/logger.rb +5 -14
- data/lib/timber/util.rb +1 -6
- data/lib/timber/util/non_nil_hash_builder.rb +3 -1
- data/lib/timber/version.rb +1 -1
- data/spec/README.md +2 -8
- data/spec/spec_helper.rb +0 -7
- data/spec/support/timber.rb +1 -3
- data/spec/timber/current_context_spec.rb +12 -50
- data/spec/timber/events/controller_call_spec.rb +4 -4
- data/spec/timber/events/error_spec.rb +4 -9
- data/spec/timber/log_devices/http_spec.rb +26 -2
- data/spec/timber/log_entry_spec.rb +12 -6
- data/spec/timber/logger_spec.rb +27 -68
- data/timber.gemspec +1 -1
- metadata +5 -139
- data/gemfiles/rails-3.0.gemfile +0 -5
- data/gemfiles/rails-3.1.gemfile +0 -5
- data/gemfiles/rails-3.2.gemfile +0 -5
- data/gemfiles/rails-4.0.gemfile +0 -9
- data/gemfiles/rails-4.1.gemfile +0 -9
- data/gemfiles/rails-4.2.gemfile +0 -9
- data/gemfiles/rails-5.0.gemfile +0 -9
- data/gemfiles/rails-5.1.gemfile +0 -9
- data/gemfiles/rails-edge.gemfile +0 -7
- data/lib/timber/cli.rb +0 -60
- data/lib/timber/cli/api.rb +0 -183
- data/lib/timber/cli/api/application.rb +0 -34
- data/lib/timber/cli/config_file.rb +0 -71
- data/lib/timber/cli/file_helper.rb +0 -53
- data/lib/timber/cli/installer.rb +0 -70
- data/lib/timber/cli/installers.rb +0 -102
- data/lib/timber/cli/installers/config_file.rb +0 -51
- data/lib/timber/cli/installers/other.rb +0 -59
- data/lib/timber/cli/installers/rails.rb +0 -225
- data/lib/timber/cli/installers/root.rb +0 -116
- data/lib/timber/cli/io.rb +0 -100
- data/lib/timber/cli/io/ansi.rb +0 -22
- data/lib/timber/cli/io/messages.rb +0 -198
- data/lib/timber/cli/os_helper.rb +0 -74
- data/lib/timber/config/integrations/rack.rb +0 -74
- data/lib/timber/contexts/custom.rb +0 -44
- data/lib/timber/contexts/organization.rb +0 -48
- data/lib/timber/events/custom.rb +0 -53
- data/lib/timber/events/http_request.rb +0 -71
- data/lib/timber/events/http_response.rb +0 -81
- data/lib/timber/frameworks.rb +0 -19
- data/lib/timber/frameworks/rails.rb +0 -27
- data/lib/timber/integrations.rb +0 -29
- data/lib/timber/integrations/action_controller.rb +0 -18
- data/lib/timber/integrations/action_controller/log_subscriber.rb +0 -27
- data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +0 -46
- data/lib/timber/integrations/action_dispatch.rb +0 -23
- data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +0 -53
- data/lib/timber/integrations/action_view.rb +0 -18
- data/lib/timber/integrations/action_view/log_subscriber.rb +0 -27
- data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +0 -83
- data/lib/timber/integrations/active_record.rb +0 -18
- data/lib/timber/integrations/active_record/log_subscriber.rb +0 -26
- data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +0 -53
- data/lib/timber/integrations/rack.rb +0 -27
- data/lib/timber/integrations/rack/error_event.rb +0 -64
- data/lib/timber/integrations/rack/http_context.rb +0 -27
- data/lib/timber/integrations/rack/http_events.rb +0 -210
- data/lib/timber/integrations/rack/middleware.rb +0 -28
- data/lib/timber/integrations/rack/session_context.rb +0 -65
- data/lib/timber/integrations/rack/user_context.rb +0 -135
- data/lib/timber/integrations/rails.rb +0 -22
- data/lib/timber/integrations/rails/rack_logger.rb +0 -60
- data/lib/timber/overrides.rb +0 -12
- data/lib/timber/overrides/active_support_3_tagged_logging.rb +0 -111
- data/lib/timber/overrides/active_support_buffered_logger.rb +0 -22
- data/lib/timber/overrides/active_support_tagged_logging.rb +0 -66
- data/lib/timber/overrides/lograge.rb +0 -18
- data/lib/timber/overrides/rails_stdout_logging.rb +0 -21
- data/lib/timber/util/active_support_log_subscriber.rb +0 -37
- data/lib/timber/util/attribute_normalizer.rb +0 -89
- data/lib/timber/util/hash.rb +0 -90
- data/lib/timber/util/request.rb +0 -72
- data/lib/timber/util/struct.rb +0 -16
- data/spec/rails/tagged_logging_spec.rb +0 -44
- data/spec/support/action_controller.rb +0 -8
- data/spec/support/active_record.rb +0 -32
- data/spec/support/rails.rb +0 -67
- data/spec/support/rails/templates/_partial.html +0 -1
- data/spec/support/rails/templates/template.html +0 -1
- data/spec/timber/cli/config_file_spec.rb +0 -26
- data/spec/timber/cli/installers/config_file_spec.rb +0 -36
- data/spec/timber/cli/installers/other_spec.rb +0 -49
- data/spec/timber/cli/installers/rails_spec.rb +0 -364
- data/spec/timber/cli/installers/root_spec.rb +0 -73
- data/spec/timber/config_spec.rb +0 -28
- data/spec/timber/contexts/custom_spec.rb +0 -11
- data/spec/timber/contexts/organization_spec.rb +0 -11
- data/spec/timber/contexts/runtime_spec.rb +0 -11
- data/spec/timber/contexts/system_spec.rb +0 -11
- data/spec/timber/contexts/user_spec.rb +0 -11
- data/spec/timber/contexts_spec.rb +0 -49
- data/spec/timber/event_spec.rb +0 -10
- data/spec/timber/events/custom_spec.rb +0 -36
- data/spec/timber/events/http_request_spec.rb +0 -32
- data/spec/timber/events/http_response_spec.rb +0 -12
- data/spec/timber/events_spec.rb +0 -55
- data/spec/timber/integrations/action_controller/log_subscriber_spec.rb +0 -55
- data/spec/timber/integrations/action_dispatch/debug_exceptions_spec.rb +0 -53
- data/spec/timber/integrations/action_view/log_subscriber_spec.rb +0 -115
- data/spec/timber/integrations/active_record/log_subscriber_spec.rb +0 -46
- data/spec/timber/integrations/rack/error_event_spec.rb +0 -63
- data/spec/timber/integrations/rack/http_context_spec.rb +0 -60
- data/spec/timber/integrations/rack/http_events_spec.rb +0 -101
- data/spec/timber/integrations/rack/session_context_spec.rb +0 -62
- data/spec/timber/integrations/rails/rack_logger_spec.rb +0 -58
- data/spec/timber/util/attribute_normalizer_spec.rb +0 -90
- data/spec/timber/util/hash_spec.rb +0 -30
- data/spec/timber/util/request_spec.rb +0 -10
@@ -1,83 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Integrations
|
3
|
-
module ActionView
|
4
|
-
class LogSubscriber < Integrator
|
5
|
-
|
6
|
-
# The log subscriber that replaces the default `ActionView::LogSubscriber`.
|
7
|
-
# The intent of this subscriber is to, as transparently as possible, properly
|
8
|
-
# track events that are being logged here.
|
9
|
-
#
|
10
|
-
# @private
|
11
|
-
class TimberLogSubscriber < ::ActionView::LogSubscriber
|
12
|
-
def render_template(event)
|
13
|
-
return true if silence?
|
14
|
-
|
15
|
-
info do
|
16
|
-
full_name = from_rails_root(event.payload[:identifier])
|
17
|
-
message = " Rendered #{full_name}"
|
18
|
-
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
|
19
|
-
message << " (#{event.duration.round(1)}ms)"
|
20
|
-
|
21
|
-
Events::TemplateRender.new(
|
22
|
-
name: full_name,
|
23
|
-
time_ms: event.duration,
|
24
|
-
message: message
|
25
|
-
)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def render_partial(event)
|
30
|
-
return true if silence?
|
31
|
-
|
32
|
-
info do
|
33
|
-
full_name = from_rails_root(event.payload[:identifier])
|
34
|
-
message = " Rendered #{full_name}"
|
35
|
-
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
|
36
|
-
message << " (#{event.duration.round(1)}ms)"
|
37
|
-
message << " #{cache_message(event.payload)}" if event.payload.key?(:cache_hit)
|
38
|
-
|
39
|
-
Events::TemplateRender.new(
|
40
|
-
name: full_name,
|
41
|
-
time_ms: event.duration,
|
42
|
-
message: message
|
43
|
-
)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def render_collection(event)
|
48
|
-
return true if silence?
|
49
|
-
|
50
|
-
if respond_to?(:render_count, true)
|
51
|
-
info do
|
52
|
-
identifier = event.payload[:identifier] || "templates"
|
53
|
-
full_name = from_rails_root(identifier)
|
54
|
-
message = " Rendered collection of #{full_name}" \
|
55
|
-
" #{render_count(event.payload)} (#{event.duration.round(1)}ms)"
|
56
|
-
|
57
|
-
Events::TemplateRender.new(
|
58
|
-
name: full_name,
|
59
|
-
time_ms: event.duration,
|
60
|
-
message: message
|
61
|
-
)
|
62
|
-
end
|
63
|
-
else
|
64
|
-
# Older versions of rails delegate this method to #render_template
|
65
|
-
render_template(event)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
def log_rendering_start(payload)
|
71
|
-
# Consolidates 2 template rendering events into 1. We don't need 2 events for
|
72
|
-
# rendering a template. If you disagree, please feel free to open a PR and we
|
73
|
-
# can make this an option.
|
74
|
-
end
|
75
|
-
|
76
|
-
def silence?
|
77
|
-
ActionView.silence?
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
@@ -1,18 +0,0 @@
|
|
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
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require "timber/integrator"
|
2
|
-
|
3
|
-
module Timber
|
4
|
-
module Integrations
|
5
|
-
module ActiveRecord
|
6
|
-
# Reponsible for uninstalling the default `ActiveRecord::LogSubscriber` and replacing it
|
7
|
-
# with the `TimberLogSubscriber`.
|
8
|
-
#
|
9
|
-
# @private
|
10
|
-
class LogSubscriber < Integrator
|
11
|
-
def initialize
|
12
|
-
require "timber/integrations/active_record/log_subscriber/timber_log_subscriber"
|
13
|
-
rescue LoadError => e
|
14
|
-
raise RequirementNotMetError.new(e.message)
|
15
|
-
end
|
16
|
-
|
17
|
-
def integrate!
|
18
|
-
return true if Util::ActiveSupportLogSubscriber.subscribed?(:active_record, TimberLogSubscriber)
|
19
|
-
|
20
|
-
Util::ActiveSupportLogSubscriber.unsubscribe!(:active_record, ::ActiveRecord::LogSubscriber)
|
21
|
-
TimberLogSubscriber.attach_to(:active_record)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# We require all of ActiveRecord because the #logger method in ::ActiveRecord::LogSubscriber
|
2
|
-
# uses ActiveRecord::Base. We can't require active_record/base directly because ActiveRecord
|
3
|
-
# does not require files properly and we receive unintialized constant errors.
|
4
|
-
require "active_record"
|
5
|
-
require "active_record/log_subscriber"
|
6
|
-
|
7
|
-
require "timber/integrator"
|
8
|
-
|
9
|
-
module Timber
|
10
|
-
module Integrations
|
11
|
-
module ActiveRecord
|
12
|
-
class LogSubscriber < Integrator
|
13
|
-
# The log subscriber that replaces the default `ActiveRecord::LogSubscriber`.
|
14
|
-
# The intent of this subscriber is to, as transparently as possible, properly
|
15
|
-
# track events that are being logged here. This LogSubscriber will never change
|
16
|
-
# default behavior / log messages.
|
17
|
-
#
|
18
|
-
# @private
|
19
|
-
class TimberLogSubscriber < ::ActiveRecord::LogSubscriber
|
20
|
-
def sql(event)
|
21
|
-
return true if silence?
|
22
|
-
|
23
|
-
r = super(event)
|
24
|
-
|
25
|
-
if @message
|
26
|
-
payload = event.payload
|
27
|
-
event = Events::SQLQuery.new(
|
28
|
-
sql: payload[:sql],
|
29
|
-
time_ms: event.duration,
|
30
|
-
message: @message
|
31
|
-
)
|
32
|
-
|
33
|
-
logger.debug event
|
34
|
-
|
35
|
-
@message = nil
|
36
|
-
end
|
37
|
-
|
38
|
-
r
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
def debug(message)
|
43
|
-
@message = message
|
44
|
-
end
|
45
|
-
|
46
|
-
def silence?
|
47
|
-
ActiveRecord.silence?
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require "timber/integrations/rack/error_event"
|
2
|
-
require "timber/integrations/rack/http_context"
|
3
|
-
require "timber/integrations/rack/http_events"
|
4
|
-
require "timber/integrations/rack/session_context"
|
5
|
-
require "timber/integrations/rack/user_context"
|
6
|
-
|
7
|
-
module Timber
|
8
|
-
module Integrations
|
9
|
-
module Rack
|
10
|
-
# Enable / disable all Rack middlewares with a single setting.
|
11
|
-
def self.enabled=(value)
|
12
|
-
ErrorEvent.enabled = value
|
13
|
-
HTTPContext.enabled = value
|
14
|
-
HTTPEvents.enabled = value
|
15
|
-
SessionContext.enabled = value
|
16
|
-
UserContext.enabled = value
|
17
|
-
end
|
18
|
-
|
19
|
-
# All enabled middlewares. The order is relevant. Middlewares that set
|
20
|
-
# context are added first so that context is included in subsequent log lines.
|
21
|
-
def self.middlewares
|
22
|
-
@middlewares ||= [HTTPContext, SessionContext, UserContext,
|
23
|
-
HTTPEvents, ErrorEvent].select(&:enabled?)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
# Rails 3.2 requires you to require all of Rails before requiring
|
3
|
-
# the exception wrapper.
|
4
|
-
require "rails"
|
5
|
-
require "action_dispatch/middleware/exception_wrapper"
|
6
|
-
rescue Exception
|
7
|
-
end
|
8
|
-
|
9
|
-
require "timber/config"
|
10
|
-
require "timber/events/error"
|
11
|
-
require "timber/integrations/rack/middleware"
|
12
|
-
require "timber/util"
|
13
|
-
|
14
|
-
module Timber
|
15
|
-
module Integrations
|
16
|
-
module Rack
|
17
|
-
# A Rack middleware that is reponsible for capturing exception and error events
|
18
|
-
# {Timber::Events::Error}.
|
19
|
-
class ErrorEvent < Middleware
|
20
|
-
# We determine this when the app loads to avoid the overhead on a per request basis.
|
21
|
-
EXCEPTION_WRAPPER_TAKES_CLEANER = defined?(::ActionDispatch::ExceptionWrapper) &&
|
22
|
-
!::ActionDispatch::ExceptionWrapper.instance_methods.include?(:env)
|
23
|
-
|
24
|
-
def call(env)
|
25
|
-
begin
|
26
|
-
status, headers, body = @app.call(env)
|
27
|
-
rescue Exception => exception
|
28
|
-
Config.instance.logger.fatal do
|
29
|
-
backtrace = extract_backtrace(env, exception)
|
30
|
-
|
31
|
-
Events::Error.new(
|
32
|
-
name: exception.class.name,
|
33
|
-
error_message: exception.message,
|
34
|
-
backtrace: backtrace
|
35
|
-
)
|
36
|
-
end
|
37
|
-
|
38
|
-
raise exception
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
# Rails provides a backtrace cleaner, so we use it here.
|
44
|
-
def extract_backtrace(env, exception)
|
45
|
-
if defined?(::ActionDispatch::ExceptionWrapper)
|
46
|
-
wrapper = if EXCEPTION_WRAPPER_TAKES_CLEANER
|
47
|
-
request = Util::Request.new(env)
|
48
|
-
backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
|
49
|
-
::ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception)
|
50
|
-
else
|
51
|
-
::ActionDispatch::ExceptionWrapper.new(env, exception)
|
52
|
-
end
|
53
|
-
|
54
|
-
trace = wrapper.application_trace
|
55
|
-
trace = wrapper.framework_trace if trace.empty?
|
56
|
-
trace
|
57
|
-
else
|
58
|
-
exception.backtrace
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require "timber/contexts/http"
|
2
|
-
require "timber/current_context"
|
3
|
-
require "timber/integrations/rack/middleware"
|
4
|
-
require "timber/util"
|
5
|
-
|
6
|
-
module Timber
|
7
|
-
module Integrations
|
8
|
-
module Rack
|
9
|
-
# A Rack middleware that is reponsible for adding the HTTP context {Timber::Contexts::HTTP}.
|
10
|
-
class HTTPContext < Middleware
|
11
|
-
def call(env)
|
12
|
-
request = Util::Request.new(env)
|
13
|
-
context = Contexts::HTTP.new(
|
14
|
-
host: request.host,
|
15
|
-
method: request.request_method,
|
16
|
-
path: request.path,
|
17
|
-
remote_addr: request.ip,
|
18
|
-
request_id: request.request_id
|
19
|
-
)
|
20
|
-
CurrentContext.with(context) do
|
21
|
-
@app.call(env)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,210 +0,0 @@
|
|
1
|
-
require "set"
|
2
|
-
|
3
|
-
require "timber/config"
|
4
|
-
require "timber/contexts/http"
|
5
|
-
require "timber/current_context"
|
6
|
-
require "timber/events/http_request"
|
7
|
-
require "timber/events/http_response"
|
8
|
-
require "timber/integrations/rack/middleware"
|
9
|
-
|
10
|
-
module Timber
|
11
|
-
module Integrations
|
12
|
-
module Rack
|
13
|
-
# A Rack middleware that is reponsible for capturing and logging HTTP server requests and
|
14
|
-
# response events. The {Events::HTTPRequest} and {Events::HTTPResponse} events
|
15
|
-
# respectively.
|
16
|
-
class HTTPEvents < Middleware
|
17
|
-
class << self
|
18
|
-
# Allows you to capture the HTTP request body, default is off (false).
|
19
|
-
#
|
20
|
-
# Capturing HTTP bodies can be extremely helpful when debugging issues,
|
21
|
-
# but please proceed with caution:
|
22
|
-
#
|
23
|
-
# 1. Capturing HTTP bodies can use quite a bit of data (this can be mitigated, see below)
|
24
|
-
# 2. The {Events::ControllerCall} event captures the parsed parmaters sent to
|
25
|
-
# the controller. This is a parsed representation of the body, which is usually more
|
26
|
-
# helpful and redundant to the body captured here.
|
27
|
-
#
|
28
|
-
# If you opt to capture bodies, you can also truncate the size to reduce the data
|
29
|
-
# captured. See {Events::HTTPRequest}.
|
30
|
-
#
|
31
|
-
# @example
|
32
|
-
# Timber::Integrations::Rack::HTTPEvents.capture_request_body = true
|
33
|
-
def capture_request_body=(value)
|
34
|
-
@capture_request_body = value
|
35
|
-
end
|
36
|
-
|
37
|
-
# Accessor method for {#capture_request_body=}
|
38
|
-
def capture_request_body?
|
39
|
-
@capture_request_body == true
|
40
|
-
end
|
41
|
-
|
42
|
-
# Just like {#capture_request_body=} but for the {Events::HTTPResponse} event.
|
43
|
-
# Please see {#capture_request_body=} for more details. The documentation there also
|
44
|
-
# applies here.
|
45
|
-
def capture_response_body=(value)
|
46
|
-
@capture_response_body = value
|
47
|
-
end
|
48
|
-
|
49
|
-
# Accessor method for {#capture_response_body=}
|
50
|
-
def capture_response_body?
|
51
|
-
@capture_response_body == true
|
52
|
-
end
|
53
|
-
|
54
|
-
# Collapse both the HTTP request and response events into a single log line event.
|
55
|
-
# While we don't recommend this, it can help to reduce log volume if desired.
|
56
|
-
# The reason we don't recommend this, is because the logging service you use should
|
57
|
-
# not be so expensive that you need to strip out useful logs. It should also provide
|
58
|
-
# the tools necessary to properly search your logs and reduce noise. Such as viewing
|
59
|
-
# logs for a specific request.
|
60
|
-
#
|
61
|
-
# To provide an example. This setting turns this:
|
62
|
-
#
|
63
|
-
# Started GET "/" for 127.0.0.1 at 2012-03-10 14:28:14 +0100
|
64
|
-
# Completed 200 OK in 79ms (Views: 78.8ms | ActiveRecord: 0.0ms)
|
65
|
-
#
|
66
|
-
# Into this:
|
67
|
-
#
|
68
|
-
# Get "/" sent 200 OK in 79ms
|
69
|
-
#
|
70
|
-
# The single event is still a {Timber::Events::HTTPResponse} event. Because
|
71
|
-
# we capture HTTP context, you still get the HTTP details, but you will not get
|
72
|
-
# all of the request details that the {Timber::Events::HTTPRequest} event would
|
73
|
-
# provide.
|
74
|
-
#
|
75
|
-
# @example
|
76
|
-
# Timber::Integrations::Rack::HTTPEvents.collapse_into_single_event = true
|
77
|
-
def collapse_into_single_event=(value)
|
78
|
-
@collapse_into_single_event = value
|
79
|
-
end
|
80
|
-
|
81
|
-
# Accessor method for {#collapse_into_single_event=}.
|
82
|
-
def collapse_into_single_event?
|
83
|
-
@collapse_into_single_event == true
|
84
|
-
end
|
85
|
-
|
86
|
-
# This setting allows you to silence requests based on any conditions you desire.
|
87
|
-
# We require a block because it gives you complete control over how you want to
|
88
|
-
# silence requests. The first parameter being the traditional Rack env hash, the
|
89
|
-
# second being a [Rack Request](http://www.rubydoc.info/gems/rack/Rack/Request) object.
|
90
|
-
#
|
91
|
-
# @example
|
92
|
-
# Integrations::Rack::HTTPEvents.silence_request = lambda do |rack_env, rack_request|
|
93
|
-
# rack_request.path == "/_health"
|
94
|
-
# end
|
95
|
-
def silence_request=(proc)
|
96
|
-
if proc && !proc.is_a?(Proc)
|
97
|
-
raise ArgumentError.new("The value passed to #silence_request must be a Proc")
|
98
|
-
end
|
99
|
-
|
100
|
-
@silence_request = proc
|
101
|
-
end
|
102
|
-
|
103
|
-
# Accessor method for {#silence_request=}
|
104
|
-
def silence_request
|
105
|
-
@silence_request
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
CONTENT_LENGTH_KEY = 'Content-Length'.freeze
|
110
|
-
|
111
|
-
def call(env)
|
112
|
-
request = Util::Request.new(env)
|
113
|
-
|
114
|
-
if silenced?(env, request)
|
115
|
-
if Config.instance.logger.respond_to?(:silence)
|
116
|
-
Config.instance.logger.silence do
|
117
|
-
@app.call(env)
|
118
|
-
end
|
119
|
-
else
|
120
|
-
@app.call(env)
|
121
|
-
end
|
122
|
-
|
123
|
-
elsif collapse_into_single_event?
|
124
|
-
start = Time.now
|
125
|
-
|
126
|
-
status, headers, body = @app.call(env)
|
127
|
-
|
128
|
-
Config.instance.logger.info do
|
129
|
-
http_context_key = Contexts::HTTP.keyspace
|
130
|
-
http_context = CurrentContext.fetch(http_context_key)
|
131
|
-
content_length = headers[CONTENT_LENGTH_KEY]
|
132
|
-
time_ms = (Time.now - start) * 1000.0
|
133
|
-
|
134
|
-
Events::HTTPResponse.new(
|
135
|
-
content_length: content_length,
|
136
|
-
headers: headers,
|
137
|
-
http_context: http_context,
|
138
|
-
request_id: request.request_id,
|
139
|
-
status: status,
|
140
|
-
time_ms: time_ms
|
141
|
-
)
|
142
|
-
end
|
143
|
-
|
144
|
-
[status, headers, body]
|
145
|
-
|
146
|
-
else
|
147
|
-
start = Time.now
|
148
|
-
|
149
|
-
Config.instance.logger.info do
|
150
|
-
event_body = capture_request_body? ? request.body_content : nil
|
151
|
-
|
152
|
-
Events::HTTPRequest.new(
|
153
|
-
body: event_body,
|
154
|
-
content_length: request.content_length,
|
155
|
-
headers: request.headers,
|
156
|
-
host: request.host,
|
157
|
-
method: request.request_method,
|
158
|
-
path: request.path,
|
159
|
-
port: request.port,
|
160
|
-
query_string: request.query_string,
|
161
|
-
request_id: request.request_id, # we insert this middleware after ActionDispatch::RequestId
|
162
|
-
scheme: request.scheme
|
163
|
-
)
|
164
|
-
end
|
165
|
-
|
166
|
-
status, headers, body = @app.call(env)
|
167
|
-
|
168
|
-
Config.instance.logger.info do
|
169
|
-
event_body = capture_response_body? ? body : nil
|
170
|
-
content_length = headers[CONTENT_LENGTH_KEY]
|
171
|
-
time_ms = (Time.now - start) * 1000.0
|
172
|
-
|
173
|
-
Events::HTTPResponse.new(
|
174
|
-
body: event_body,
|
175
|
-
content_length: content_length,
|
176
|
-
headers: headers,
|
177
|
-
request_id: request.request_id,
|
178
|
-
status: status,
|
179
|
-
time_ms: time_ms
|
180
|
-
)
|
181
|
-
end
|
182
|
-
|
183
|
-
[status, headers, body]
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
private
|
188
|
-
def capture_request_body?
|
189
|
-
self.class.capture_request_body?
|
190
|
-
end
|
191
|
-
|
192
|
-
def capture_response_body?
|
193
|
-
self.class.capture_response_body?
|
194
|
-
end
|
195
|
-
|
196
|
-
def collapse_into_single_event?
|
197
|
-
self.class.collapse_into_single_event?
|
198
|
-
end
|
199
|
-
|
200
|
-
def silenced?(env, request)
|
201
|
-
if !self.class.silence_request.nil?
|
202
|
-
self.class.silence_request.call(env, request)
|
203
|
-
else
|
204
|
-
false
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|