module Semantic class InstrumentationManager NOTIFICATIONS = { action_controller: %i[start_processing process_action redirect_to], action_view: %i[render_partial render_template render_collection render_layout], active_record: %i[sql strict_loading instantiation start_transaction transaction] }.freeze def logger = @logger ||= SemanticLogger[:instrumentation] def initialize logger.debug 're-initialized' end def self.clear NOTIFICATIONS.each do |event_group, hooks| hooks.each { |hook| ActiveSupport::Notifications.unsubscribe("#{hook}.#{event_group}") } end end def process(changes) logger.info "process called with #{changes.size} change(s)" changes.each do |change| constant = change[:constant] value = change[:new_value] case constant when 'ACTION_VIEW', 'ACTION_CONTROLLER', 'ACTIVE_RECORD' value ? enable(constant) : disable(constant) end end logger.info 'DONE' end def enable(constant) logger.info("enable: #{constant}") event_group = constant.underscore.to_sym log_subscriber = build_log_subscriber_from(event_group.to_s.camelize) logger.warn(log_subscriber) NOTIFICATIONS[event_group].each do |hook| logger.info("subscribe to #{hook}.#{event_group}") ActiveSupport::Notifications.subscribe("#{hook}.#{event_group}") do |event| # logger.debug("SEND #{log_subscriber} hook=#{hook}") log_subscriber.send(hook, event) end end end def disable(constant) logger.info("disable: #{constant}") event_group = constant.underscore.to_sym logger.debug(NOTIFICATIONS[event_group].size) NOTIFICATIONS[event_group].each do |hook| logger.info("unsubscribe to #{hook}.#{event_group}") ActiveSupport::Notifications.unsubscribe("#{hook}.#{event_group}") end end def build_log_subscriber_from(classname) case classname when 'ActionController' then Semantic::Subscribers.const_get(classname).new('toto1') else Semantic::Subscribers.const_get(classname).new end end end end