Module: Engram::Instrumentation

Defined in:
lib/engram/instrumentation.rb

Overview

Optional ActiveSupport::Notifications integration.

Engram core remains dependency-free: when ActiveSupport is not loaded, instrumentation is a no-op around the supplied block.

Class Method Summary collapse

Class Method Details

.adapter_name(adapter) ⇒ Object



38
39
40
# File 'lib/engram/instrumentation.rb', line 38

def adapter_name(adapter)
  adapter.class.name || adapter.class.to_s
end

.elapsed_ms(started_at) ⇒ Object



49
50
51
# File 'lib/engram/instrumentation.rb', line 49

def elapsed_ms(started_at)
  ((monotonic_time - started_at) * 1000).round(1)
end

.instrument(event, payload = {}) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/engram/instrumentation.rb', line 11

def instrument(event, payload = {})
  started_at = monotonic_time

  unless notifications?
    return yield if block_given?
    return nil
  end

  ActiveSupport::Notifications.instrument("#{event}.engram", payload) do
    yield if block_given?
  ensure
    payload[:duration_ms] = elapsed_ms(started_at)
  end
end

.monotonic_timeObject



53
54
55
# File 'lib/engram/instrumentation.rb', line 53

def monotonic_time
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
end

.notifications?Boolean

Returns:

  • (Boolean)


34
35
36
# File 'lib/engram/instrumentation.rb', line 34

def notifications?
  defined?(ActiveSupport::Notifications) && ActiveSupport::Notifications.respond_to?(:instrument)
end

.payload(scope: nil, store: nil, **attributes) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/engram/instrumentation.rb', line 26

def payload(scope: nil, store: nil, **attributes)
  attributes = attributes.compact
  attributes[:store_adapter] = adapter_name(store) if store
  scope_identifier = scope_identifier(scope)
  attributes[:scope_identifier] = scope_identifier if scope_identifier
  attributes
end

.scope_identifier(scope) ⇒ Object



42
43
44
45
46
47
# File 'lib/engram/instrumentation.rb', line 42

def scope_identifier(scope)
  formatter = Engram.config.instrumentation_scope_identifier
  return nil unless formatter

  formatter.respond_to?(:call) ? formatter.call(scope) : scope.to_s
end