Class: Foam::Otel::RedactingMetricsExporter

Inherits:
Object
  • Object
show all
Defined in:
lib/foam/otel/redacting_exporter.rb

Overview

The metrics twin, added for door 2 (fleet contract ruling): door 1 masks metric attributes at capture, which FOREIGN instruments never pass — the ingest metric path runs the floor here, on foam's collected copy, before serialization and before any retry buffer. Same fail-closed posture as the span/log exporters: a metric whose rebuild fails is DROPPED loudly (never exported raw) and the batch reports FAILURE.

Also forwards reset — PeriodicMetricReader#after_fork calls exporter.reset to re-establish the OTLP HTTP connection in a forked child; a wrapper that swallowed it would leave door-2 metric taps dark in every Puma worker (GOTCHAS R7).

Instance Method Summary collapse

Constructor Details

#initialize(inner, config) ⇒ RedactingMetricsExporter

Returns a new instance of RedactingMetricsExporter.



106
107
108
109
# File 'lib/foam/otel/redacting_exporter.rb', line 106

def initialize(inner, config)
  @inner = inner
  @config = config
end

Instance Method Details

#export(metrics, timeout: nil) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/foam/otel/redacting_exporter.rb', line 111

def export(metrics, timeout: nil)
  batch = metrics.to_a
  masked = batch.filter_map { |md| Redaction.mask_metric_data(md, @config) }
  dropped = batch.length - masked.length
  if dropped.positive?
    Diagnostics.warn("redaction failed for #{dropped} metric(s) — dropped rather than exported " \
                     "unmasked (rule 14 fail-closed)")
    @inner.export(masked, timeout: timeout) unless masked.empty?
    return OpenTelemetry::SDK::Metrics::Export::FAILURE
  end
  @inner.export(masked, timeout: timeout)
rescue StandardError, SystemStackError
  Diagnostics.warn("metric redaction raised past its guards — batch dropped (fail-closed, rule 14/15)")
  OpenTelemetry::SDK::Metrics::Export::FAILURE
end

#force_flush(timeout: nil) ⇒ Object



127
# File 'lib/foam/otel/redacting_exporter.rb', line 127

def force_flush(timeout: nil) = @inner.force_flush(timeout: timeout)

#resetObject



130
131
132
# File 'lib/foam/otel/redacting_exporter.rb', line 130

def reset
  @inner.reset if @inner.respond_to?(:reset)
end

#shutdown(timeout: nil) ⇒ Object



128
# File 'lib/foam/otel/redacting_exporter.rb', line 128

def shutdown(timeout: nil) = @inner.shutdown(timeout: timeout)