relay_event_normalization/
statsd.rs

1use relay_statsd::{CounterMetric, TimerMetric};
2
3pub enum Counters {
4    /// Records the status of the AI cost calculation.
5    ///
6    /// The metric is tagged with:
7    ///  - `result`: The outcome of the cost calculation. Possible values are:
8    ///    `calculation_negative`,
9    ///    `calculation_zero`,
10    ///    `calculation_positive`,
11    ///    `calculation_no_tokens`
12    ///    `calculation_no_model_cost_available`
13    ///    `calculation_no_model_id_available`
14    ///  - `integration`: The integration used for the cost calculation.
15    ///  - `platform`: The platform used for the cost calculation.
16    GenAiCostCalculationResult,
17}
18
19impl CounterMetric for Counters {
20    fn name(&self) -> &'static str {
21        match *self {
22            Self::GenAiCostCalculationResult => "gen_ai.cost_calculation.result",
23        }
24    }
25}
26
27pub enum Timers {
28    /// Measures how log normalization of SQL queries in span description take.
29    ///
30    /// This metric is tagged with:
31    ///  - `mode`: The method used for normalization (either `parser` or `regex`).
32    SpanDescriptionNormalizeSQL,
33}
34
35impl TimerMetric for Timers {
36    fn name(&self) -> &'static str {
37        match *self {
38            Self::SpanDescriptionNormalizeSQL => "normalize.span.description.sql",
39        }
40    }
41}
42
43/// Maps a span origin to a well-known AI integration name for metrics.
44///
45/// Origins follow the pattern `auto.<integration>.<source>` or `auto.<category>.<protocol>.<source>`.
46/// This function extracts recognized AI integrations for cleaner metric tagging.
47pub fn map_origin_to_integration(origin: Option<&str>) -> &'static str {
48    match origin {
49        Some(o) if o.starts_with("auto.ai.openai_agents") => "openai_agents",
50        Some(o) if o.starts_with("auto.ai.openai") => "openai",
51        Some(o) if o.starts_with("auto.ai.anthropic") => "anthropic",
52        Some(o) if o.starts_with("auto.ai.cohere") => "cohere",
53        Some(o) if o.starts_with("auto.vercelai.") => "vercelai",
54        Some(o) if o.starts_with("auto.ai.langchain") => "langchain",
55        Some(o) if o.starts_with("auto.ai.langgraph") => "langgraph",
56        Some(o) if o.starts_with("auto.ai.google_genai") => "google_genai",
57        Some(o) if o.starts_with("auto.ai.pydantic_ai") => "pydantic_ai",
58        Some(o) if o.starts_with("auto.ai.huggingface_hub") => "huggingface_hub",
59        Some(o) if o.starts_with("auto.ai.litellm") => "litellm",
60        Some(o) if o.starts_with("auto.ai.mcp_server") => "mcp_server",
61        Some(o) if o.starts_with("auto.ai.mcp") => "mcp",
62        Some(o) if o.starts_with("auto.ai.claude_agent_sdk") => "claude_agent_sdk",
63        Some(o) if o.starts_with("auto.ai.laravel") => "laravel",
64        Some(o) if o.starts_with("auto.ai.") => "other_ai",
65        Some(o) if o.starts_with("manual") => "manual",
66        Some(_) => "other",
67        None => "unknown",
68    }
69}
70
71pub fn platform_tag(platform: Option<&str>) -> &'static str {
72    match platform {
73        Some("cocoa") => "cocoa",
74        Some("csharp") => "csharp",
75        Some("edge") => "edge",
76        Some("go") => "go",
77        Some("java") => "java",
78        Some("javascript") => "javascript",
79        Some("julia") => "julia",
80        Some("native") => "native",
81        Some("node") => "node",
82        Some("objc") => "objc",
83        Some("perl") => "perl",
84        Some("php") => "php",
85        Some("python") => "python",
86        Some("ruby") => "ruby",
87        Some("swift") => "swift",
88        Some(_) => "other",
89        None => "unknown",
90    }
91}