# frozen_string_literal: true # encoding: utf-8 module Mongoid module Railties module ControllerRuntime # This extension mimics the Rails' internal method to # measure ActiveRecord runtime during request processing. # It appends MongoDB runtime value (`mongoid_runtime`) into payload # of instrumentation event `process_action.action_controller`. module ControllerExtension extend ActiveSupport::Concern protected attr_internal :mongoid_runtime # Reset the runtime before each action. def process_action(action, *args) Collector.reset_runtime super end # Override to collect the measurements. def cleanup_view_runtime mongo_rt_before_render = Collector.reset_runtime runtime = super mongo_rt_after_render = Collector.reset_runtime self.mongoid_runtime = mongo_rt_before_render + mongo_rt_after_render runtime - mongo_rt_after_render end # Add the measurement to the instrumentation event payload. def append_info_to_payload(payload) super payload[:mongoid_runtime] = (mongoid_runtime || 0) + Collector.reset_runtime end module ClassMethods # Append MongoDB runtime information to ActionController runtime # log message. def log_process_action(payload) messages = super mongoid_runtime = payload[:mongoid_runtime] messages << ("MongoDB: %.1fms" % mongoid_runtime.to_f) if mongoid_runtime messages end end end # The Collector of MongoDB runtime metric, that subscribes to Mongo # driver command monitoring. Stores the value within a thread-local # variable to provide correct accounting when an application issues # MongoDB operations from background threads. class Collector VARIABLE_NAME = "Mongoid.controller_runtime".freeze def started _; end def _completed e Collector.runtime += e.duration end alias :succeeded :_completed alias :failed :_completed def self.runtime Thread.current[VARIABLE_NAME] ||= 0 end def self.runtime= value Thread.current[VARIABLE_NAME] = value end def self.reset_runtime to_now = runtime self.runtime = 0 to_now end end end end end