Module: ActiveRecordQueryCounter::ConnectionAdapterExtension

Defined in:
lib/active_record_query_counter/connection_adapter_extension.rb

Overview

Module to prepend to the connection adapter to inject the counting behavior.

Defined Under Namespace

Modules: ExecQuery, InternalExecQuery

Constant Summary collapse

CPU_CLOCK_ID =

Clock used to measure the CPU time consumed by the current thread while a query runs. It is not available on every platform (e.g. Windows), in which case CPU time is not measured and is treated as zero.

(Process::CLOCK_THREAD_CPUTIME_ID))

Class Method Summary collapse

Class Method Details

.inject(connection_class) ⇒ Object



12
13
14
15
16
17
18
# File 'lib/active_record_query_counter/connection_adapter_extension.rb', line 12

def inject(connection_class)
  # Rails 7.1+ uses internal_exec_query instead of exec_query.
  mod = (connection_class.method_defined?(:internal_exec_query) ? InternalExecQuery : ExecQuery)
  unless connection_class.include?(mod)
    connection_class.prepend(mod)
  end
end

.measure_query(sql, name, binds) { ... } ⇒ Object

Measure a query by wrapping its execution. In addition to the wall clock time, the GC time and thread CPU time spent while the query runs are captured so that the time actually spent waiting on the database can be isolated from time lost to garbage collection and Ruby VM work.

Parameters:

  • sql (String)

    the SQL statement being executed

  • name (String, nil)

    the name of the query

  • binds (Array)

    the bind parameters

Yields:

  • executes the query and returns its result

Returns:

  • (Object)

    the result of the query



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/active_record_query_counter/connection_adapter_extension.rb', line 30

def measure_query(sql, name, binds)
  gc_start = GC.total_time
  cpu_start = current_cpu_time
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  result = yield
  if result.is_a?(ActiveRecord::Result)
    end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
    cpu_time = current_cpu_time - cpu_start
    gc_time = (GC.total_time - gc_start) / 1_000_000_000.0
    ActiveRecordQueryCounter.add_query(sql, name, binds, result.length, start_time, end_time, gc_time, cpu_time)
  end
  result
end