Module: Smith::Trace

Defined in:
lib/smith/trace.rb,
lib/smith/trace/logger.rb,
lib/smith/trace/memory.rb,
lib/smith/trace/open_telemetry.rb

Defined Under Namespace

Classes: Logger, Memory, OpenTelemetry

Constant Summary collapse

SENSITIVITY_CONTENT_KEYS =
%i[args result].freeze

Class Method Summary collapse

Class Method Details

.apply_content_policy(data, sensitivity) ⇒ Object



34
35
36
37
38
39
40
41
42
43
# File 'lib/smith/trace.rb', line 34

def self.apply_content_policy(data, sensitivity)
  case Smith.config.trace_content
  when true
    apply_sensitivity(data, sensitivity)
  when :redacted
    apply_sensitivity(redact_sensitive_keys(data), sensitivity)
  else
    data.except(*SENSITIVITY_CONTENT_KEYS)
  end
end

.apply_sensitivity(data, sensitivity) ⇒ Object



45
46
47
48
49
50
51
52
53
54
# File 'lib/smith/trace.rb', line 45

def self.apply_sensitivity(data, sensitivity)
  case sensitivity
  when :high
    data.except(*SENSITIVITY_CONTENT_KEYS)
  when :medium
    redact_sensitive_keys(data)
  else
    data
  end
end

.filter_fields(type, data) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/smith/trace.rb', line 77

def self.filter_fields(type, data)
  configured_fields = Smith.config.trace_fields
  return data unless configured_fields.is_a?(Hash)

  allowed = configured_fields[type]
  return data unless allowed.respond_to?(:include?)

  data.each_with_object({}) do |(key, value), filtered|
    filtered[key] = value if allowed.include?(key)
  end
end

.record(type:, data:, sensitivity: :low) ⇒ Object



7
8
9
10
11
12
13
14
15
16
# File 'lib/smith/trace.rb', line 7

def self.record(type:, data:, sensitivity: :low)
  adapter = resolve_adapter
  return unless adapter

  filtered = apply_content_policy(data, sensitivity)
  filtered = filter_fields(type, filtered)
  adapter.record(type: type, data: filtered)
rescue StandardError => e
  Smith.config.logger&.error("Smith::Trace adapter error: #{e.message}")
end

.redact_sensitive_keys(data) ⇒ Object



56
57
58
59
60
61
62
63
64
# File 'lib/smith/trace.rb', line 56

def self.redact_sensitive_keys(data)
  data.each_with_object({}) do |(key, value), filtered|
    filtered[key] = if SENSITIVITY_CONTENT_KEYS.include?(key)
                      redact_value(value)
                    else
                      value
                    end
  end
end

.redact_value(value) ⇒ Object



66
67
68
69
70
71
72
73
74
75
# File 'lib/smith/trace.rb', line 66

def self.redact_value(value)
  case value
  when String
    "[REDACTED]"
  when Hash
    value.transform_values { |v| v.is_a?(String) ? "[REDACTED]" : v }
  else
    value
  end
end

.reset!Object



30
31
32
# File 'lib/smith/trace.rb', line 30

def self.reset!
  @adapter_instances = nil
end

.resolve_adapterObject



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/smith/trace.rb', line 18

def self.resolve_adapter
  configured = Smith.config.trace_adapter
  return nil unless configured

  if configured.is_a?(Class)
    @adapter_instances ||= {}
    @adapter_instances[configured] ||= configured.new
  else
    configured
  end
end