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.6 KiB

  1. module Semantic
  2. NOTIFICATIONS = {
  3. action_controller: %i[start_processing process_action redirect_to],
  4. action_view: %i[render_partial render_template render_collection render_layout],
  5. active_record: %i[sql strict_loading instantiation start_transaction transaction]
  6. }.freeze
  7. # enable/disable instrumentation callbacks
  8. class Instrumentalizer
  9. include SemanticLogger::Loggable
  10. class << self
  11. def activate(*event_groups)
  12. reset
  13. runtime_registry_subscriber
  14. event_groups.each { |event_group| enable(event_group) }
  15. end
  16. private
  17. def runtime_registry_subscriber
  18. global_subscribers << ActiveSupport::Notifications.monotonic_subscribe('sql.active_record') do |name, start, finish, id, payload|
  19. unless %w[SCHEMA TRANSACTION].include?(payload[:name])
  20. ActiveRecord::RuntimeRegistry.queries_count += 1
  21. ActiveRecord::RuntimeRegistry.cached_queries_count += 1 if payload[:cached]
  22. end
  23. runtime = (finish - start) * 1_000.0
  24. ActiveRecord::RuntimeRegistry.async_sql_runtime += (runtime - payload[:lock_wait]) if payload[:async]
  25. ActiveRecord::RuntimeRegistry.sql_runtime += runtime
  26. end
  27. end
  28. def global_subscribers
  29. @global_subscribers ||= []
  30. end
  31. def reset
  32. global_subscribers.each do |sub|
  33. ActiveSupport::Notifications.unsubscribe(sub)
  34. end
  35. global_subscribers.clear
  36. NOTIFICATIONS.each do |event_group, hooks|
  37. hooks.each do |hook|
  38. hook_full_name = "#{hook}.#{event_group}"
  39. ActiveSupport::Notifications.unsubscribe(hook_full_name)
  40. end
  41. end
  42. end
  43. def enable(event_group)
  44. log_subscriber = build_log_subscriber_from(event_group)
  45. NOTIFICATIONS[event_group].each do |hook|
  46. subscriber = ActiveSupport::Notifications.subscribe("#{hook}.#{event_group}") do |event|
  47. # logger.debug("SEND #{log_subscriber} hook=#{hook}")
  48. log_subscriber.send(hook, event)
  49. rescue StandardError => e
  50. logger.error('Error during instrumentation handling', e)
  51. end
  52. global_subscribers << subscriber
  53. end
  54. end
  55. def build_log_subscriber_from(event_group)
  56. classname = event_group.to_s.camelize
  57. case classname
  58. when 'ActionController'
  59. Semantic::Subscribers.const_get(classname).new('toto1') # FIXME: externalize session_key
  60. else
  61. Semantic::Subscribers.const_get(classname).new
  62. end
  63. end
  64. end
  65. end
  66. end