Class: ClaudeMemory::OTel::Attributes

Inherits:
Object
  • Object
show all
Defined in:
lib/claude_memory/otel/attributes.rb

Overview

Value object wrapping an OTel attribute hash (already flattened from the OTLP KeyValue representation by OtlpJsonEnvelope). Hides the primitive Hash from callers so panels and ingestors don’t reach into raw JSON keys.

All accessors return nil when the underlying attribute is missing. Frozen on construction — pass a fresh hash if you need to mutate.

Constant Summary collapse

PROMPT_CONTENT_KEYS =

OTel keys we treat as “captured prompt content”. Used by #contains_prompt_content? to flag privacy concerns regardless of which content flag was flipped (OTEL_LOG_USER_PROMPTS, OTEL_LOG_TOOL_CONTENT, OTEL_LOG_RAW_API_BODIES).

%w[
  prompt
  body
  tool_input
  tool.output
  full_command
  user_prompt
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash) ⇒ Attributes

Returns a new instance of Attributes.

Parameters:

  • hash (Hash)

    flattened attributes (string keys)



29
30
31
32
# File 'lib/claude_memory/otel/attributes.rb', line 29

def initialize(hash)
  @hash = (hash || {}).dup.freeze
  freeze
end

Class Method Details

.from_json(json_string) ⇒ Attributes

Parse a JSON string into Attributes. Returns Attributes wrapping an empty hash for nil, blank, or unparseable input — matches the tolerance the existing dashboard panels expect.

Parameters:

  • json_string (String, nil)

Returns:



40
41
42
43
44
45
# File 'lib/claude_memory/otel/attributes.rb', line 40

def self.from_json(json_string)
  return new({}) if json_string.nil? || json_string.empty?
  new(JSON.parse(json_string))
rescue JSON::ParserError
  new({})
end

.token_count(row) ⇒ Object

Token count carried on a token.usage data point.

Parameters:

  • row (Hash)

    otel_metrics row



88
89
90
# File 'lib/claude_memory/otel/attributes.rb', line 88

def self.token_count(row)
  (row[:value_int] || row[:value_float] || 0).to_i
end

Instance Method Details

#[](key) ⇒ Object



55
56
57
# File 'lib/claude_memory/otel/attributes.rb', line 55

def [](key)
  @hash[key.to_s]
end

#contains_prompt_content?Boolean

True when any attribute carries actual prompt or body content. Used by panels to render a one-line privacy notice without auto-flipping OTEL_LOG_USER_PROMPTS.

Returns:

  • (Boolean)


110
111
112
113
114
115
# File 'lib/claude_memory/otel/attributes.rb', line 110

def contains_prompt_content?
  PROMPT_CONTENT_KEYS.any? do |key|
    value = @hash[key]
    !value.nil? && !value.to_s.strip.empty?
  end
end

#duration_msInteger?

Tool execution duration in ms when the event is a tool_result.

Returns:

  • (Integer, nil)


94
95
96
97
# File 'lib/claude_memory/otel/attributes.rb', line 94

def duration_ms
  value = @hash["duration_ms"]
  value&.to_i
end

#modelObject

GenAI semconv canonical key + Claude Code’s ‘model` alias.



70
71
72
# File 'lib/claude_memory/otel/attributes.rb', line 70

def model
  @hash["gen_ai.request.model"] || @hash["model"]
end

#prompt_idObject

Claude Code attaches ‘prompt.id` to events that should be UNION’d into the prompt journey. See docs/claude_monitoring.md.



61
62
63
# File 'lib/claude_memory/otel/attributes.rb', line 61

def prompt_id
  @hash["prompt.id"] || @hash["prompt_id"]
end

#query_sourceObject



99
100
101
# File 'lib/claude_memory/otel/attributes.rb', line 99

def query_source
  @hash["query_source"]
end

#session_idObject



65
66
67
# File 'lib/claude_memory/otel/attributes.rb', line 65

def session_id
  @hash["session.id"] || @hash["session_id"]
end

#speedObject



103
104
105
# File 'lib/claude_memory/otel/attributes.rb', line 103

def speed
  @hash["speed"]
end

#to_hObject



47
48
49
# File 'lib/claude_memory/otel/attributes.rb', line 47

def to_h
  @hash
end

#to_json(*args) ⇒ Object



51
52
53
# File 'lib/claude_memory/otel/attributes.rb', line 51

def to_json(*args)
  @hash.to_json(*args)
end

#token_typeObject

Cost counter values arrive as the metric value, not as an attribute. The ‘type` attribute on token.usage tells us input/output/cacheRead/ cacheCreation; this is only useful for token rows. Returns nil when missing so callers can guard with #compact.



82
83
84
# File 'lib/claude_memory/otel/attributes.rb', line 82

def token_type
  @hash["type"]
end

#tool_nameObject



74
75
76
# File 'lib/claude_memory/otel/attributes.rb', line 74

def tool_name
  @hash["tool_name"]
end