pvincent
3 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> |
|||
<h1 class="font-bold text-4xl">Hot#index</h1> |
|||
<%= Hot::Live %> |
|||
ssss |
|||
</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