timber 1.1.14 → 2.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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -2
  3. data/.travis.yml +47 -0
  4. data/Gemfile +1 -28
  5. data/README.md +83 -298
  6. data/bin/timber +13 -0
  7. data/gemfiles/rails-3.0.gemfile +5 -0
  8. data/gemfiles/rails-3.1.gemfile +5 -0
  9. data/gemfiles/rails-3.2.gemfile +5 -0
  10. data/gemfiles/rails-4.0.gemfile +9 -0
  11. data/gemfiles/rails-4.1.gemfile +9 -0
  12. data/gemfiles/rails-4.2.gemfile +9 -0
  13. data/gemfiles/rails-5.0.gemfile +9 -0
  14. data/gemfiles/rails-edge.gemfile +7 -0
  15. data/lib/timber.rb +7 -7
  16. data/lib/timber/cli.rb +72 -0
  17. data/lib/timber/cli/api.rb +104 -0
  18. data/lib/timber/cli/application.rb +28 -0
  19. data/lib/timber/cli/install.rb +186 -0
  20. data/lib/timber/cli/io_helper.rb +58 -0
  21. data/lib/timber/cli/messages.rb +170 -0
  22. data/lib/timber/config.rb +47 -6
  23. data/lib/timber/contexts/http.rb +2 -2
  24. data/lib/timber/current_context.rb +1 -1
  25. data/lib/timber/event.rb +8 -0
  26. data/lib/timber/events.rb +2 -0
  27. data/lib/timber/events/controller_call.rb +12 -3
  28. data/lib/timber/events/exception.rb +4 -3
  29. data/lib/timber/events/http_client_request.rb +61 -0
  30. data/lib/timber/events/http_client_response.rb +47 -0
  31. data/lib/timber/events/http_server_request.rb +15 -23
  32. data/lib/timber/events/http_server_response.rb +9 -9
  33. data/lib/timber/events/sql_query.rb +2 -2
  34. data/lib/timber/events/template_render.rb +2 -2
  35. data/lib/timber/frameworks/rails.rb +31 -6
  36. data/lib/timber/integrations.rb +22 -0
  37. data/lib/timber/integrations/action_controller/log_subscriber.rb +25 -0
  38. data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +40 -0
  39. data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +51 -0
  40. data/lib/timber/integrations/action_view/log_subscriber.rb +25 -0
  41. data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +73 -0
  42. data/lib/timber/integrations/active_record/log_subscriber.rb +25 -0
  43. data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +39 -0
  44. data/lib/timber/integrations/active_support/tagged_logging.rb +71 -0
  45. data/lib/timber/integrations/rack.rb +16 -0
  46. data/lib/timber/integrations/rack/exception_event.rb +28 -0
  47. data/lib/timber/integrations/rack/http_context.rb +25 -0
  48. data/lib/timber/integrations/rack/http_events.rb +46 -0
  49. data/lib/timber/integrations/rack/user_context.rb +59 -0
  50. data/lib/timber/integrations/rails/rack_logger.rb +49 -0
  51. data/lib/timber/integrator.rb +24 -0
  52. data/lib/timber/log_devices/http.rb +14 -21
  53. data/lib/timber/log_entry.rb +1 -1
  54. data/lib/timber/logger.rb +38 -12
  55. data/lib/timber/overrides.rb +9 -0
  56. data/lib/timber/overrides/lograge.rb +14 -0
  57. data/lib/timber/overrides/rails_server.rb +10 -0
  58. data/lib/timber/util.rb +2 -0
  59. data/lib/timber/util/active_support_log_subscriber.rb +13 -9
  60. data/lib/timber/util/http_event.rb +54 -0
  61. data/lib/timber/util/request.rb +44 -0
  62. data/lib/timber/version.rb +1 -1
  63. data/spec/README.md +5 -9
  64. data/spec/spec_helper.rb +1 -4
  65. data/spec/support/action_controller.rb +7 -3
  66. data/spec/support/active_record.rb +23 -19
  67. data/spec/support/rails.rb +56 -32
  68. data/spec/support/timber.rb +2 -3
  69. data/spec/support/webmock.rb +1 -0
  70. data/spec/timber/integrations/action_controller/log_subscriber_spec.rb +55 -0
  71. data/spec/timber/integrations/action_dispatch/debug_exceptions_spec.rb +53 -0
  72. data/spec/timber/integrations/action_view/log_subscriber_spec.rb +115 -0
  73. data/spec/timber/integrations/active_record/log_subscriber_spec.rb +46 -0
  74. data/spec/timber/integrations/rack/http_context_spec.rb +60 -0
  75. data/spec/timber/integrations/rails/rack_logger_spec.rb +58 -0
  76. data/spec/timber/logger_spec.rb +45 -9
  77. data/timber.gemspec +29 -3
  78. metadata +143 -46
  79. data/Appraisals +0 -41
  80. data/circle.yml +0 -33
  81. data/lib/timber/overrides/logger_add.rb +0 -38
  82. data/lib/timber/probe.rb +0 -23
  83. data/lib/timber/probes.rb +0 -23
  84. data/lib/timber/probes/action_controller_log_subscriber.rb +0 -20
  85. data/lib/timber/probes/action_controller_log_subscriber/log_subscriber.rb +0 -64
  86. data/lib/timber/probes/action_controller_user_context.rb +0 -52
  87. data/lib/timber/probes/action_dispatch_debug_exceptions.rb +0 -80
  88. data/lib/timber/probes/action_view_log_subscriber.rb +0 -20
  89. data/lib/timber/probes/action_view_log_subscriber/log_subscriber.rb +0 -69
  90. data/lib/timber/probes/active_record_log_subscriber.rb +0 -20
  91. data/lib/timber/probes/active_record_log_subscriber/log_subscriber.rb +0 -31
  92. data/lib/timber/probes/active_support_tagged_logging.rb +0 -63
  93. data/lib/timber/probes/rails_rack_logger.rb +0 -77
  94. data/lib/timber/rack_middlewares.rb +0 -12
  95. data/lib/timber/rack_middlewares/http_context.rb +0 -30
  96. data/spec/support/action_view.rb +0 -4
  97. data/spec/support/coveralls.rb +0 -2
  98. data/spec/support/simplecov.rb +0 -9
  99. data/spec/timber/overrides/logger_add_spec.rb +0 -26
  100. data/spec/timber/probes/action_controller_log_subscriber_spec.rb +0 -65
  101. data/spec/timber/probes/action_controller_user_context_spec.rb +0 -53
  102. data/spec/timber/probes/action_dispatch_debug_exceptions_spec.rb +0 -48
  103. data/spec/timber/probes/action_view_log_subscriber_spec.rb +0 -107
  104. data/spec/timber/probes/active_record_log_subscriber_spec.rb +0 -47
  105. data/spec/timber/probes/rails_rack_logger_spec.rb +0 -46
  106. data/spec/timber/rack_middlewares/http_context_spec.rb +0 -47
