timber 1.1.14 → 2.0.0

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