diff --git a/config/initializers/semantic_logger.rb b/config/initializers/semantic_logger.rb index ab55c76..d357092 100644 --- a/config/initializers/semantic_logger.rb +++ b/config/initializers/semantic_logger.rb @@ -1,22 +1,18 @@ RailsSemanticLogger::Rack::Logger.logger.level = :info # useful for remaining log like "[Rack::Log] Started..." SemanticLogger.clear_appenders! +im = nil # Zeitwerk reload message -Rails.autoloaders.main.on_load('ApplicationController') { SemanticLogger[:Zeitwerk].debug('reload!') } - -all_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] -} +Rails.autoloaders.main.on_load('ApplicationController') do + SemanticLogger[:zeitwerk].debug('reload!') + im = Semantic::InstrumentationManager.new +end Rails.configuration.after_initialize do - all_notifications.each do |event_group, hooks| - hooks.each { |hook| ActiveSupport::Notifications.unsubscribe("#{hook}.#{event_group}") } - end - + Semantic::InstrumentationManager.clear ActiveSupport::Notifications.subscribe('rolling.live_constant') do |event| - SemanticLogger[:live_notifications].warn('rolling.live_constant', event.payload) - # FIXME: to be continued... + im.process(event.payload[:changes]) + rescue StandardError => e + puts e end end diff --git a/lib/live/definable.rb b/lib/live/definable.rb index 35d0da4..631e4bf 100644 --- a/lib/live/definable.rb +++ b/lib/live/definable.rb @@ -30,6 +30,8 @@ module Live def trigger_rolling_event(changes) ActiveSupport::Notifications.instrument('rolling.live_constant', changes:) FileUtils.touch(MAIN_CSS) if defined?(RailsLiveReload) # triggering RailsLiveReload + rescue StandardError => e + logger.error(e) end def override(constant, raw) diff --git a/lib/semantic/fancy_formatter.rb b/lib/semantic/fancy_formatter.rb index 54ceeb5..8b6c414 100644 --- a/lib/semantic/fancy_formatter.rb +++ b/lib/semantic/fancy_formatter.rb @@ -131,7 +131,8 @@ module Semantic def centerize(text, max_length = CENTER_SIZE) = text.reverse.truncate(max_length).reverse.center(max_length) def origin - taint = log.name.include?('_') ? TEXT_GRAY_400 : TEXT_CYAN + true_class = log.name == log.name.upcase_first + taint = true_class ? TEXT_CYAN : TEXT_GRAY_400 colorize(centerize(log.name), taint) end diff --git a/lib/semantic/instrumentation_manager.rb b/lib/semantic/instrumentation_manager.rb new file mode 100644 index 0000000..c21e5db --- /dev/null +++ b/lib/semantic/instrumentation_manager.rb @@ -0,0 +1,68 @@ +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 diff --git a/lib/semantic/subscribers/action_controller.rb b/lib/semantic/subscribers/action_controller.rb index 5a4f8d5..dbb0d11 100644 --- a/lib/semantic/subscribers/action_controller.rb +++ b/lib/semantic/subscribers/action_controller.rb @@ -21,9 +21,9 @@ module Semantic request = event.payload[:request] path = colorize(request.filtered_path, BOLD) - dimensions = Semantic::AnsiDimensions.new(rails: '╓─╖', before: 1) + dimensions = Semantic::FancyDimensions.new(rails: '╓─╖', before: 1) if defined?(@previously_redirect) && @previously_redirect - dimensions = Semantic::AnsiDimensions.new(rails: '╓║╖', before: 0) + dimensions = Semantic::FancyDimensions.new(rails: '╓║╖', before: 0) @previously_redirect = false end logger.info("Started #{request.raw_request_method} #{path}", dimensions:) @@ -44,7 +44,7 @@ module Semantic end end - def finish_processing(event) + def process_action(event) session_value = @transactions.delete(event.transaction_id) # delete previous session_value from start_processing SemanticLogger.tagged(session_value) do payload = event.payload @@ -70,17 +70,17 @@ module Semantic dimensions = case status_family when 2 - Semantic::AnsiDimensions.new(rails: TERMINUS_STRING) + Semantic::FancyDimensions.new(rails: TERMINUS_STRING) when 3 - Semantic::AnsiDimensions.new(rails: '╙║╜') + Semantic::FancyDimensions.new(rails: '╙║╜') when 4 - Semantic::AnsiDimensions.new(rails: '╙╨╜') + Semantic::FancyDimensions.new(rails: '╙╨╜') when 5 - Semantic::AnsiDimensions.new(rails: '╙║╜') + Semantic::FancyDimensions.new(rails: '╙║╜') end logger.info("Completed #{colorize(status, BOLD)} #{Rack::Utils::HTTP_STATUS_CODES[status]}", dimensions:) - logger.info(' ', dimensions: Semantic::AnsiDimensions.new(rails: ' ║ ')) if status_family == 3 - logger.info(' ', dimensions: Semantic::AnsiDimensions.new(rails: '╓║╖')) if status_family == 5 + logger.info(' ', dimensions: Semantic::FancyDimensions.new(rails: ' ║ ')) if status_family == 3 + logger.info(' ', dimensions: Semantic::FancyDimensions.new(rails: '╓║╖')) if status_family == 5 end end diff --git a/lib/semantic/subscribers/action_view.rb b/lib/semantic/subscribers/action_view.rb index e4efaff..02e76a4 100644 --- a/lib/semantic/subscribers/action_view.rb +++ b/lib/semantic/subscribers/action_view.rb @@ -9,7 +9,6 @@ module Semantic def initialize super(:action_view) - logger.level = Hot::Constants.log_action_view ? :debug : :fatal end def render_partial(event)