require"honeybadger/instrumentation_helper"require"honeybadger/util/sql"moduleHoneybadgerclassNotificationSubscriberincludeHoneybadger::InstrumentationHelperdefstart(name,id,payload)payload[:_start_time]=::Process.clock_gettime(::Process::CLOCK_MONOTONIC)enddeffinish(name,id,payload)finish_time=::Process.clock_gettime(::Process::CLOCK_MONOTONIC)returnunlessprocess?(name,payload)payload={instrumenter_id: id,duration: ((finish_time-payload.delete(:_start_time))*1000).round(2)}.merge(format_payload(payload).compact)record(name,payload)enddefrecord(name,payload)ifHoneybadger.config.load_plugin_insights_events?(:rails)Honeybadger.event(name,payload)endifHoneybadger.config.load_plugin_insights_metrics?(:rails)metric_source"rails"record_metrics(name,payload)endenddefrecord_metrics(name,payload)casenamewhen"sql.active_record"gauge("duration.sql.active_record",value: payload[:duration],**payload.slice(:query))when"process_action.action_controller"gauge("duration.process_action.action_controller",value: payload[:duration],**payload.slice(:method,:controller,:action,:format,:status))gauge("db_runtime.process_action.action_controller",value: payload[:db_runtime],**payload.slice(:method,:controller,:action,:format,:status))gauge("view_runtime.process_action.action_controller",value: payload[:view_runtime],**payload.slice(:method,:controller,:action,:format,:status))when"perform.active_job"gauge("duration.perform.active_job",value: payload[:duration],**payload.slice(:job_class,:queue_name))when/^cache_.*.active_support$/gauge("duration.#{name}",value: payload[:duration],**payload.slice(:store,:key))endenddefprocess?(event,payload)trueenddefformat_payload(payload)payloadendendclassActionControllerSubscriber<NotificationSubscriberdefformat_payload(payload)payload.except(:headers,:request,:response)endendclassActionControllerCacheSubscriber<NotificationSubscriberdefformat_payload(payload)payload[:key]=::ActiveSupport::Cache.expand_cache_key(payload[:key])ifpayload[:key]payloadendendclassActiveSupportCacheSubscriber<NotificationSubscriberdefformat_payload(payload)payload[:key]=::ActiveSupport::Cache.expand_cache_key(payload[:key])ifpayload[:key]payloadendendclassActiveSupportCacheMultiSubscriber<NotificationSubscriberdefformat_payload(payload)payload[:key]=expand_cache_keys_from_payload(payload[:key])payload[:hits]=expand_cache_keys_from_payload(payload[:hits])payloadenddefexpand_cache_keys_from_payload(data)returnunlessdatadata=data.keysifdata.is_a?(Hash)Array(data).mapdo|k|::ActiveSupport::Cache.expand_cache_key(k)endendendclassActionViewSubscriber<NotificationSubscriberPROJECT_ROOT=defined?(::Rails)?::Rails.root.to_s:""defformat_payload(payload){view: payload[:identifier].to_s.gsub(PROJECT_ROOT,"[PROJECT_ROOT]"),layout: payload[:layout]}endendclassActiveRecordSubscriber<NotificationSubscriberdefformat_payload(payload){query: Util::SQL.obfuscate(payload[:sql],payload[:connection]&.adapter_name),async: payload[:async]}enddefprocess?(event,payload)returnfalseifpayload[:name]=="SCHEMA"trueendendclassActiveJobSubscriber<NotificationSubscriberdefformat_payload(payload)job=payload[:job]jobs=payload[:jobs]adapter=payload[:adapter]base_payload=payload.except(:job,:jobs,:adapter).merge({adapter_class: adapter&.class&.to_s})ifjobsbase_payload.merge({jobs: jobs.compact.map{|j|{job_class: j.class.to_s,job_id: j.job_id,queue_name: j.queue_name}}})elsifjobbase_payload.merge({job_class: job.class.to_s,job_id: job.job_id,queue_name: job.queue_name})elsebase_payloadendendendclassActionMailerSubscriber<NotificationSubscriberdefformat_payload(payload)# Don't include the mail object in the payload...mail=payload.delete(:mail)# ... but do include any attachment filenamesattachment_info=ifmail&.attachments&.any?{attachments: mail.attachments.map{|a|{filename: a.filename}}}else{}endpayload.merge(attachment_info)endendclassActiveStorageSubscriber<NotificationSubscriberendend