@@ -0,0 +1,47 @@
1
+ module Timber
2
+ module Events
3
+ # The HTTP client response event tracks responses for *outgoing* HTTP *requests*.
4
+ # This gives you structured insight into communication with external services.
5
+ #
6
+ # @note This event should be installed automatically through integrations,
7
+ # such as the {Integrations::NetHTTP} integration.
8
+ class HTTPClientResponse < Timber::Event
9
+ attr_reader :body, :headers, :request_id, :service_name, :status, :time_ms
10
+
11
+ def initialize(attributes)
12
+ @headers = Util::HTTPEvent.normalize_headers(attributes[:headers])
13
+ @request_id = attributes[:request_id]
14
+ @service_name = attributes[:service_name]
15
+ @status = attributes[:status] || raise(ArgumentError.new(":status is required"))
16
+ @time_ms = attributes[:time_ms] || raise(ArgumentError.new(":time_ms is required"))
17
+ @time_ms = @time_ms.round(6)
18
+
19
+ @body = Util::HTTPEvent.normalize_body(@headers["content-type"], attributes[:body])
20
+ end
21
+
22
+ def to_hash
23
+ {body: body, headers: headers, request_id: request_id, service_name: service_name,
24
+ status: status, time_ms: time_ms}
25
+ end
26
+ alias to_h to_hash
27
+
28
+ def as_json(_options = {})
29
+ {:server_side_app => {:http_client_response => to_hash}}
30
+ end
31
+
32
+ def message
33
+ message = "Outgoing HTTP response"
34
+
35
+ if service_name
36
+ message << " from #{service_name}"
37
+ end
38
+
39
+ message << " #{status_description} in #{time_ms}ms"
40
+ end
41
+
42
+ def status_description
43
+ Rack::Utils::HTTP_STATUS_CODES[status]
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,31 +1,30 @@
1
1
  module Timber
2
2
  module Events
3
- # The HTTP request event tracks incoming HTTP requests.
3
+ # The HTTP server request event tracks incoming HTTP requests to your HTTP server.
4
+ # Such as unicorn, webrick, puma, etc.
4
5
  #
5
- # @note This event should be installed automatically through probes,
6
- # such as the {Probes::ActionControllerLogSubscriber} probe.
6
+ # @note This event should be installed automatically through integrations,
7
+ # such as the {Integrations::ActionController::LogSubscriber} integration.
7
8
  class HTTPServerRequest < Timber::Event
8
- attr_reader :host, :method, :path, :port, :query_string, :content_type,
9
- :remote_addr, :referrer, :request_id, :scheme, :user_agent
9
+ attr_reader :body, :headers, :host, :method, :path, :port, :query_string, :request_id,
10
+ :scheme
10
11
 
11
12
  def initialize(attributes)
13
+ @headers = Util::HTTPEvent.normalize_headers(attributes[:headers])
12
14
  @host = attributes[:host] || raise(ArgumentError.new(":host is required"))
13
- @method = attributes[:method] || raise(ArgumentError.new(":method is required"))
15
+ @method = Util::HTTPEvent.normalize_method(attributes[:method]) || raise(ArgumentError.new(":method is required"))
14
16
  @path = attributes[:path] || raise(ArgumentError.new(":path is required"))
15
17
  @port = attributes[:port]
16
- @query_string = attributes[:query_string]
17
- @content_type = attributes[:content_type]
18
- @remote_addr = attributes[:remote_addr]
19
- @referrer = attributes[:referrer]
20
- @request_id = attributes[:request_id]
18
+ @query_string = Util::HTTPEvent.normalize_query_string(attributes[:query_string])
21
19
  @scheme = attributes[:scheme] || raise(ArgumentError.new(":scheme is required"))
22
- @user_agent = attributes[:user_agent]
20
+ @request_id = attributes[:request_id]
21
+
22
+ @body = Util::HTTPEvent.normalize_body(@headers["content-type"], attributes[:body])
23
23
  end
24
24
 
25
25
  def to_hash
26
- {host: host, method: method, path: path, port: port, query_string: query_string,
27
- headers: {content_type: content_type, remote_addr: remote_addr, referrer: referrer,
28
- request_id: request_id, scheme: scheme, user_agent: user_agent}}
26
+ {body: body, headers: headers, host: host, method: method, path: path, port: port,
27
+ query_string: query_string, request_id: request_id, scheme: scheme}
29
28
  end
30
29
  alias to_h to_hash
31
30
 
@@ -34,14 +33,7 @@ module Timber
34
33
  end
35
34
 
36
35
  def message
37
- 'Started %s "%s" for %s' % [
38
- method,
39
- path,
40
- remote_addr]
41
- end
42
-
43
- def status_description
44
- Rack::Utils::HTTP_STATUS_CODES[status]
36
+ 'Started %s "%s"' % [method, path]
45
37
  end
46
38
  end
47
39
  end
@@ -1,21 +1,23 @@
1
1
  module Timber
2
2
  module Events
3
- # The HTTP response event tracks outgoing HTTP request responses.
3
+ # The HTTP server response event tracks outgoing HTTP responses that you send
4
+ # to clients.
4
5
  #
5
- # @note This event should be installed automatically through probes,
6
- # such as the {Probes::ActionControllerLogSubscriber} probe.
6
+ # @note This event should be installed automatically through integrations,
7
+ # such as the {Integrations::ActionController::LogSubscriber} integration.
7
8
  class HTTPServerResponse < Timber::Event
