You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.4 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
  1. module Semantic
  2. # use the Zeitwerk autoloader to reattach_appender for development autoreloading feature
  3. class DevLoader
  4. def initialize(session_key)
  5. @session_key = session_key
  6. @subscribers = {}
  7. RailsSemanticLogger::ActionController::LogSubscriber.logger.level = :fatal # useful for remanent Rack::Log started
  8. launch
  9. end
  10. def launch
  11. once_and_reload do
  12. append_ansi_formatter
  13. Semantic::NotificationUtil.clear_subscribers(/\.action_controller$/)
  14. Semantic::NotificationUtil.clear_subscribers(/\.action_view$/)
  15. reset_subscribers
  16. register_action_controller
  17. register_action_view
  18. end
  19. end
  20. private
  21. def once_and_reload(&)
  22. yield
  23. Rails.autoloaders.main.on_load('ApplicationController', &)
  24. end
  25. def append_ansi_formatter
  26. SemanticLogger.clear_appenders!
  27. formatter = Semantic::AnsiFormatter.new
  28. SemanticLogger.add_appender(io: $stdout,
  29. formatter:,
  30. filter: ->(log) { !formatter.reject(log) })
  31. end
  32. def register_action_controller
  33. sub_instance = Semantic::Subscribers::ActionController.new(@session_key)
  34. register_hook(sub_instance, :start_processing)
  35. register_hook(sub_instance, :process_action, :finish_processing)
  36. register_hook(sub_instance, :redirect_to)
  37. %i[send_file send_data halted_callback unpermitted_parameters send_stream write_fragment
  38. read_fragment expire_fragment exist_fragment?].each do |hook|
  39. register_hook(sub_instance, hook, :any_hook)
  40. end
  41. end
  42. def register_action_view
  43. sub_instance = Semantic::Subscribers::ActionView.new
  44. %i[render_template render_partial render_collection render_layout].each do |hook|
  45. register_hook(sub_instance, hook)
  46. end
  47. end
  48. def register_hook(sub_instance, hook, method = hook)
  49. @subscribers[sub_instance.class] ||= []
  50. @subscribers[sub_instance.class] << ActiveSupport::Notifications.subscribe("#{hook}.#{sub_instance.event_group}") do |event|
  51. sub_instance.send(method, event)
  52. end
  53. end
  54. def reset_subscribers
  55. return if @subscribers.empty?
  56. @subscribers.each_pair do |clazz, subs|
  57. # puts "reset #{subs.size} subscribers for class <#{clazz}>"
  58. subs.each { |sub| ActiveSupport::Notifications.unsubscribe(sub) }
  59. subs.clear
  60. end
  61. end
  62. end
  63. end