diff --git a/lib/active_model_serializers/logging.rb b/lib/active_model_serializers/logging.rb index 6a1ede89..2658da84 100644 --- a/lib/active_model_serializers/logging.rb +++ b/lib/active_model_serializers/logging.rb @@ -1,31 +1,59 @@ ## # Adapted from: +# https://github.com/rubygems/rubygems/blob/cb28f5e991/lib/rubygems/deprecate.rb # https://github.com/rails/rails/blob/280654ef88/activejob/lib/active_job/logging.rb +# +# Provides a single method +notify+ to be used to declare when +# something a method notifies. +# +# class Adapter +# def self.klass_method +# # ... +# end +# +# def instance_method +# # ... +# end +# +# extend ActiveModelSerializers::Logging +# notify :instance_method, :render +# +# class << self +# extend ActiveModelSerializers::Logging +# notify :klass_method, :render +# end +# end module ActiveModelSerializers::Logging - def self.included(base) - base.send(:include, ActiveSupport::Callbacks) - base.extend ClassMethods - base.class_eval do - define_callbacks :render - around_render do |_, block| - notify_active_support do - block.call - end - end - end + extend ActiveSupport::Concern + + included do + include ActiveSupport::Callbacks + instrument_around_render end module ClassMethods + def instrument_around_render + define_callbacks :render + around_render do |args, block| + tag_logger do + notify_render do + block.call(args) + end + end + end + end + def around_render(*filters, &blk) set_callback(:render, :around, *filters, &blk) end + ## # Simple notify method that wraps up +name+ - # in a dummy method. It notifies on each call to the dummy method - # telling what the current serializer and adapter are being rendered. + # in a dummy method. It notifies on with the +callback_name+ notifier on + # each call to the dummy method, telling what the current serializer and adapter + # are being rendered. # Adapted from: # https://github.com/rubygems/rubygems/blob/cb28f5e991/lib/rubygems/deprecate.rb - def notify(name, callback_name) class_eval do old = "_notifying_#{callback_name}_#{name}" @@ -39,25 +67,39 @@ module ActiveModelSerializers::Logging end end - def notify_active_support + def notify_render(*) event_name = 'render.active_model_serializers'.freeze - payload = { serializer: serializer, adapter: adapter } - ActiveSupport::Notifications.instrument(event_name, payload) do + ActiveSupport::Notifications.instrument(event_name, notify_render_payload) do yield end end + def notify_render_payload + { serializer: serializer, adapter: adapter } + end + private + def tag_logger(*tags) + if ActiveModelSerializers.logger.respond_to?(:tagged) + tags.unshift 'AMS'.freeze unless logger_tagged_by_active_model_serializers? + ActiveModelSerializers.logger.tagged(*tags) { yield } + else + yield + end + end + + def logger_tagged_by_active_model_serializers? + ActiveModelSerializers.logger.formatter.current_tags.include?('AMS'.freeze) + end + class LogSubscriber < ActiveSupport::LogSubscriber def render(event) - logger.tagged('AMS') do - info do - serializer = event.payload[:serializer] - adapter = event.payload[:adapter] - duration = event.duration.round(2) - "Rendered #{serializer.name} with #{adapter.class} (#{duration}ms)" - end + info do + serializer = event.payload[:serializer] + adapter = event.payload[:adapter] + duration = event.duration.round(2) + "Rendered #{serializer.name} with #{adapter.class} (#{duration}ms)" end end