8
- attr_reader :status, :time_ms, :additions
9
+ attr_reader :headers, :request_id, :status, :time_ms
9
10
 
10
11
  def initialize(attributes)
12
+ @headers = Util::HTTPEvent.normalize_headers(attributes[:headers])
13
+ @request_id = attributes[:request_id]
11
14
  @status = attributes[:status] || raise(ArgumentError.new(":status is required"))
12
15
  @time_ms = attributes[:time_ms] || raise(ArgumentError.new(":time_ms is required"))
13
16
  @time_ms = @time_ms.round(6)
14
- @additions = attributes[:additions]
15
17
  end
16
18
 
17
19
  def to_hash
18
- {status: status, time_ms: time_ms}
20
+ {headers: headers, request_id: request_id, status: status, time_ms: time_ms}
19
21
  end
20
22
  alias to_h to_hash
21
23
 
@@ -24,9 +26,7 @@ module Timber
24
26
  end
25
27
 
26
28
  def message
27
- message = "Completed #{status} #{status_description} in #{time_ms}ms"
28
- message << " (#{additions.join(" | ".freeze)})" unless additions.empty?
29
- message
29
+ "Completed #{status} #{status_description} in #{time_ms}ms"
30
30
  end
31
31
 
32
32
  def status_description
@@ -2,8 +2,8 @@ module Timber
2
2
  module Events
3
3
  # The SQL query event tracks sql queries to your database.
4
4
  #
5
- # @note This event should be installed automatically through probes,
6
- # such as the {Probes::ActiveRecordLogSubscriber} probe.
5
+ # @note This event should be installed automatically through integrations,
6
+ # such as the {Integrations::ActiveRecord::LogSubscriber} integration.
7
7
  class SQLQuery < Timber::Event
8
8
  attr_reader :sql, :time_ms, :message
9
9
 
@@ -2,8 +2,8 @@ module Timber
2
2
  module Events
3
3
  # The template render event track template renderings and their performance.
4
4
  #
5
- # @note This event should be installed automatically through probes,
6
- # such as the {Probes::ActionViewLogSubscriber} probe.
5
+ # @note This event should be installed automatically through integrations,
6
+ # such as the {Integrations::ActionView::LogSubscriber} integration.
7
7
  class TemplateRender < Timber::Event
8
8
  attr_reader :message, :name, :time_ms
9
9
 
@@ -4,19 +4,44 @@ module Timber
4
4
  # Installs Timber into your Rails app automatically.
5
5
  class Railtie < ::Rails::Railtie
6
6
  config.timber = Config.instance
7
- config.before_initialize do
8
- Probes.insert!
9
- Timber::Frameworks::Rails.insert_middlewares(config.app_middleware)
7
+
8
+ initializer(:timber_logger, before: :initialize_logger) do
9
+ Rails.configure_middlewares(config.app_middleware)
10
+ Integrations.integrate!
11
+
12
+ # We set a default logger because Rails tries to write to a file by default.
13
+ # This causes errors on paltforms with a readon only file system (Heroku)
14
+ # Moreover, the Timber logger gets configured properly later in an initiailizer.
15
+ # This is a hold over until we reach that file in the initialization process.
16
+ logger = if defined?(::ActiveSupport::Logger)
17
+ ::ActiveSupport::Logger.new(STDOUT)
18
+ else
19
+ ::Logger.new(STDOUT)
20
+ end
21
+ ::Rails.logger = Config.instance.logger = logger
10
22
  end
11
23
  end
12
24
 
13
- def self.insert_middlewares(middleware)
25
+ def self.set_logger(logger)
26
+ if defined?(::ActiveSupport::TaggedLogging) && !logger.is_a?(::ActiveSupport::TaggedLogging)
27
+ logger = ::ActiveSupport::TaggedLogging.new(logger)
28
+ end
29
+
30
+ Config.instance.logger = logger
31
+ ::ActionController::Base.logger = logger
32
+ ::ActionView::Base.logger = logger if ::ActionView::Base.respond_to?(:logger=)
33
+ ::ActiveRecord::Base.logger = logger
34
+ ::Rails.logger = logger
35
+ end
36
+
37
+ def self.configure_middlewares(middleware)
14
38
  var_name = :"@_timber_middlewares_inserted"
