timber 2.6.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|