aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support
diff options
context:
space:
mode:
authorDaniel Schierbeck <dasch@zendesk.com>2013-04-15 15:23:46 +0200
committerDaniel Schierbeck <dasch@zendesk.com>2013-04-16 14:39:22 +0200
commit5f07048dfdcc86bf78d0a498c5f23fa4dec917f7 (patch)
treeba1aabafd14af3df6a3b580fd9fea8569e0ef7a4 /activesupport/lib/active_support
parentc78da9aed9453bf2c933392e7ae7831f3d2ef73e (diff)
downloadrails-5f07048dfdcc86bf78d0a498c5f23fa4dec917f7.tar.gz
rails-5f07048dfdcc86bf78d0a498c5f23fa4dec917f7.tar.bz2
rails-5f07048dfdcc86bf78d0a498c5f23fa4dec917f7.zip
Extract a base class from ActiveSupport::LogSubscriber
Adds a ActiveSupport::Subscriber base class that LogSubscriber inherits from. By inheriting from Subscriber, other kinds of subscribers can take advantage of the event attachment system.
Diffstat (limited to 'activesupport/lib/active_support')
-rw-r--r--activesupport/lib/active_support/log_subscriber.rb50
-rw-r--r--activesupport/lib/active_support/subscriber.rb76
2 files changed, 83 insertions, 43 deletions
diff --git a/activesupport/lib/active_support/log_subscriber.rb b/activesupport/lib/active_support/log_subscriber.rb
index c4b64bd1a6..e95dc5a866 100644
--- a/activesupport/lib/active_support/log_subscriber.rb
+++ b/activesupport/lib/active_support/log_subscriber.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/class/attribute'
+require 'active_support/subscriber'
module ActiveSupport
# ActiveSupport::LogSubscriber is an object set to consume
@@ -33,7 +34,7 @@ module ActiveSupport
# Log subscriber also has some helpers to deal with logging and automatically
# flushes all logs when the request finishes (via action_dispatch.callback
# notification) in a Rails environment.
- class LogSubscriber
+ class LogSubscriber < Subscriber
# Embed in a String to clear all previous ANSI sequences.
CLEAR = "\e[0m"
BOLD = "\e[1m"
@@ -60,18 +61,8 @@ module ActiveSupport
attr_writer :logger
- def attach_to(namespace, log_subscriber=new, notifier=ActiveSupport::Notifications)
- log_subscribers << log_subscriber
-
- log_subscriber.public_methods(false).each do |event|
- next if %w{ start finish }.include?(event.to_s)
-
- notifier.subscribe("#{event}.#{namespace}", log_subscriber)
- end
- end
-
def log_subscribers
- @@log_subscribers ||= []
+ subscribers
end
# Flush all log_subscribers' logger.
@@ -80,39 +71,18 @@ module ActiveSupport
end
end
- def initialize
- @queue_key = [self.class.name, object_id].join "-"
- super
- end
-
def logger
LogSubscriber.logger
end
def start(name, id, payload)
- return unless logger
-
- e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
- parent = event_stack.last
- parent << e if parent
-
- event_stack.push e
+ super if logger
end
def finish(name, id, payload)
- return unless logger
-
- finished = Time.now
- event = event_stack.pop
- event.end = finished
- event.payload.merge!(payload)
-
- method = name.split('.').first
- begin
- send(method, event)
- rescue Exception => e
- logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
- end
+ super if logger
+ rescue Exception => e
+ logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
end
protected
@@ -135,11 +105,5 @@ module ActiveSupport
bold = bold ? BOLD : ""
"#{bold}#{color}#{text}#{CLEAR}"
end
-
- private
-
- def event_stack
- Thread.current[@queue_key] ||= []
- end
end
end
diff --git a/activesupport/lib/active_support/subscriber.rb b/activesupport/lib/active_support/subscriber.rb
new file mode 100644
index 0000000000..a6ad473b59
--- /dev/null
+++ b/activesupport/lib/active_support/subscriber.rb
@@ -0,0 +1,76 @@
+module ActiveSupport
+ # ActiveSupport::Subscriber is an object set to consume
+ # ActiveSupport::Notifications. The subscriber dispatches notifications to
+ # a registered object based on its given namespace.
+ #
+ # An example would be Active Record subscriber responsible for collecting
+ # statistics about queries:
+ #
+ # module ActiveRecord
+ # class StatsSubscriber < ActiveSupport::Subscriber
+ # def sql(event)
+ # Statsd.timing("sql.#{event.payload[:name]}", event.duration)
+ # end
+ # end
+ # end
+ #
+ # And it's finally registered as:
+ #
+ # ActiveRecord::Subscriber.attach_to :active_record
+ #
+ # Since we need to know all instance methods before attaching the log
+ # subscriber, the line above should be called after your
+ # <tt>ActiveRecord::Subscriber</tt> definition.
+ #
+ # After configured, whenever a "sql.active_record" notification is published,
+ # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
+ # the `sql` method.
+ class Subscriber
+ class << self
+
+ # Attach the subscriber to a namespace.
+ def attach_to(namespace, subscriber=new, notifier=ActiveSupport::Notifications)
+ subscribers << subscriber
+
+ subscriber.public_methods(false).each do |event|
+ next if %w{ start finish }.include?(event.to_s)
+
+ notifier.subscribe("#{event}.#{namespace}", subscriber)
+ end
+ end
+
+ def subscribers
+ @@subscribers ||= []
+ end
+ end
+
+ def initialize
+ @queue_key = [self.class.name, object_id].join "-"
+ super
+ end
+
+ def start(name, id, payload)
+ e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
+ parent = event_stack.last
+ parent << e if parent
+
+ event_stack.push e
+ end
+
+ def finish(name, id, payload)
+ finished = Time.now
+ event = event_stack.pop
+ event.end = finished
+ event.payload.merge!(payload)
+
+ method = name.split('.').first
+ send(method, event)
+ end
+
+ private
+
+ def event_stack
+ Thread.current[@queue_key] ||= []
+ end
+ end
+end