ActiveSupport::Notifications render.active_model_serializers

Squashed commits:

Add Logging

Generates logging when renders a serializer.

Tunning performance on notify_active_support

- Use yield over block.call
- Freeze the event name string

Organize the logger architeture

* Keep only the `ActiveModel::Serializer.logger` to follow the same public API we
  have for example to config, like `ActiveModel::Serializer.config.adapter` and
  remove the `ActiveModelSerializers.logger` API.
* Define the logger on the load of the AMS, following the Rails convention on
  Railties [1], [2] and [3].

This way on non Rails apps we have a default logger and on Rails apps we will
use the `Rails.logger` the same way that Active Job do [4].

[1]: 2ad9afe4ff/activejob/lib/active_job/railtie.rb (L9-L11)
[2]: 2ad9afe4ff/activerecord/lib/active_record/railtie.rb (L75-L77)
[3]: 2ad9afe4ff/actionview/lib/action_view/railtie.rb (L19-L21)
[4]: 2ad9afe4ff/activejob/lib/active_job/logging.rb (L10-L11)

Performance tunning on LogSubscriber#render

Move the definition of locals to inside the `info` block this way the code is
executed only when the logger is called.

Remove not needed check on SerializableResource

Use SerializableResource on ActionController integration

On the ActionController was using a adapter, and since the instrumentation is
made on the SerializableResource we need to use the SerializableResource over
the adapter directly. Otherwise the logger is not called on a Rails app.

Use SerializableResource on the ActionController, since this is the main
interface to create and call a serializer.

Using always the SerializableResource we can keep the adapter code more easy to
mantain since no Adapter will need to call the instrumentation, only the
SerializableResource care about this.

Add docs about logging

Add a CHANGELOG entry

Keep the ActiveModelSerializers.logger

Better wording on Logging docs

[ci skip]

Add doc about instrumentation

[ci skip]

Use ActiveModel::Callbacks on the SerializableResource
This commit is contained in:
Mauro George
2015-10-21 20:12:47 -02:00
committed by Benjamin Fleischer
parent efe5128a2e
commit 51424963da
10 changed files with 183 additions and 1 deletions

View File

@@ -32,6 +32,7 @@ module ActionController
serializable_resource.serialization_scope_name = _serialization_scope
begin
serializable_resource.adapter
serializable_resource
rescue ActiveModel::Serializer::CollectionSerializer::NoSerializerError
resource
end

View File

@@ -2,6 +2,15 @@ require 'set'
module ActiveModel
class SerializableResource
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter, :meta, :meta_key, :links])
extend ActiveModel::Callbacks
define_model_callbacks :render
around_render do |_, block, _|
notify_active_support do
block.call
end
end
# Primary interface to composing a resource with a serializer and adapter.
# @return the serializable_resource, ready for #as_json/#to_json/#serializable_hash.
@@ -11,7 +20,23 @@ module ActiveModel
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] }
end
delegate :serializable_hash, :as_json, :to_json, to: :adapter
def serializable_hash(*args)
run_callbacks :render do
adapter.serializable_hash(*args)
end
end
def as_json(*args)
run_callbacks :render do
adapter.as_json(*args)
end
end
def to_json(*args)
run_callbacks :render do
adapter.to_json(*args)
end
end
def serialization_scope=(scope)
serializer_opts[:scope] = scope
@@ -64,5 +89,13 @@ module ActiveModel
protected
attr_reader :resource, :adapter_opts, :serializer_opts
def notify_active_support
event_name = 'render.active_model_serializers'.freeze
payload = { serializer: serializer, adapter: adapter }
ActiveSupport::Notifications.instrument(event_name, payload) do
yield
end
end
end
end

View File

@@ -6,6 +6,7 @@ require 'active_model/serializer/associations'
require 'active_model/serializer/configuration'
require 'active_model/serializer/fieldset'
require 'active_model/serializer/lint'
require 'active_model/serializer/logging'
# ActiveModel::Serializer is an abstract class that is
# reified when subclassed to decorate a resource.
@@ -13,6 +14,7 @@ module ActiveModel
class Serializer
include Configuration
include Associations
include Logging
require 'active_model/serializer/adapter'
# Matches

View File

@@ -0,0 +1,26 @@
module ActiveModel
class Serializer
module Logging
extend ActiveSupport::Concern
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
end
end
def logger
ActiveModelSerializers.logger
end
end
end
end
end
ActiveModel::Serializer::Logging::LogSubscriber.attach_to :active_model_serializers