logtail-rails 0.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.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +144 -0
- data/.gitignore +23 -0
- data/.rspec +3 -0
- data/Gemfile +3 -0
- data/LICENSE.md +13 -0
- data/README.md +10 -0
- data/Rakefile +6 -0
- data/gemfiles/rails-3.0.gemfile +8 -0
- data/gemfiles/rails-3.1.gemfile +8 -0
- data/gemfiles/rails-3.2.gemfile +8 -0
- data/gemfiles/rails-4.0.gemfile +12 -0
- data/gemfiles/rails-4.1.gemfile +12 -0
- data/gemfiles/rails-4.2.gemfile +12 -0
- data/gemfiles/rails-5.0.gemfile +12 -0
- data/gemfiles/rails-5.1.gemfile +12 -0
- data/gemfiles/rails-5.2.gemfile +12 -0
- data/gemfiles/rails-6.0.gemfile +12 -0
- data/gemfiles/rails-6.1.gemfile +12 -0
- data/gemfiles/rails-edge.gemfile +10 -0
- data/lib/logtail-rails.rb +64 -0
- data/lib/logtail-rails/action_controller.rb +17 -0
- data/lib/logtail-rails/action_controller/log_subscriber.rb +25 -0
- data/lib/logtail-rails/action_controller/log_subscriber/logtail_log_subscriber.rb +46 -0
- data/lib/logtail-rails/action_dispatch.rb +20 -0
- data/lib/logtail-rails/action_dispatch/debug_exceptions.rb +51 -0
- data/lib/logtail-rails/action_view.rb +17 -0
- data/lib/logtail-rails/action_view/log_subscriber.rb +25 -0
- data/lib/logtail-rails/action_view/log_subscriber/logtail_log_subscriber.rb +84 -0
- data/lib/logtail-rails/active_record.rb +17 -0
- data/lib/logtail-rails/active_record/log_subscriber.rb +20 -0
- data/lib/logtail-rails/active_record/log_subscriber/logtail_log_subscriber.rb +52 -0
- data/lib/logtail-rails/active_support_log_subscriber.rb +39 -0
- data/lib/logtail-rails/config.rb +12 -0
- data/lib/logtail-rails/config/action_controller.rb +29 -0
- data/lib/logtail-rails/config/action_view.rb +29 -0
- data/lib/logtail-rails/config/active_record.rb +29 -0
- data/lib/logtail-rails/error_event.rb +62 -0
- data/lib/logtail-rails/logger.rb +20 -0
- data/lib/logtail-rails/overrides.rb +12 -0
- data/lib/logtail-rails/overrides/active_support_3_tagged_logging.rb +111 -0
- data/lib/logtail-rails/overrides/active_support_buffered_logger.rb +22 -0
- data/lib/logtail-rails/overrides/active_support_tagged_logging.rb +66 -0
- data/lib/logtail-rails/overrides/lograge.rb +18 -0
- data/lib/logtail-rails/overrides/rails_stdout_logging.rb +20 -0
- data/lib/logtail-rails/rack_logger.rb +59 -0
- data/lib/logtail-rails/railtie.rb +27 -0
- data/lib/logtail-rails/session_context.rb +37 -0
- data/lib/logtail-rails/version.rb +7 -0
- data/logtail-rails.gemspec +60 -0
- metadata +263 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
require "logtail-rails/action_controller"
|
2
|
+
|
3
|
+
module Logtail
|
4
|
+
class Config
|
5
|
+
# Convenience module for accessing the various `Logtail::Integrations::*` classes
|
6
|
+
# through the {Logtail::Config} object. Logtail couples configuration with the class
|
7
|
+
# responsible for implementing it. This provides for a tighter design, but also
|
8
|
+
# requires the user to understand and access the various classes. This module aims
|
9
|
+
# to provide a simple ruby-like configuration interface for internal Logtail classes.
|
10
|
+
#
|
11
|
+
# For example:
|
12
|
+
#
|
13
|
+
# config = Logtail::Config.instance
|
14
|
+
# config.integrations.active_record.silence = true
|
15
|
+
module Integrations
|
16
|
+
extend self
|
17
|
+
|
18
|
+
# Convenience method for accessing the {Logtail::Integrations::ActionController} class
|
19
|
+
# specific configuration.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# config = Logtail::Config.instance
|
23
|
+
# config.integrations.action_controller.silence = true
|
24
|
+
def action_controller
|
25
|
+
Logtail::Integrations::ActionController
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "logtail-rails/action_view"
|
2
|
+
|
3
|
+
module Logtail
|
4
|
+
class Config
|
5
|
+
# Convenience module for accessing the various `Logtail::Integrations::*` classes
|
6
|
+
# through the {Logtail::Config} object. Logtail couples configuration with the class
|
7
|
+
# responsible for implementing it. This provides for a tighter design, but also
|
8
|
+
# requires the user to understand and access the various classes. This module aims
|
9
|
+
# to provide a simple ruby-like configuration interface for internal Logtail classes.
|
10
|
+
#
|
11
|
+
# For example:
|
12
|
+
#
|
13
|
+
# config = Logtail::Config.instance
|
14
|
+
# config.integrations.active_record.silence = true
|
15
|
+
module Integrations
|
16
|
+
extend self
|
17
|
+
|
18
|
+
# Convenience method for accessing the {Logtail::Integrations::ActionView} class
|
19
|
+
# specific configuration.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# config = Logtail::Config.instance
|
23
|
+
# config.integrations.action_view.silence = true
|
24
|
+
def action_view
|
25
|
+
Logtail::Integrations::ActionView
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "logtail-rails/active_record"
|
2
|
+
|
3
|
+
module Logtail
|
4
|
+
class Config
|
5
|
+
# Convenience module for accessing the various `Logtail::Integrations::*` classes
|
6
|
+
# through the {Logtail::Config} object. Logtail couples configuration with the class
|
7
|
+
# responsible for implementing it. This provides for a tighter design, but also
|
8
|
+
# requires the user to understand and access the various classes. This module aims
|
9
|
+
# to provide a simple ruby-like configuration interface for internal Logtail classes.
|
10
|
+
#
|
11
|
+
# For example:
|
12
|
+
#
|
13
|
+
# config = Logtail::Config.instance
|
14
|
+
# config.integrations.active_record.silence = true
|
15
|
+
module Integrations
|
16
|
+
extend self
|
17
|
+
|
18
|
+
# Convenience method for accessing the {Logtail::Integrations::ActiveRecord} class
|
19
|
+
# specific configuration.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# config = Logtail::Config.instance
|
23
|
+
# config.integrations.active_record.silence = true
|
24
|
+
def active_record
|
25
|
+
Logtail::Integrations::ActiveRecord
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
begin
|
2
|
+
# Rails 3.2 requires you to require all of Rails before requiring
|
3
|
+
# the exception wrapper.
|
4
|
+
require "action_dispatch/middleware/exception_wrapper"
|
5
|
+
rescue Exception
|
6
|
+
end
|
7
|
+
|
8
|
+
require "logtail/events/error"
|
9
|
+
require "logtail-rack/middleware"
|
10
|
+
require "logtail/util"
|
11
|
+
|
12
|
+
module Logtail
|
13
|
+
module Integrations
|
14
|
+
module Rails
|
15
|
+
# A Rack middleware that is responsible for capturing exception and error events
|
16
|
+
# {Logtail::Events::Error}.
|
17
|
+
class ErrorEvent < Logtail::Integrations::Rack::Middleware
|
18
|
+
# We determine this when the app loads to avoid the overhead on a per request basis.
|
19
|
+
EXCEPTION_WRAPPER_TAKES_CLEANER = defined?(::ActionDispatch::ExceptionWrapper) &&
|
20
|
+
!::ActionDispatch::ExceptionWrapper.instance_methods.include?(:env)
|
21
|
+
|
22
|
+
def call(env)
|
23
|
+
begin
|
24
|
+
status, headers, body = @app.call(env)
|
25
|
+
rescue Exception => exception
|
26
|
+
Config.instance.logger.fatal do
|
27
|
+
backtrace = extract_backtrace(env, exception)
|
28
|
+
Events::Error.new(
|
29
|
+
name: exception.class.name,
|
30
|
+
error_message: exception.message,
|
31
|
+
backtrace: backtrace
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
raise exception
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Rails provides a backtrace cleaner, so we use it here.
|
42
|
+
def extract_backtrace(env, exception)
|
43
|
+
if defined?(::ActionDispatch::ExceptionWrapper)
|
44
|
+
wrapper = if EXCEPTION_WRAPPER_TAKES_CLEANER
|
45
|
+
request = Util::Request.new(env)
|
46
|
+
backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
|
47
|
+
::ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception)
|
48
|
+
else
|
49
|
+
::ActionDispatch::ExceptionWrapper.new(env, exception)
|
50
|
+
end
|
51
|
+
|
52
|
+
trace = wrapper.application_trace
|
53
|
+
trace = wrapper.framework_trace if trace.empty?
|
54
|
+
trace
|
55
|
+
else
|
56
|
+
exception.backtrace
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Logtail
|
2
|
+
# The Logtail Logger behaves exactly like the standard Ruby `::Logger`, except that it supports a
|
3
|
+
# transparent API for logging structured data and events.
|
4
|
+
#
|
5
|
+
# @example Basic logging
|
6
|
+
# logger.info "Payment rejected for customer #{customer_id}"
|
7
|
+
#
|
8
|
+
# @example Logging an event
|
9
|
+
# logger.info "Payment rejected", payment_rejected: {customer_id: customer_id, amount: 100}
|
10
|
+
class Logger < ::Logger
|
11
|
+
include ::ActiveSupport::LoggerThreadSafeLevel if defined?(::ActiveSupport::LoggerThreadSafeLevel)
|
12
|
+
|
13
|
+
if defined?(::ActiveSupport::LoggerSilence)
|
14
|
+
include ::ActiveSupport::LoggerSilence
|
15
|
+
elsif defined?(::LoggerSilence)
|
16
|
+
include ::LoggerSilence
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# The order is relevant
|
2
|
+
require "logtail-rails/overrides/active_support_3_tagged_logging"
|
3
|
+
require "logtail-rails/overrides/active_support_tagged_logging"
|
4
|
+
require "logtail-rails/overrides/active_support_buffered_logger"
|
5
|
+
require "logtail-rails/overrides/lograge"
|
6
|
+
require "logtail-rails/overrides/rails_stdout_logging"
|
7
|
+
|
8
|
+
module Logtail
|
9
|
+
# @private
|
10
|
+
module Overrides
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# Please note, this patch is merely an upgrade, backporting improved tagged logging code
|
2
|
+
# from newer versions of Rails:
|
3
|
+
# https://github.com/rails/rails/blob/5-1-stable/activesupport/lib/active_support/tagged_logging.rb
|
4
|
+
# The behavior of tagged logging will not change in any way.
|
5
|
+
#
|
6
|
+
# This patch is specifically for Rails 3. The legacy approach to wrapping the logger in
|
7
|
+
# ActiveSupport::TaggedLogging is rather poor, hence the reason it was changed entirely
|
8
|
+
# for Rails 4 and 5. The problem is that ActiveSupport::TaggedLogging is a wrapping
|
9
|
+
# class that entirely redefines the public API for the logger. As a result, any deviations
|
10
|
+
# from this API in the logger are not exposed (such as accepting event data as a second argument).
|
11
|
+
# This is assuming, so we're fixing it here.
|
12
|
+
|
13
|
+
begin
|
14
|
+
require "active_support/tagged_logging"
|
15
|
+
|
16
|
+
# Instead of patching the class we're pulling the code from Rails master. This brings in
|
17
|
+
# a number of improvements while also addressing the issue above.
|
18
|
+
if ActiveSupport::TaggedLogging.instance_of?(Class)
|
19
|
+
ActiveSupport.send(:remove_const, :TaggedLogging)
|
20
|
+
|
21
|
+
require "active_support/core_ext/module/delegation"
|
22
|
+
require "active_support/core_ext/object/blank"
|
23
|
+
require "logger"
|
24
|
+
|
25
|
+
module ActiveSupport
|
26
|
+
# Wraps any standard Logger object to provide tagging capabilities.
|
27
|
+
#
|
28
|
+
# logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
|
29
|
+
# logger.tagged('BCX') { logger.info 'Stuff' } # Logs "[BCX] Stuff"
|
30
|
+
# logger.tagged('BCX', "Jason") { logger.info 'Stuff' } # Logs "[BCX] [Jason] Stuff"
|
31
|
+
# logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff"
|
32
|
+
#
|
33
|
+
# This is used by the default Rails.logger as configured by Railties to make
|
34
|
+
# it easy to stamp log lines with subdomains, request ids, and anything else
|
35
|
+
# to aid debugging of multi-user production applications.
|
36
|
+
module TaggedLogging
|
37
|
+
module Formatter # :nodoc:
|
38
|
+
# This method is invoked when a log event occurs.
|
39
|
+
def call(severity, timestamp, progname, msg)
|
40
|
+
super(severity, timestamp, progname, "#{tags_text}#{msg}")
|
41
|
+
end
|
42
|
+
|
43
|
+
def tagged(*tags)
|
44
|
+
new_tags = push_tags(*tags)
|
45
|
+
yield self
|
46
|
+
ensure
|
47
|
+
pop_tags(new_tags.size)
|
48
|
+
end
|
49
|
+
|
50
|
+
def push_tags(*tags)
|
51
|
+
tags.flatten.reject(&:blank?).tap do |new_tags|
|
52
|
+
current_tags.concat new_tags
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def pop_tags(size = 1)
|
57
|
+
current_tags.pop size
|
58
|
+
end
|
59
|
+
|
60
|
+
def clear_tags!
|
61
|
+
current_tags.clear
|
62
|
+
end
|
63
|
+
|
64
|
+
def current_tags
|
65
|
+
# We use our object ID here to avoid conflicting with other instances
|
66
|
+
thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}".freeze
|
67
|
+
Thread.current[thread_key] ||= []
|
68
|
+
end
|
69
|
+
|
70
|
+
def tags_text
|
71
|
+
tags = current_tags
|
72
|
+
if tags.any?
|
73
|
+
tags.collect { |tag| "[#{tag}] " }.join
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Simple formatter which only displays the message.
|
79
|
+
class SimpleFormatter < ::Logger::Formatter
|
80
|
+
# This method is invoked when a log event occurs
|
81
|
+
def call(severity, timestamp, progname, msg)
|
82
|
+
"#{String === msg ? msg : msg.inspect}\n"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.new(logger)
|
87
|
+
if logger.respond_to?(:formatter=) && logger.respond_to?(:formatter)
|
88
|
+
# Ensure we set a default formatter so we aren't extending nil!
|
89
|
+
logger.formatter ||= SimpleFormatter.new
|
90
|
+
logger.formatter.extend Formatter
|
91
|
+
end
|
92
|
+
|
93
|
+
logger.extend(self)
|
94
|
+
end
|
95
|
+
|
96
|
+
delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter
|
97
|
+
|
98
|
+
def tagged(*tags)
|
99
|
+
formatter.tagged(*tags) { yield self }
|
100
|
+
end
|
101
|
+
|
102
|
+
def flush
|
103
|
+
clear_tags!
|
104
|
+
super if defined?(super)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
rescue Exception
|
111
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# This adds a #formatter and #formatter= method to the legacy ActiveSupport::BufferedLogger
|
2
|
+
# class. This bug was never resolved due to it being phased out past Rails >= 4.
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "active_support/buffered_logger"
|
6
|
+
|
7
|
+
class ActiveSupport::BufferedLogger
|
8
|
+
def formatter
|
9
|
+
if @log.respond_to?(:formatter)
|
10
|
+
@log.formatter
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def formatter=(value)
|
15
|
+
if @log.respond_to?(:formatter=)
|
16
|
+
@log.formatter = value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
rescue Exception
|
22
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# This is an override instead of an integration because without this Logtail would not
|
2
|
+
# work properly if ActiveSupport::TaggedLogging is used.
|
3
|
+
#
|
4
|
+
# This is called after 'active_support_3_tagged_logging' where the constant is loaded and
|
5
|
+
# replaced. I want to make sure we don't attempt to load it again undoing the patches
|
6
|
+
# applied there.
|
7
|
+
if defined?(ActiveSupport::TaggedLogging)
|
8
|
+
module Logtail
|
9
|
+
module Overrides
|
10
|
+
# @private
|
11
|
+
module ActiveSupportTaggedLogging
|
12
|
+
# @private
|
13
|
+
module FormatterMethods
|
14
|
+
def self.included(mod)
|
15
|
+
mod.module_eval do
|
16
|
+
alias_method :_logtail_original_push_tags, :push_tags
|
17
|
+
alias_method :_logtail_original_pop_tags, :pop_tags
|
18
|
+
|
19
|
+
def call(severity, timestamp, progname, msg)
|
20
|
+
if is_a?(Logtail::Logger::Formatter)
|
21
|
+
# Don't convert the message into a string
|
22
|
+
super(severity, timestamp, progname, msg)
|
23
|
+
else
|
24
|
+
super(severity, timestamp, progname, "#{tags_text}#{msg}")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @private
|
32
|
+
module LoggerMethods
|
33
|
+
def self.included(klass)
|
34
|
+
klass.class_eval do
|
35
|
+
def add(severity, message = nil, progname = nil, &block)
|
36
|
+
if message.nil?
|
37
|
+
if block_given?
|
38
|
+
message = block.call
|
39
|
+
else
|
40
|
+
message = progname
|
41
|
+
progname = nil #No instance variable for this like Logger
|
42
|
+
end
|
43
|
+
end
|
44
|
+
if @logger.is_a?(Logtail::Logger)
|
45
|
+
@logger.add(severity, message, progname)
|
46
|
+
else
|
47
|
+
@logger.add(severity, "#{tags_text}#{message}", progname)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if defined?(::ActiveSupport::TaggedLogging::Formatter)
|
55
|
+
if !::ActiveSupport::TaggedLogging::Formatter.include?(FormatterMethods)
|
56
|
+
::ActiveSupport::TaggedLogging::Formatter.send(:include, FormatterMethods)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
if !::ActiveSupport::TaggedLogging.include?(LoggerMethods)
|
60
|
+
::ActiveSupport::TaggedLogging.send(:include, LoggerMethods)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Logtail and lograge are not compatible installed together. Using lograge
|
2
|
+
# with the Logtail.com *service* is perfectly fine, but not with the Logtail *gem*.
|
3
|
+
#
|
4
|
+
# Logtail does ship with a {Logtail::Config#logrageify!} option that configures
|
5
|
+
# Logtail to behave similarly to Lograge (silencing various logs). Check out
|
6
|
+
# the aforementioned method or the README for info.
|
7
|
+
begin
|
8
|
+
require "lograge"
|
9
|
+
|
10
|
+
module Lograge
|
11
|
+
module_function
|
12
|
+
|
13
|
+
def setup(app)
|
14
|
+
return true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
rescue Exception
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# See https://github.com/heroku/rails_stdout_logging
|
2
|
+
# I have no idea why this library was created, but most Heroku / Rails apps use it.
|
3
|
+
# This library completely obliterates any logger configuration you set.
|
4
|
+
# So this patch fixes that.
|
5
|
+
|
6
|
+
begin
|
7
|
+
require "rails_stdout_logging"
|
8
|
+
|
9
|
+
module RailsStdoutLogging
|
10
|
+
class Rails2 < Rails
|
11
|
+
def self.set_logger
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Rails3 < Rails
|
16
|
+
def self.set_logger(config) end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
rescue Exception
|
20
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Logtail
|
2
|
+
module Integrations
|
3
|
+
module Rails
|
4
|
+
# Disables the default rail's rack logging. Note, we cannot simply uninstall this rack
|
5
|
+
# middleware because rails couples this with ActiveSupport instrumentation. As such,
|
6
|
+
# we simply disable the logger and let our Rack middleware handle the logging.
|
7
|
+
#
|
8
|
+
# See: https://github.com/rails/rails/blob/80e66cc4d90bf8c15d1a5f6e3152e90147f00772/railties/lib/rails/rack/logger.rb#L34
|
9
|
+
#
|
10
|
+
# @private
|
11
|
+
class RackLogger < Integrator
|
12
|
+
|
13
|
+
# @private
|
14
|
+
module InstanceMethods
|
15
|
+
LOGGER = ::Logger.new(nil)
|
16
|
+
|
17
|
+
def self.included(klass)
|
18
|
+
klass.class_eval do
|
19
|
+
private
|
20
|
+
|
21
|
+
if ::Rails::VERSION::MAJOR == 3
|
22
|
+
# Rails 3.2 calls Rails.logger directly in call_app, so we
|
23
|
+
# will just replace it with a version that doesn't
|
24
|
+
def call_app(_, env)
|
25
|
+
# Put some space between requests in development logs.
|
26
|
+
if ::Rails.env.development?
|
27
|
+
::Rails.logger.info ''
|
28
|
+
::Rails.logger.info ''
|
29
|
+
end
|
30
|
+
@app.call(env)
|
31
|
+
ensure
|
32
|
+
ActiveSupport::LogSubscriber.flush_all!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Rails > 3.2 uses a logger method. Muting logs is accomplished by
|
37
|
+
# passing a dummy logger instance with a nil log device.
|
38
|
+
def logger
|
39
|
+
LOGGER
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
require "rails/rack/logger"
|
47
|
+
rescue LoadError => e
|
48
|
+
raise RequirementNotMetError.new(e.message)
|
49
|
+
end
|
50
|
+
|
51
|
+
def integrate!
|
52
|
+
return true if ::Rails::Rack::Logger.include?(InstanceMethods)
|
53
|
+
|
54
|
+
::Rails::Rack::Logger.send(:include, InstanceMethods)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|