Module: Familia::Instrumentation

Defined in:
lib/familia/instrumentation.rb

Overview

Provides instrumentation hooks for observability into Familia operations.

This module allows applications to register callbacks for various events in Familia's lifecycle, enabling audit trails, performance monitoring, and operational observability.

Examples:

Basic usage

Familia.on_command do |cmd, duration, context|
  puts "Redis command: #{cmd} (#{duration}μs)"
end

Audit trail for secrets service

Familia.on_lifecycle do |event, instance, context|
  case event
  when :save
    AuditLog.create!(
      event: 'secret_saved',
      secret_id: instance.identifier,
      user_id: RequestContext.current_user_id
    )
  end
end

Class Method Summary collapse

Class Method Details

.notify_command(cmd, duration, context = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Notify all registered command hooks.



117
118
119
120
121
122
123
# File 'lib/familia/instrumentation.rb', line 117

def notify_command(cmd, duration, context = {})
  @hooks[:command].each do |hook|
    hook.call(cmd, duration, context)
  rescue => e
    Familia.error("Instrumentation hook failed", error: e.message, hook_type: :command)
  end
end

.notify_error(error, context = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Notify all registered error hooks.



147
148
149
150
151
152
153
# File 'lib/familia/instrumentation.rb', line 147

def notify_error(error, context = {})
  @hooks[:error].each do |hook|
    hook.call(error, context)
  rescue => e
    # Don't recurse on hook failures - just silently skip
  end
end

.notify_lifecycle(event, instance, context = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Notify all registered lifecycle hooks.



137
138
139
140
141
142
143
# File 'lib/familia/instrumentation.rb', line 137

def notify_lifecycle(event, instance, context = {})
  @hooks[:lifecycle].each do |hook|
    hook.call(event, instance, context)
  rescue => e
    Familia.error("Instrumentation hook failed", error: e.message, hook_type: :lifecycle)
  end
end

.notify_pipeline(command_count, duration, context = {}) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Notify all registered pipeline hooks.



127
128
129
130
131
132
133
# File 'lib/familia/instrumentation.rb', line 127

def notify_pipeline(command_count, duration, context = {})
  @hooks[:pipeline].each do |hook|
    hook.call(command_count, duration, context)
  rescue => e
    Familia.error("Instrumentation hook failed", error: e.message, hook_type: :pipeline)
  end
end

.on_command {|cmd, duration, context| ... } ⇒ Object

Register a callback for Redis command execution.

Examples:

Familia.on_command do |cmd, duration, ctx|
  StatsD.timing("familia.command.#{cmd.downcase}", duration / 1000.0)
end

Yields:

  • (cmd, duration, context)

    Callback block

Yield Parameters:

  • cmd (String)

    The Redis command name (e.g., "SET", "ZADD")

  • duration (Integer)

    Command execution duration in microseconds

  • context (Hash)

    Additional context including:

    • :full_command [Array] Complete command with arguments
    • :db [Integer] Database number
    • :connection_id [String] Connection identifier


55
56
57
# File 'lib/familia/instrumentation.rb', line 55

def on_command(&block)
  @hooks[:command] << block
end

.on_error {|error, context| ... } ⇒ Object

Register a callback for error conditions.

Examples:

Familia.on_error do |error, ctx|
  Sentry.capture_exception(error, extra: ctx)
end

Yields:

  • (error, context)

    Callback block

Yield Parameters:

  • error (Exception)

    The error that occurred

  • context (Hash)

    Additional context including:

    • :operation [Symbol] Operation that failed (:serialization, etc.)
    • :field [Symbol] Field name (for serialization errors)
    • :object_class [String] Class name of the object


111
112
113
# File 'lib/familia/instrumentation.rb', line 111

def on_error(&block)
  @hooks[:error] << block
end

.on_lifecycle {|event, instance, context| ... } ⇒ Object

Register a callback for Horreum lifecycle events.

Examples:

Familia.on_lifecycle do |event, instance, ctx|
  case event
  when :destroy
    Rails.logger.info("Destroyed #{instance.class}:#{instance.identifier}")
  end
end

Yields:

  • (event, instance, context)

    Callback block

Yield Parameters:

  • event (Symbol)

    Lifecycle event (:initialize, :save, :destroy)

  • instance (Familia::Horreum)

    The object instance

  • context (Hash)

    Additional context including:

    • :duration [Integer] Operation duration in microseconds (for initialize/save)
    • :update_expiration [Boolean] Whether TTL was updated (for save)


93
94
95
# File 'lib/familia/instrumentation.rb', line 93

def on_lifecycle(&block)
  @hooks[:lifecycle] << block
end

.on_pipeline {|command_count, duration, context| ... } ⇒ Object

Register a callback for pipelined Redis operations.

Examples:

Familia.on_pipeline do |count, duration, ctx|
  StatsD.timing("familia.pipeline", duration / 1000.0)
  StatsD.gauge("familia.pipeline.commands", count)
end

Yields:

  • (command_count, duration, context)

    Callback block

Yield Parameters:

  • command_count (Integer)

    Number of commands in the pipeline

  • duration (Integer)

    Pipeline execution duration in microseconds

  • context (Hash)

    Additional context



72
73
74
# File 'lib/familia/instrumentation.rb', line 72

def on_pipeline(&block)
  @hooks[:pipeline] << block
end