pvincent
2 months ago
11 changed files with 126 additions and 104 deletions
-
2app/controllers/strong_controller.rb
-
2app/views/hot/index.html.erb
-
2app/views/scores/index.html.erb
-
65config/initializers/instrumentalizing.rb
-
1config/initializers/monkey_patches.rb
-
28config/initializers/semantic_logger.rb
-
4config/puma.rb
-
6lib/live/constants.rb
-
2lib/live/definable.rb
-
50lib/semantic/instrumentalizer.rb
-
68lib/semantic/instrumentation_manager.rb
@ -1,4 +1,4 @@ |
|||||
<div> |
<div> |
||||
<h1 class="font-bold text-4xl">Hot#index</h1> |
<h1 class="font-bold text-4xl">Hot#index</h1> |
||||
<%= Hot::Live %> |
|
||||
|
ssss |
||||
</div> |
</div> |
@ -0,0 +1,65 @@ |
|||||
|
return if Rails.application.tailwind_watcher? |
||||
|
|
||||
|
RailsSemanticLogger::Rack::Logger.logger.level = :info # useful for remaining log like "[Rack::Log] Started..." |
||||
|
SemanticLogger.clear_appenders! |
||||
|
|
||||
|
return unless Rails.application.server? |
||||
|
|
||||
|
def build_instrumentation_config |
||||
|
{ |
||||
|
action_controller: true, |
||||
|
action_view: Live::Constants::ACTION_VIEW |
||||
|
# active_record: Live::Constants::ACTIVE_RECORD |
||||
|
}.map do |key, value| |
||||
|
key if value |
||||
|
end.compact |
||||
|
end |
||||
|
|
||||
|
Rails.autoloaders.main.on_load('ApplicationController') do |
||||
|
puts '--- Zeitwerk RELOAD ---' |
||||
|
Semantic::Instrumentalizer.activate(*build_instrumentation_config) |
||||
|
end |
||||
|
|
||||
|
Rails.configuration.after_initialize do |
||||
|
puts '---- AFTER INITIALIZE ---------' |
||||
|
Rails.logger.name = 'rails' |
||||
|
|
||||
|
ActiveSupport::Notifications.subscribe('rolling.live_constant') do |event| |
||||
|
puts event.payload[:changes].inspect |
||||
|
# TODO: if key includes ACTIVE_RECORD ACTION_VIEW |
||||
|
Semantic::Instrumentalizer.activate(*build_instrumentation_config) |
||||
|
end |
||||
|
|
||||
|
# im = nil |
||||
|
# Rails.autoloaders.main.on_load('ApplicationController') do |
||||
|
# SemanticLogger[:zeitwerk].debug('reload!') |
||||
|
# im = Semantic::InstrumentationManager.new |
||||
|
# end |
||||
|
|
||||
|
# Semantic::InstrumentationManager.clear |
||||
|
|
||||
|
# bootstrap = [{ kind: :restored, constant: 'ACTION_VIEW', type: :boolean, old_value: false, new_value: true }, |
||||
|
# { kind: :restored, constant: 'ACTION_CONTROLLER', type: :boolean, old_value: false, new_value: true }] |
||||
|
# im ||= Semantic::InstrumentationManager.new |
||||
|
# im.process(bootstrap) |
||||
|
end |
||||
|
|
||||
|
# RAILS_HOOKS = %i[ |
||||
|
# action_controller |
||||
|
# action_controller_api |
||||
|
# action_controller_base |
||||
|
# action_dispatch_request |
||||
|
# action_dispatch_response |
||||
|
# action_view |
||||
|
# active_job |
||||
|
# active_model |
||||
|
# active_record |
||||
|
# active_record_fixture_set |
||||
|
# after_initialize |
||||
|
# after_routes_loaded |
||||
|
# before_configuration |
||||
|
# before_eager_load |
||||
|
# before_initialize |
||||
|
# i18n |
||||
|
# message_pack |
||||
|
# ].freeze |
@ -1,28 +0,0 @@ |
|||||
return if Rails.application.tailwind_watcher? |
|
||||
|
|
||||
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') do |
|
||||
SemanticLogger[:zeitwerk].debug('reload!') |
|
||||
im = Semantic::InstrumentationManager.new |
|
||||
end |
|
||||
|
|
||||
Rails.configuration.after_initialize do |
|
||||
Rails.logger.name = 'error_trap' |
|
||||
Semantic::InstrumentationManager.clear |
|
||||
|
|
||||
bootstrap = [{ kind: :restored, constant: 'ACTION_VIEW', type: :boolean, old_value: false, new_value: true }, |
|
||||
{ kind: :restored, constant: 'ACTION_CONTROLLER', type: :boolean, old_value: false, new_value: true }] |
|
||||
im ||= Semantic::InstrumentationManager.new |
|
||||
im.process(bootstrap) |
|
||||
|
|
||||
ActiveSupport::Notifications.subscribe('rolling.live_constant') do |event| |
|
||||
puts event.payload[:changes].inspect |
|
||||
im.process(event.payload[:changes]) |
|
||||
rescue StandardError => e |
|
||||
puts e |
|
||||
end |
|
||||
end |
|
@ -0,0 +1,50 @@ |
|||||
|
module Semantic |
||||
|
# enable/disable instrumentation callbacks |
||||
|
class Instrumentalizer |
||||
|
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 |
||||
|
|
||||
|
class << self |
||||
|
def activate(*event_groups) |
||||
|
reset |
||||
|
event_groups.each { |event_group| enable(event_group) } |
||||
|
end |
||||
|
|
||||
|
private |
||||
|
|
||||
|
def logger = @logger ||= SemanticLogger[:instrumentation] |
||||
|
|
||||
|
def reset |
||||
|
NOTIFICATIONS.each do |event_group, hooks| |
||||
|
hooks.each { |hook| ActiveSupport::Notifications.unsubscribe("#{hook}.#{event_group}") } |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def enable(event_group) |
||||
|
logger.debug { "enabling: #{event_group}" } |
||||
|
|
||||
|
log_subscriber = build_log_subscriber_from(event_group) |
||||
|
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 build_log_subscriber_from(event_group) |
||||
|
classname = event_group.to_s.camelize |
||||
|
case classname |
||||
|
when 'ActionController' |
||||
|
Semantic::Subscribers.const_get(classname).new('toto1') |
||||
|
else |
||||
|
Semantic::Subscribers.const_get(classname).new |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
end |
||||
|
end |
@ -1,68 +0,0 @@ |
|||||
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 |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue