module Semantic module Subscribers # LogSubscriber for event_group :action_view class ActionView < LogSubscriber include AnsiColors REGEX_BASEDIR = %r{^#{Rails.root}/(.*)} def initialize(*) super(:view) @partials = {} end def render_partial(event) identifier = pathname(event.payload[:identifier]) partial_savings = @partials[event.transaction_id] ||= {} partial_saving = partial_savings[identifier] ||= {} origin = Rails.backtrace_cleaner.clean(caller)[1] # [0] is related to Instrumentalizer, get rid of it! partial_saving[origin] = partial_saving.key?(origin) ? partial_saving[origin] + 1 : 1 end def render_template(event) layout = event.payload[:layout] return unless layout identifier = pathname(event.payload[:identifier]) return unless identifier logger.debug do pop_partial_savings(event.transaction_id) "Rendered template #{identifier}" end end def render_collection(event) identifier = pathname(event.payload[:identifier]) return unless identifier count = event.payload[:count] cache_hits = event.payload[:cache_hits] || 0 logger.debug do pop_partial_savings(event.transaction_id) "Rendered collection #{identifier} (#{count} times, #{cache_hits} cached)" end end def render_layout(event) identifier = pathname(event.payload[:identifier]) return unless identifier logger.debug do pop_partial_savings(event.transaction_id) "Rendered layout #{identifier}" end end private def pop_partial_savings(transaction_id) partial_savings = @partials.delete(transaction_id) partial_savings.each do |partial, origins| sum_count = origins.values.reduce(:+) sum_count_info = " (#{sum_count} times in total)" if sum_count > 1 logger.debug("Rendered partial #{partial}#{sum_count_info}") origins.each do |origin, count| count_info = colorize("(#{count} times)", TEXT_GRAY_400) if count > 1 logger.debug("#{Semantic::Helper.stackisize(origin, symbol: '⇤')}#{count_info}") end end end def pathname(location) m = REGEX_BASEDIR.match(location) m[1] if m end end end end