Skip to content

Commit

Permalink
Optimize log subscribers to check if the log level is sufficient befo…
Browse files Browse the repository at this point in the history
…re performing an operations.
  • Loading branch information
Brian Durand committed Sep 30, 2012
1 parent 01059d7 commit 3785272
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 14 deletions.
6 changes: 4 additions & 2 deletions actionmailer/lib/action_mailer/log_subscriber.rb
@@ -1,13 +1,15 @@
module ActionMailer module ActionMailer
class LogSubscriber < ActiveSupport::LogSubscriber class LogSubscriber < ActiveSupport::LogSubscriber
def deliver(event) def deliver(event)
return unless logger.info?
recipients = Array(event.payload[:to]).join(', ') recipients = Array(event.payload[:to]).join(', ')
info("\nSent mail to #{recipients} (%1.fms)" % event.duration) info("\nSent mail to #{recipients} (#{event.duration.round(1)}ms)")
debug(event.payload[:mail]) debug(event.payload[:mail])
end end


def receive(event) def receive(event)
info("\nReceived mail (%.1fms)" % event.duration) return unless logger.info?
info("\nReceived mail (#{event.duration.round(1)}ms)")
debug(event.payload[:mail]) debug(event.payload[:mail])
end end


Expand Down
17 changes: 11 additions & 6 deletions actionpack/lib/action_controller/log_subscriber.rb
Expand Up @@ -4,6 +4,8 @@ class LogSubscriber < ActiveSupport::LogSubscriber
INTERNAL_PARAMS = %w(controller action format _method only_path) INTERNAL_PARAMS = %w(controller action format _method only_path)


def start_processing(event) def start_processing(event)
return unless logger.info?

payload = event.payload payload = event.payload
params = payload[:params].except(*INTERNAL_PARAMS) params = payload[:params].except(*INTERNAL_PARAMS)
format = payload[:format] format = payload[:format]
Expand All @@ -14,6 +16,8 @@ def start_processing(event)
end end


def process_action(event) def process_action(event)
return unless logger.info?

payload = event.payload payload = event.payload
additions = ActionController::Base.log_process_action(payload) additions = ActionController::Base.log_process_action(payload)


Expand All @@ -22,35 +26,36 @@ def process_action(event)
exception_class_name = payload[:exception].first exception_class_name = payload[:exception].first
status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name) status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
end end
message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in %.0fms" % event.duration message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
message << " (#{additions.join(" | ")})" unless additions.blank? message << " (#{additions.join(" | ")})" unless additions.blank?


info(message) info(message)
end end


def halted_callback(event) def halted_callback(event)
info "Filter chain halted as #{event.payload[:filter]} rendered or redirected" info("Filter chain halted as #{event.payload[:filter]} rendered or redirected")
end end


def send_file(event) def send_file(event)
info("Sent file %s (%.1fms)" % [event.payload[:path], event.duration]) info("Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)")
end end


def redirect_to(event) def redirect_to(event)
info "Redirected to #{event.payload[:location]}" info("Redirected to #{event.payload[:location]}")
end end


def send_data(event) def send_data(event)
info("Sent data %s (%.1fms)" % [event.payload[:filename], event.duration]) info("Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)")
end end


%w(write_fragment read_fragment exist_fragment? %w(write_fragment read_fragment exist_fragment?
expire_fragment expire_page write_page).each do |method| expire_fragment expire_page write_page).each do |method|
class_eval <<-METHOD, __FILE__, __LINE__ + 1 class_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{method}(event) def #{method}(event)
return unless logger.info?
key_or_path = event.payload[:key] || event.payload[:path] key_or_path = event.payload[:key] || event.payload[:path]
human_name = #{method.to_s.humanize.inspect} human_name = #{method.to_s.humanize.inspect}
info("\#{human_name} \#{key_or_path} \#{"(%.1fms)" % event.duration}") info("\#{human_name} \#{key_or_path} (\#{event.duration.round(1)}ms)")
end end
METHOD METHOD
end end
Expand Down
7 changes: 5 additions & 2 deletions actionpack/lib/action_view/log_subscriber.rb
Expand Up @@ -3,10 +3,13 @@ module ActionView
# #
# Provides functionality so that Rails can output logs from Action View. # Provides functionality so that Rails can output logs from Action View.
class LogSubscriber < ActiveSupport::LogSubscriber class LogSubscriber < ActiveSupport::LogSubscriber
VIEWS_PATTERN = /^app\/views\//.freeze

def render_template(event) def render_template(event)
return unless logger.info?
message = " Rendered #{from_rails_root(event.payload[:identifier])}" message = " Rendered #{from_rails_root(event.payload[:identifier])}"
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout] message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
message << (" (%.1fms)" % event.duration) message << " (#{event.duration.round(1)}ms)"
info(message) info(message)
end end
alias :render_partial :render_template alias :render_partial :render_template
Expand All @@ -19,7 +22,7 @@ def logger
protected protected


def from_rails_root(string) def from_rails_root(string)
string.sub("#{Rails.root}/", "").sub(/^app\/views\//, "") string.sub("#{Rails.root}/", "").sub(VIEWS_PATTERN, "")
end end
end end
end end
Expand Down
10 changes: 6 additions & 4 deletions activerecord/lib/active_record/log_subscriber.rb
@@ -1,11 +1,13 @@
module ActiveRecord module ActiveRecord
class LogSubscriber < ActiveSupport::LogSubscriber class LogSubscriber < ActiveSupport::LogSubscriber
IGNORE_PAYLOAD_NAMES = ["SCHEMA", "EXPLAIN"]

def self.runtime=(value) def self.runtime=(value)
Thread.current["active_record_sql_runtime"] = value Thread.current[:active_record_sql_runtime] = value
end end


def self.runtime def self.runtime
Thread.current["active_record_sql_runtime"] ||= 0 Thread.current[:active_record_sql_runtime] ||= 0
end end


def self.reset_runtime def self.reset_runtime
Expand All @@ -24,9 +26,9 @@ def sql(event)


payload = event.payload payload = event.payload


return if 'SCHEMA' == payload[:name] return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])


name = '%s (%.1fms)' % [payload[:name], event.duration] name = "#{payload[:name]} (#{event.duration.round(1)}ms)"
sql = payload[:sql].squeeze(' ') sql = payload[:sql].squeeze(' ')
binds = nil binds = nil


Expand Down
2 changes: 2 additions & 0 deletions activesupport/CHANGELOG.md
Expand Up @@ -197,4 +197,6 @@


* Remove deprecated ActiveSupport::JSON::Variable. *Erich Menge* * Remove deprecated ActiveSupport::JSON::Variable. *Erich Menge*


* Optimize log subscribers to check log level before doing any processing. *Brian Durand*

Please check [3-2-stable](https://github.com/rails/rails/blob/3-2-stable/activesupport/CHANGELOG.md) for previous changes. Please check [3-2-stable](https://github.com/rails/rails/blob/3-2-stable/activesupport/CHANGELOG.md) for previous changes.

0 comments on commit 3785272

Please sign in to comment.