15
39
  return true if middleware.instance_variable_defined?(var_name) && middleware.instance_variable_get(var_name) == true
40
+
16
41
  # Rails uses a proxy :/, so we need to do this instance variable hack
17
42
  middleware.instance_variable_set(var_name, true)
18
- Timber::RackMiddlewares.middlewares.each do |m|
19
- middleware.insert_before ::Rails::Rack::Logger, m
43
+ Integrations::Rack.middlewares.each do |middleware_class|
44
+ middleware.use middleware_class
20
45
  end
21
46
  end
22
47
  end
@@ -0,0 +1,22 @@
1
+ require "timber/integrations/action_controller/log_subscriber"
2
+ require "timber/integrations/action_dispatch/debug_exceptions"
3
+ require "timber/integrations/action_view/log_subscriber"
4
+ require "timber/integrations/active_record/log_subscriber"
5
+ require "timber/integrations/active_support/tagged_logging"
6
+ require "timber/integrations/rack"
7
+ require "timber/integrations/rails/rack_logger"
8
+
9
+ module Timber
10
+ # Namespace for all integrations.
11
+ # @private
12
+ module Integrations
13
+ def self.integrate!
14
+ ActionController::LogSubscriber.integrate!
15
+ ActionDispatch::DebugExceptions.integrate!
16
+ ActionView::LogSubscriber.integrate!
17
+ ActiveRecord::LogSubscriber.integrate!
18
+ ActiveSupport::TaggedLogging.integrate!
19
+ Rails::RackLogger.integrate!
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ module Timber
2
+ module Integrations
3
+ module ActionController
4
+ # Responsible for removing the default ActionController::LogSubscriber and installing
5
+ # the TimberLogSubscriber
6
+ #
7
+ # @private
8
+ class LogSubscriber < Integrator
9
+ def initialize
10
+ require "action_controller/log_subscriber"
11
+ require "timber/integrations/action_controller/log_subscriber/timber_log_subscriber"
12
+ rescue LoadError => e
13
+ raise RequirementNotMetError.new(e.message)
14
+ end
15
+
16
+ def integrate!
17
+ return true if Util::ActiveSupportLogSubscriber.subscribed?(:action_controller, TimberLogSubscriber)
18
+
19
+ Util::ActiveSupportLogSubscriber.unsubscribe!(:action_controller, ::ActionController::LogSubscriber)
20
+ TimberLogSubscriber.attach_to(:action_controller)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,40 @@
1
+ module Timber
2
+ module Integrations
3
+ module ActionController
4
+ class LogSubscriber < Integrator
5
+ # The log subscriber that replaces the default `ActionController::LogSubscriber`.
6
+ # The intent of this subscriber is to, as transparently as possible, properly
7
+ # track events that are being logged here. This LogSubscriber will never change
8
+ # default behavior / log messages.
9
+ #
10
+ # @private
11
+ class TimberLogSubscriber < ::ActionController::LogSubscriber
12
+ def start_processing(event)
13
+ info do
14
+ payload = event.payload
15
+ params = payload[:params].except(*INTERNAL_PARAMS)
16
+ format = extract_format(payload)
17
+ format = format.to_s.upcase if format.is_a?(Symbol)
18
+
19
+ Events::ControllerCall.new(
20
+ controller: payload[:controller],
21
+ action: payload[:action],
22
+ format: format,
23
+ params: params
24
+ )
25
+ end
26
+ end
27
+
28
+ private
29
+ def extract_format(payload)
30
+ if payload.key?(:format)
31
+ payload[:format] # rails > 4.X
32
+ elsif payload.key?(:formats)
33
+ payload[:formats].first # rails 3.X
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,51 @@
1
+ module Timber
2
+ module Integrations
3
+ module ActionDispatch
4
+ # Reponsible for disabled logging in the ActionDispatch::DebugExceptions
5
+ # Rack middleware. We cannot simply remove the middleware because it is
6
+ # coupled with displaying an exception debug screen if debug exceptions is enabled.
7
+ #
8
+ # @private
9
+ class DebugExceptions < Integrator
10
+
11
+ # Patch for disabling logging
12
+ #
13
+ # @private
14
+ module InstanceMethods
15
+ def self.included(klass)
16
+ klass.class_eval do
17
+ private
18
+ def logger(*args)
19
+ nil
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ def initialize
26
+ begin
27
+ # Rails >= 3.1
28
+ require "action_dispatch/middleware/debug_exceptions"
29
+ rescue LoadError
30
+ # Rails < 3.1
31
+ require "action_dispatch/middleware/show_exceptions"
32
+ end
33
+ rescue LoadError => e
34
+ raise RequirementNotMetError.new(e.message)
35
+ end
36
+
37
+ def integrate!
38
+ if defined?(::ActionDispatch::DebugExceptions) && !::ActionDispatch::DebugExceptions.include?(InstanceMethods)
39
+ ::ActionDispatch::DebugExceptions.send(:include, InstanceMethods)
40
+ end
41
+
42
+ if defined?(::ActionDispatch::ShowExceptions) && !::ActionDispatch::ShowExceptions.include?(InstanceMethods)
43
+ ::ActionDispatch::ShowExceptions.send(:include, InstanceMethods)
44
+ end
45
+
46
+ true
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,25 @@
1
+ module Timber
2
+ module Integrations
3
+ module ActionView
4
+ # Reponsible for uninstalling the default `ActionView::LogSubscriber` and installing
5
+ # the TimberLogSubscriber.
6
+ #
7
+ # @private
8
+ class LogSubscriber < Integrator
9
+ def initialize
10
+ require "action_view/log_subscriber"
11
+ require "timber/integrations/action_view/log_subscriber/timber_log_subscriber"
12
+ rescue LoadError => e
13
+ raise RequirementNotMetError.new(e.message)
14
+ end
15
+
16
+ def integrate!
17
+ return true if Util::ActiveSupportLogSubscriber.subscribed?(:action_view, TimberLogSubscriber)
18
+
19
+ Util::ActiveSupportLogSubscriber.unsubscribe!(:action_view, ::ActionView::LogSubscriber)
20
+ TimberLogSubscriber.attach_to(:action_view)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,73 @@
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
+ info do
14
+ full_name = from_rails_root(event.payload[:identifier])
15
+ message = " Rendered #{full_name}"
16
+ message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
17
+ message << " (#{event.duration.round(1)}ms)"
18
+
19
+ Events::TemplateRender.new(
20
+ name: full_name,
21
+ time_ms: event.duration,
22
+ message: message
23
+ )
24
+ end
25
+ end
26
+
27
+ def render_partial(event)
28
+ info do
29
+ full_name = from_rails_root(event.payload[:identifier])
30
+ message = " Rendered #{full_name}"
31
+ message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
32
+ message << " (#{event.duration.round(1)}ms)"
33
+ message << " #{cache_message(event.payload)}" if event.payload.key?(:cache_hit)
34
+
35
+ Events::TemplateRender.new(
36
+ name: full_name,
37
+ time_ms: event.duration,
38
+ message: message
39
+ )
40
+ end
41
+ end
42
+
43
+ def render_collection(event)
44
+ if respond_to?(:render_count, true)
45
+ info do
46
+ identifier = event.payload[:identifier] || "templates"
47
+ full_name = from_rails_root(identifier)
48
+ message = " Rendered collection of #{full_name}" \
49
+ " #{render_count(event.payload)} (#{event.duration.round(1)}ms)"
50
+
51
+ Events::TemplateRender.new(
52
+ name: full_name,
53
+ time_ms: event.duration,
54
+ message: message
55
+ )
56
+ end
57
+ else
58
+ # Older versions of rails delegate this method to #render_template
59
+ render_template(event)
60
+ end
61
+ end
62
+
63
+ private
64
+ def log_rendering_start(payload)
65
+ # Consolidates 2 template rendering events into 1. We don't need 2 events for
66
+ # rendering a template. If you disagree, please feel free to open a PR and we
67
+ # can make this an option.
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end