Skip to content

Commit 807f933

Browse files
committed
add fixed platforms and ai integrations
1 parent d49be0f commit 807f933

File tree

1 file changed

+64
-3
lines changed
  • relay-event-normalization/src/eap

1 file changed

+64
-3
lines changed

relay-event-normalization/src/eap/ai.rs

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,18 @@ pub fn normalize_ai(
3737
normalize_ai_type(attributes);
3838
let span_origin = attributes
3939
.get_value(ORIGIN)
40+
let platform = attributes
41+
.get_value(PLATFORM)
4042
.and_then(|v| v.as_str())
4143
.map(String::from);
4244
normalize_total_tokens(attributes);
4345
normalize_tokens_per_second(attributes, duration);
44-
normalize_ai_costs(attributes, costs, span_origin.as_deref());
46+
normalize_ai_costs(
47+
attributes,
48+
costs,
49+
span_origin.as_deref(),
50+
platform.as_deref(),
51+
);
4552
}
4653

4754
/// Returns whether the item is should have AI normalizations applied.
@@ -113,11 +120,60 @@ fn normalize_tokens_per_second(attributes: &mut Attributes, duration: Option<Dur
113120
}
114121
}
115122

123+
/// Maps a span origin to a well-known AI integration name for metrics.
124+
///
125+
/// Origins follow the pattern `auto.<integration>.<source>` or `auto.<category>.<protocol>.<source>`.
126+
/// This function extracts recognized AI integrations for cleaner metric tagging.
127+
fn map_origin_to_integration(origin: Option<&str>) -> &'static str {
128+
match origin {
129+
Some(o) if o.starts_with("auto.ai.openai") => "openai",
130+
Some(o) if o.starts_with("auto.ai.openai_agents") => "openai_agents",
131+
Some(o) if o.starts_with("auto.ai.anthropic") => "anthropic",
132+
Some(o) if o.starts_with("auto.ai.cohere") => "cohere",
133+
Some(o) if o.starts_with("auto.vercelai.") => "vercelai",
134+
Some(o) if o.starts_with("auto.ai.langchain") => "langchain",
135+
Some(o) if o.starts_with("auto.ai.langgraph") => "langgraph",
136+
Some(o) if o.starts_with("auto.ai.google_genai") => "google_genai",
137+
Some(o) if o.starts_with("auto.ai.pydantic_ai") => "pydantic_ai",
138+
Some(o) if o.starts_with("auto.ai.huggingface_hub") => "huggingface_hub",
139+
Some(o) if o.starts_with("auto.ai.litellm") => "litellm",
140+
Some(o) if o.starts_with("auto.ai.mcp") => "mcp",
141+
Some(o) if o.starts_with("auto.ai.mcp_server") => "mcp_server",
142+
Some(o) if o.starts_with("auto.ai.claude_agent_sdk") => "claude_agent_sdk",
143+
Some(o) if o.starts_with("auto.ai.") => "other",
144+
Some(_) => "other",
145+
None => "unknown",
146+
}
147+
}
148+
149+
fn platform_tag(platform: Option<&str>) -> &'static str {
150+
match platform {
151+
Some("cocoa") => "cocoa",
152+
Some("csharp") => "csharp",
153+
Some("edge") => "edge",
154+
Some("go") => "go",
155+
Some("java") => "java",
156+
Some("javascript") => "javascript",
157+
Some("julia") => "julia",
158+
Some("native") => "native",
159+
Some("node") => "node",
160+
Some("objc") => "objc",
161+
Some("perl") => "perl",
162+
Some("php") => "php",
163+
Some("python") => "python",
164+
Some("ruby") => "ruby",
165+
Some("swift") => "swift",
166+
Some(_) => "other",
167+
None => "unknown",
168+
}
169+
}
170+
116171
/// Calculates model costs and serializes them into attributes.
117172
fn normalize_ai_costs(
118173
attributes: &mut Attributes,
119174
model_costs: Option<&ModelCosts>,
120175
origin: Option<&str>,
176+
platform: Option<&str>,
121177
) {
122178
if attributes.contains_key(GEN_AI_COST_TOTAL_TOKENS) {
123179
return;
@@ -146,11 +202,15 @@ fn normalize_ai_costs(
146202
output_reasoning_tokens: get_tokens(GEN_AI_USAGE_OUTPUT_REASONING_TOKENS),
147203
};
148204

205+
let integration = map_origin_to_integration(origin);
206+
let platform = platform_tag(platform);
207+
149208
let Some(costs) = ai::calculate_costs(model_cost, tokens) else {
150209
relay_statsd::metric!(
151210
counter(Counters::GenAiCostCalculationResult) += 1,
152211
result = "calculation_none",
153-
origin = origin.unwrap_or("unknown"),
212+
integration = integration,
213+
platform = platform,
154214
);
155215

156216
return;
@@ -166,7 +226,8 @@ fn normalize_ai_costs(
166226
relay_statsd::metric!(
167227
counter(Counters::GenAiCostCalculationResult) += 1,
168228
result = metric_label,
169-
origin = origin.unwrap_or("unknown"),
229+
integration = integration,
230+
platform = platform,
170231
);
171232

172233
attributes.insert(GEN_AI_COST_INPUT_TOKENS, costs.input);

0 commit comments

Comments
 (0)