Skip to main content

relay_server/
statsd.rs

1use relay_statsd::{CounterMetric, DistributionMetric, GaugeMetric, TimerMetric};
2#[cfg(doc)]
3use relay_system::RuntimeMetrics;
4
5/// Gauge metrics used by Relay
6pub enum RelayGauges {
7    /// Tracks the number of futures waiting to be executed in the pool's queue.
8    ///
9    /// Useful for understanding the backlog of work and identifying potential bottlenecks.
10    ///
11    /// This metric is tagged with:
12    /// - `pool`: the name of the pool.
13    AsyncPoolQueueSize,
14    /// Tracks the utilization of the async pool.
15    ///
16    /// The utilization is a value between 0.0 and 100.0 which determines how busy the pool is doing
17    /// CPU-bound work.
18    ///
19    /// This metric is tagged with:
20    /// - `pool`: the name of the pool.
21    AsyncPoolUtilization,
22    /// Tracks the activity of the async pool.
23    ///
24    /// The activity is a value between 0.0 and 100.0 which determines how busy is the pool
25    /// w.r.t. to its provisioned capacity.
26    ///
27    /// This metric is tagged with:
28    /// - `pool`: the name of the pool.
29    AsyncPoolActivity,
30    /// The state of Relay with respect to the upstream connection.
31    /// Possible values are `0` for normal operations and `1` for a network outage.
32    NetworkOutage,
33    /// Number of elements in the envelope buffer across all the stacks.
34    ///
35    /// This metric is tagged with:
36    /// - `storage_type`: The type of storage used in the envelope buffer.
37    BufferEnvelopesCount,
38    /// The number of individual stacks in the priority queue.
39    ///
40    /// Per combination of `(own_key, sampling_key)`, a new stack is created.
41    BufferStackCount,
42    /// The used disk for the buffer.
43    BufferDiskUsed,
44    /// The currently used memory by the entire system.
45    ///
46    /// Relay uses the same value for its memory health check.
47    SystemMemoryUsed,
48    /// The total system memory.
49    ///
50    /// Relay uses the same value for its memory health check.
51    SystemMemoryTotal,
52    /// The number of connections currently being managed by the Redis Pool.
53    #[cfg(feature = "processing")]
54    RedisPoolConnections,
55    /// The number of idle connections in the Redis Pool.
56    #[cfg(feature = "processing")]
57    RedisPoolIdleConnections,
58    /// The maximum number of connections in the Redis pool.
59    #[cfg(feature = "processing")]
60    RedisPoolMaxConnections,
61    /// The number of futures waiting to grab a connection.
62    #[cfg(feature = "processing")]
63    RedisPoolWaitingForConnection,
64    /// The number of notifications in the broadcast channel of the project cache.
65    ProjectCacheNotificationChannel,
66    /// The number of scheduled and in progress fetches in the project cache.
67    ProjectCacheScheduledFetches,
68    /// Exposes the amount of currently open and handled connections by the server.
69    ServerActiveConnections,
70    /// Maximum delay of a metric bucket in seconds.
71    ///
72    /// The maximum is measured from initial creation of the bucket in an internal Relay
73    /// until it is produced to Kafka.
74    ///
75    /// This metric is tagged with:
76    /// - `namespace`: the metric namespace.
77    #[cfg(feature = "processing")]
78    MetricDelayMax,
79    /// Estimated percentage [0-100] of how busy Relay's internal services are.
80    ///
81    /// This metric is tagged with:
82    /// - `service`: the service name.
83    /// - `instance_id`: a for the service name unique identifier for the running service
84    ServiceUtilization,
85}
86
87impl GaugeMetric for RelayGauges {
88    fn name(&self) -> &'static str {
89        match self {
90            Self::AsyncPoolQueueSize => "async_pool.queue_size",
91            Self::AsyncPoolUtilization => "async_pool.utilization",
92            Self::AsyncPoolActivity => "async_pool.activity",
93            Self::NetworkOutage => "upstream.network_outage",
94            Self::BufferEnvelopesCount => "buffer.envelopes_count.gauge",
95            Self::BufferStackCount => "buffer.stack_count",
96            Self::BufferDiskUsed => "buffer.disk_used",
97            Self::SystemMemoryUsed => "health.system_memory.used",
98            Self::SystemMemoryTotal => "health.system_memory.total",
99            #[cfg(feature = "processing")]
100            Self::RedisPoolConnections => "redis.pool.connections",
101            #[cfg(feature = "processing")]
102            Self::RedisPoolIdleConnections => "redis.pool.idle_connections",
103            #[cfg(feature = "processing")]
104            Self::RedisPoolMaxConnections => "redis.pool.max_connections",
105            #[cfg(feature = "processing")]
106            Self::RedisPoolWaitingForConnection => "redis.pool.waiting_for_connection",
107            Self::ProjectCacheNotificationChannel => "project_cache.notification_channel.size",
108            Self::ProjectCacheScheduledFetches => "project_cache.fetches.size",
109            Self::ServerActiveConnections => "server.http.connections",
110            #[cfg(feature = "processing")]
111            Self::MetricDelayMax => "metrics.delay.max",
112            Self::ServiceUtilization => "service.utilization",
113        }
114    }
115}
116
117/// Gauge metrics collected from the Runtime.
118pub enum RuntimeGauges {
119    /// Exposes [`RuntimeMetrics::num_idle_threads`].
120    NumIdleThreads,
121    /// Exposes [`RuntimeMetrics::num_alive_tasks`].
122    NumAliveTasks,
123    /// Exposes [`RuntimeMetrics::blocking_queue_depth`].
124    BlockingQueueDepth,
125    /// Exposes [`RuntimeMetrics::num_blocking_threads`].
126    NumBlockingThreads,
127    /// Exposes [`RuntimeMetrics::num_idle_blocking_threads`].
128    NumIdleBlockingThreads,
129    /// Exposes [`RuntimeMetrics::num_workers`].
130    NumWorkers,
131    /// Exposes [`RuntimeMetrics::worker_local_queue_depth`].
132    ///
133    /// This metric is tagged with:
134    /// - `worker`: the worker id.
135    WorkerLocalQueueDepth,
136    /// Exposes [`RuntimeMetrics::worker_mean_poll_time`].
137    ///
138    /// This metric is tagged with:
139    /// - `worker`: the worker id.
140    WorkerMeanPollTime,
141}
142
143impl GaugeMetric for RuntimeGauges {
144    fn name(&self) -> &'static str {
145        match self {
146            RuntimeGauges::NumIdleThreads => "runtime.idle_threads",
147            RuntimeGauges::NumAliveTasks => "runtime.alive_tasks",
148            RuntimeGauges::BlockingQueueDepth => "runtime.blocking_queue_depth",
149            RuntimeGauges::NumBlockingThreads => "runtime.num_blocking_threads",
150            RuntimeGauges::NumIdleBlockingThreads => "runtime.num_idle_blocking_threads",
151            RuntimeGauges::NumWorkers => "runtime.num_workers",
152            RuntimeGauges::WorkerLocalQueueDepth => "runtime.worker_local_queue_depth",
153            RuntimeGauges::WorkerMeanPollTime => "runtime.worker_mean_poll_time",
154        }
155    }
156}
157
158/// Counter metrics collected from the Runtime.
159pub enum RuntimeCounters {
160    /// Exposes [`RuntimeMetrics::budget_forced_yield_count`].
161    BudgetForcedYieldCount,
162    /// Exposes [`RuntimeMetrics::worker_local_schedule_count`].
163    ///
164    /// This metric is tagged with:
165    /// - `worker`: the worker id.
166    WorkerLocalScheduleCount,
167    /// Exposes [`RuntimeMetrics::worker_noop_count`].
168    ///
169    /// This metric is tagged with:
170    /// - `worker`: the worker id.
171    WorkerNoopCount,
172    /// Exposes [`RuntimeMetrics::worker_overflow_count`].
173    ///
174    /// This metric is tagged with:
175    /// - `worker`: the worker id.
176    WorkerOverflowCount,
177    /// Exposes [`RuntimeMetrics::worker_park_count`].
178    ///
179    /// This metric is tagged with:
180    /// - `worker`: the worker id.
181    WorkerParkCount,
182    /// Exposes [`RuntimeMetrics::worker_poll_count`].
183    ///
184    /// This metric is tagged with:
185    /// - `worker`: the worker id.
186    WorkerPollCount,
187    /// Exposes [`RuntimeMetrics::worker_steal_count`].
188    ///
189    /// This metric is tagged with:
190    /// - `worker`: the worker id.
191    WorkerStealCount,
192    /// Exposes [`RuntimeMetrics::worker_steal_operations`].
193    ///
194    /// This metric is tagged with:
195    /// - `worker`: the worker id.
196    WorkerStealOperations,
197    /// Exposes [`RuntimeMetrics::worker_total_busy_duration`].
198    ///
199    /// This metric is tagged with:
200    /// - `worker`: the worker id.
201    WorkerTotalBusyDuration,
202}
203
204impl CounterMetric for RuntimeCounters {
205    fn name(&self) -> &'static str {
206        match self {
207            RuntimeCounters::BudgetForcedYieldCount => "runtime.budget_forced_yield_count",
208            RuntimeCounters::WorkerLocalScheduleCount => "runtime.worker_local_schedule_count",
209            RuntimeCounters::WorkerNoopCount => "runtime.worker_noop_count",
210            RuntimeCounters::WorkerOverflowCount => "runtime.worker_overflow_count",
211            RuntimeCounters::WorkerParkCount => "runtime.worker_park_count",
212            RuntimeCounters::WorkerPollCount => "runtime.worker_poll_count",
213            RuntimeCounters::WorkerStealCount => "runtime.worker_steal_count",
214            RuntimeCounters::WorkerStealOperations => "runtime.worker_steal_operations",
215            RuntimeCounters::WorkerTotalBusyDuration => "runtime.worker_total_busy_duration",
216        }
217    }
218}
219
220/// Histogram metrics used by Relay.
221pub enum RelayDistributions {
222    /// The number of bytes received by Relay for each individual envelope item type.
223    ///
224    /// This metric is tagged with:
225    ///  - `item_type`: The type of the items being counted.
226    ///  - `is_container`: Whether this item is a container holding multiple items.
227    EnvelopeItemSize,
228    /// The amount of bytes in the item payloads of an envelope pushed to the envelope buffer.
229    ///
230    /// This is not quite the same as the actual size of a serialized envelope, because it ignores
231    /// the envelope header and item headers.
232    BufferEnvelopeBodySize,
233    /// Size of a serialized envelope pushed to the envelope buffer.
234    BufferEnvelopeSize,
235    /// Size of a compressed envelope pushed to the envelope buffer.
236    BufferEnvelopeSizeCompressed,
237    /// The number of batches emitted per partition.
238    BatchesPerPartition,
239    /// The number of buckets in a batch emitted.
240    ///
241    /// This corresponds to the number of buckets that will end up in an envelope.
242    BucketsPerBatch,
243    /// The number of spans per processed transaction event.
244    ///
245    /// This metric is tagged with:
246    ///  - `platform`: The event's platform, such as `"javascript"`.
247    ///  - `sdk`: The name of the Sentry SDK sending the transaction. This tag is only set for
248    ///    Sentry's SDKs and defaults to "proprietary".
249    EventSpans,
250    /// Number of projects in the in-memory project cache that are waiting for their state to be
251    /// updated.
252    ///
253    /// See `project_cache.size` for more description of the project cache.
254    ProjectStatePending,
255    /// Number of project states **requested** from the upstream for each batch request.
256    ///
257    /// If multiple batches are updated concurrently, this metric is reported multiple times.
258    ///
259    /// The batch size can be configured with `cache.batch_size`. See `project_cache.size` for more
260    /// description of the project cache.
261    ProjectStateRequestBatchSize,
262    /// Number of project states **returned** from the upstream for each batch request.
263    ///
264    /// If multiple batches are updated concurrently, this metric is reported multiple times.
265    ///
266    /// See `project_cache.size` for more description of the project cache.
267    ProjectStateReceived,
268    /// Number of attempts required to fetch the config for a given project key.
269    ProjectStateAttempts,
270    /// Number of project states currently held in the in-memory project cache.
271    ///
272    /// The cache duration for project states can be configured with the following options:
273    ///
274    ///  - `cache.project_expiry`: The time after which a project state counts as expired. It is
275    ///    automatically refreshed if a request references the project after it has expired.
276    ///  - `cache.project_grace_period`: The time after expiry at which the project state will still
277    ///    be used to ingest events. Once the grace period expires, the cache is evicted and new
278    ///    requests wait for an update.
279    ///
280    /// There is no limit to the number of cached projects.
281    ProjectStateCacheSize,
282    /// The size of the compressed project config in the redis cache, in bytes.
283    #[cfg(feature = "processing")]
284    ProjectStateSizeBytesCompressed,
285    /// The size of the uncompressed project config in the redis cache, in bytes.
286    #[cfg(feature = "processing")]
287    ProjectStateSizeBytesDecompressed,
288    /// The number of upstream requests queued up for sending.
289    ///
290    /// Relay employs connection keep-alive whenever possible. Connections are kept open for _15_
291    /// seconds of inactivity or _75_ seconds of activity. If all connections are busy, they are
292    /// queued, which is reflected in this metric.
293    ///
294    /// This metric is tagged with:
295    ///  - `priority`: The queueing priority of the request, either `"high"` or `"low"`. The
296    ///    priority determines precedence in executing requests.
297    ///
298    /// The number of concurrent connections can be configured with:
299    ///  - `limits.max_concurrent_requests` for the overall number of connections
300    ///  - `limits.max_concurrent_queries` for the number of concurrent high-priority requests
301    UpstreamMessageQueueSize,
302    /// Counts the number of retries for each upstream http request.
303    ///
304    /// This metric is tagged with:
305    ///  - `result`: What happened to the request, an enumeration with the following values:
306    ///    * `success`: The request was sent and returned a success code `HTTP 2xx`
307    ///    * `response_error`: The request was sent and it returned an HTTP error.
308    ///    * `payload_failed`: The request was sent but there was an error in interpreting the response.
309    ///    * `send_failed`: Failed to send the request due to a network error.
310    ///    * `rate_limited`: The request was rate limited.
311    ///    * `invalid_json`: The response could not be parsed back into JSON.
312    ///  - `upstream`: The upstream the request is sent to.
313    ///  - `route`: The endpoint that was called on the upstream.
314    ///  - `status-code`: The status code of the request when available, otherwise "-".
315    UpstreamRetries,
316    /// Size of request bodies sent over HTTP in bytes.
317    ///
318    /// This does not include requests with streaming bodies.
319    ///
320    /// This metric is tagged with:
321    ///  - `upstream`: The upstream the request is sent to.
322    ///  - `route`: The endpoint that was called on the upstream.
323    UpstreamBodySize,
324    /// Distribution of flush buckets over partition keys.
325    ///
326    /// The distribution of buckets should be even.
327    /// If it is not, this metric should expose it.
328    PartitionKeys,
329    /// Measures how many splits were performed when sending out a partition.
330    PartitionSplits,
331    /// Canonical size of a Trace Item.
332    ///
333    /// This is not the size in bytes, this is using the same algorithm we're using for the logs
334    /// billing category.
335    ///
336    /// This metric is tagged with:
337    ///  - `item`: the trace item type.
338    ///  - `too_large`: `true` or `false`, whether the item is bigger than the allowed size limit.
339    TraceItemCanonicalSize,
340    /// The Content-Length of incoming HTTP requests in bytes.
341    ///
342    /// This metric is tagged with:
343    ///  - `has_content_length`: Whether the Content-Length header was present ("true"/"false").
344    ///  - `route`: The matched route pattern.
345    ///  - `status_code`: The HTTP response status code.
346    ContentLength,
347}
348
349impl DistributionMetric for RelayDistributions {
350    fn name(&self) -> &'static str {
351        match self {
352            Self::EnvelopeItemSize => "event.item_size",
353            Self::EventSpans => "event.spans",
354            Self::BatchesPerPartition => "metrics.buckets.batches_per_partition",
355            Self::BucketsPerBatch => "metrics.buckets.per_batch",
356            Self::BufferEnvelopeBodySize => "buffer.envelope_body_size",
357            Self::BufferEnvelopeSize => "buffer.envelope_size",
358            Self::BufferEnvelopeSizeCompressed => "buffer.envelope_size.compressed",
359            Self::ProjectStatePending => "project_state.pending",
360            Self::ProjectStateAttempts => "project_state.attempts",
361            Self::ProjectStateRequestBatchSize => "project_state.request.batch_size",
362            Self::ProjectStateReceived => "project_state.received",
363            Self::ProjectStateCacheSize => "project_cache.size",
364            #[cfg(feature = "processing")]
365            Self::ProjectStateSizeBytesCompressed => "project_state.size_bytes.compressed",
366            #[cfg(feature = "processing")]
367            Self::ProjectStateSizeBytesDecompressed => "project_state.size_bytes.decompressed",
368            Self::UpstreamMessageQueueSize => "http_queue.size",
369            Self::UpstreamRetries => "upstream.retries",
370            Self::UpstreamBodySize => "upstream.body_size",
371            Self::PartitionKeys => "metrics.buckets.partition_keys",
372            Self::PartitionSplits => "partition_splits",
373            Self::TraceItemCanonicalSize => "trace_item.canonical_size",
374            Self::ContentLength => "requests.content_length",
375        }
376    }
377}
378
379/// Timer metrics used by Relay
380pub enum RelayTimers {
381    /// Time in milliseconds spent deserializing an event from JSON bytes into the native data
382    /// structure on which Relay operates.
383    EventProcessingDeserialize,
384    /// Time in milliseconds spent running normalization on an event. Normalization
385    /// happens before envelope filtering and metric extraction.
386    EventProcessingNormalization,
387    /// Time in milliseconds spent running inbound data filters on an event.
388    EventProcessingFiltering,
389    /// Time in milliseconds spent checking for organization, project, and DSN rate limits.
390    ///
391    /// Not all events reach this point. After an event is rate limited for the first time, the rate
392    /// limit is cached. Events coming in after this will be discarded earlier in the request queue
393    /// and do not reach the processing queue.
394    ///
395    /// This metric is tagged with:
396    ///  - `type`: The type of limiter executed, `cached` or `consistent`.
397    ///  - `unit`: The item/unit of work which is being rate limited, only available for new
398    ///    processing pipelines.
399    EventProcessingRateLimiting,
400    /// Time in milliseconds spent in data scrubbing for the current event. Data scrubbing happens
401    /// last before serializing the event back to JSON.
402    EventProcessingPii,
403    /// Time spent converting the event from its in-memory reprsentation into a JSON string.
404    EventProcessingSerialization,
405    /// Time used to extract span metrics from an event.
406    EventProcessingSpanMetricsExtraction,
407    /// Time in milliseconds spent in each processor.
408    ///
409    /// This metric is tagged with:
410    ///  - `processor`: The processor executed.
411    EventProcessingProcess,
412    /// Time spent between the start of request handling and processing of the envelope.
413    ///
414    /// This includes streaming the request body, scheduling overheads, project config fetching,
415    /// batched requests and congestions in the internal processor. This does not include delays in
416    /// the incoming request (body upload) and skips all envelopes that are fast-rejected.
417    EnvelopeWaitTime,
418    /// Time in milliseconds spent in synchronous processing of envelopes.
419    ///
420    /// This timing covers the end-to-end processing in the CPU pool and comprises:
421    ///
422    ///  - `event_processing.deserialize`
423    ///  - `event_processing.pii`
424    ///  - `event_processing.serialization`
425    ///
426    /// With Relay in processing mode, this also includes the following timings:
427    ///
428    ///  - `event_processing.process`
429    ///  - `event_processing.filtering`
430    ///  - `event_processing.rate_limiting`
431    EnvelopeProcessingTime,
432    /// Total time in milliseconds an envelope spends in Relay from the time it is received until it
433    /// finishes processing and has been submitted to the upstream.
434    EnvelopeTotalTime,
435    /// Latency of project config updates until they reach Relay.
436    ///
437    /// The metric is calculated by using the creation timestamp of the project config
438    /// and when Relay updates its local cache with the new project config.
439    ///
440    /// No metric is emitted when Relay fetches a project config for the first time.
441    ///
442    /// This metric is tagged with:
443    ///  - `delay`: Bucketed amount of seconds passed between fetches.
444    ProjectCacheUpdateLatency,
445    /// Total time spent from starting to fetch a project config update to completing the fetch.
446    ProjectCacheFetchDuration,
447    /// Total time in milliseconds spent fetching queued project configuration updates requests to
448    /// resolve.
449    ///
450    /// Relay updates projects in batches. Every update cycle, Relay requests
451    /// `limits.max_concurrent_queries * cache.batch_size` projects from the upstream. This metric
452    /// measures the wall clock time for all concurrent requests in this loop.
453    ///
454    /// Note that after an update loop has completed, there may be more projects pending updates.
455    /// This is indicated by `project_state.pending`.
456    ProjectStateRequestDuration,
457    /// Time in milliseconds required to decompress a project config from redis.
458    ///
459    /// Note that this also times the cases where project config is uncompressed,
460    /// in which case the timer should be very close to zero.
461    #[cfg(feature = "processing")]
462    ProjectStateDecompression,
463    /// Total duration in milliseconds for handling inbound web requests until the HTTP response is
464    /// returned to the client.
465    ///
466    /// This does **not** correspond to the full event ingestion time. Requests for events that are
467    /// not immediately rejected due to bad data or cached rate limits always return `200 OK`. Full
468    /// validation and normalization occur asynchronously, which is reported by
469    /// `event.processing_time`.
470    ///
471    /// This metric is tagged with:
472    ///  - `method`: The HTTP method of the request.
473    ///  - `route`: Unique dashed identifier of the endpoint.
474    RequestsDuration,
475    /// Time spent on minidump scrubbing.
476    ///
477    /// This is the total time spent on parsing and scrubbing the minidump.
478    ///
479    /// This metric is tagged with:
480    ///
481    /// - `status`: Scrubbing status: "ok" means successful scrubbed, "error" means there
482    ///   was an error during scrubbing and finally "n/a" means scrubbing was successful
483    ///   but no scrubbing rules applied.
484    MinidumpScrubbing,
485    /// Time spent on view hierarchy scrubbing.
486    ///
487    /// This is the total time spent on parsing and scrubbing the view hierarchy json file.
488    ///
489    /// This metric is tagged with:
490    ///
491    /// - `status`: "ok" means successful scrubbed, "error" means there was an error during
492    ///   scrubbing. "n/a" means unchanged.
493    ViewHierarchyScrubbing,
494    /// Time spend on attachment scrubbing.
495    ///
496    /// This represents the total time spent on evaluating the scrubbing rules for an
497    /// attachment and the attachment scrubbing itself, regardless of whether any rules were
498    /// applied.  Note that minidumps which failed to be parsed (status="error" in
499    /// scrubbing.minidumps.duration) will be scrubbed as plain attachments and count
500    /// towards this.
501    ///
502    /// This metric is tagged with:
503    ///
504    ///   - `attachment_type`: The type of attachment, e.g. "minidump".
505    ///   - `status`: "ok" means successful scrubbed. "n/a" means not changed.
506    AttachmentScrubbing,
507    /// Total time spent to send request to upstream Relay and handle the response.
508    ///
509    /// This metric is tagged with:
510    ///
511    ///   - `result`: What happened to the request, an enumeration with the following values:
512    ///     * `success`: The request was sent and returned a success code `HTTP 2xx`
513    ///     * `response_error`: The request was sent and it returned an HTTP error.
514    ///     * `payload_failed`: The request was sent but there was an error in interpreting the response.
515    ///     * `send_failed`: Failed to send the request due to a network error.
516    ///     * `rate_limited`: The request was rate limited.
517    ///     * `invalid_json`: The response could not be parsed back into JSON.
518    ///   - `route`: The endpoint that was called on the upstream.
519    ///   - `status-code`: The status code of the request when available, otherwise "-".
520    ///   - `retries`: Number of retries bucket 0, 1, 2, few (3 - 10), many (more than 10).
521    UpstreamRequestsDuration,
522    /// The delay between the timestamp stated in a payload and the receive time.
523    ///
524    /// SDKs cannot transmit payloads immediately in all cases. Sometimes, crashes require that
525    /// events are sent after restarting the application. Similarly, SDKs buffer events during
526    /// network downtimes for later transmission. This metric measures the delay between the time of
527    /// the event and the time it arrives in Relay. The delay is measured after clock drift
528    /// correction is applied.
529    ///
530    /// Only payloads with a delay of more than 1 minute are captured.
531    ///
532    /// This metric is tagged with:
533    ///
534    ///  - `category`: The data category of the payload. Can be one of: `event`, `transaction`,
535    ///    `security`, or `session`.
536    TimestampDelay,
537    /// Time in milliseconds spent on parsing, normalizing and scrubbing replay recordings.
538    ReplayRecordingProcessing,
539    /// Total time spent to send a request and receive the response from upstream.
540    GlobalConfigRequestDuration,
541    /// Timing in milliseconds for processing a message in the internal CPU pool.
542    ///
543    /// This metric is tagged with:
544    ///
545    ///  - `message`: The type of message that was processed.
546    ProcessMessageDuration,
547    /// Timing in milliseconds for processing a task in the project cache service.
548    ///
549    /// This metric is tagged with:
550    /// - `task`: The type of the task the project cache does.
551    ProjectCacheTaskDuration,
552    /// Timing in milliseconds for awaiting a loaded project state.
553    ///
554    /// This metric is tagged with:
555    /// - `result`: Outcome of the fetch.
556    ProjectStateReadyDuration,
557    /// Timing in milliseconds for handling and responding to a health check request.
558    ///
559    /// This metric is tagged with:
560    ///  - `type`: The type of the health check, `liveness` or `readiness`.
561    HealthCheckDuration,
562    /// Temporary timing metric for how much time was spent evaluating span and transaction
563    /// rate limits using the `RateLimitBuckets` message in the processor.
564    ///
565    /// This metric is tagged with:
566    ///  - `category`: The data category evaluated.
567    ///  - `limited`: Whether the batch is rate limited.
568    ///  - `count`: How many items matching the data category are contained in the batch.
569    #[cfg(feature = "processing")]
570    RateLimitBucketsDuration,
571    /// Timing in milliseconds for processing a task in the aggregator service.
572    ///
573    /// This metric is tagged with:
574    ///  - `task`: The task being executed by the aggregator.
575    ///  - `aggregator`: The name of the aggregator.
576    AggregatorServiceDuration,
577    /// Timing in milliseconds for processing a message in the metric router service.
578    ///
579    /// This metric is tagged with:
580    ///  - `message`: The type of message that was processed.
581    MetricRouterServiceDuration,
582    /// Timing in milliseconds for processing a message in the metric store service.
583    ///
584    /// This metric is tagged with:
585    ///  - `message`: The type of message that was processed.
586    #[cfg(feature = "processing")]
587    StoreServiceDuration,
588    /// Timing in milliseconds for the time it takes for initialize the buffer.
589    BufferInitialization,
590    /// Timing in milliseconds for the time it takes for the buffer to pack & spool a batch.
591    ///
592    /// Contains the time it takes to pack multiple envelopes into a single memory blob.
593    BufferSpool,
594    /// Timing in milliseconds for the time it takes for the buffer to spool data to SQLite.
595    BufferSqlWrite,
596    /// Timing in milliseconds for the time it takes for the buffer to unspool data from disk.
597    BufferUnspool,
598    /// Timing in milliseconds for the time it takes for the buffer to push.
599    BufferPush,
600    /// Timing in milliseconds for the time it takes for the buffer to peek.
601    BufferPeek,
602    /// Timing in milliseconds for the time it takes for the buffer to pop.
603    BufferPop,
604    /// Timing in milliseconds for the time it takes for the buffer to drain its envelopes.
605    BufferDrain,
606    /// Timing in milliseconds for the time it takes for an envelope to be serialized.
607    BufferEnvelopesSerialization,
608    /// Timing in milliseconds for the time it takes for an envelope to be compressed.
609    BufferEnvelopeCompression,
610    /// Timing in milliseconds for the time it takes for an envelope to be decompressed.
611    BufferEnvelopeDecompression,
612    /// Timing in milliseconds to count spans in a serialized transaction payload.
613    CheckNestedSpans,
614    /// The time it needs to create a signature. Includes both the signature used for
615    /// trusted relays and for register challenges.
616    SignatureCreationDuration,
617    /// Time needed to upload an attachment to objectstore.
618    ///
619    /// This metric measures the duration of a download attempt.
620    /// Every retry contributes to the metric individually.
621    ///
622    /// Tagged by:
623    /// - `type`: "envelope" or "attachment_v2".
624    #[cfg(feature = "processing")]
625    AttachmentUploadDuration,
626
627    /// Time spent waiting for the producer of an async stream.
628    ///
629    /// Tagged by:
630    /// - `name`: Name of the stream, for example "upload".
631    StreamProducerLatency,
632    /// Time spent waiting for the consumer of an async stream.
633    ///
634    /// Tagged by:
635    /// - `name`: Name of the stream, for example "upload".
636    StreamConsumerLatency,
637}
638
639impl TimerMetric for RelayTimers {
640    fn name(&self) -> &'static str {
641        match self {
642            RelayTimers::EventProcessingDeserialize => "event_processing.deserialize",
643            RelayTimers::EventProcessingNormalization => "event_processing.normalization",
644            RelayTimers::EventProcessingFiltering => "event_processing.filtering",
645            RelayTimers::EventProcessingRateLimiting => "event_processing.rate_limiting",
646            RelayTimers::EventProcessingPii => "event_processing.pii",
647            RelayTimers::EventProcessingSpanMetricsExtraction => {
648                "event_processing.span_metrics_extraction"
649            }
650            RelayTimers::EventProcessingSerialization => "event_processing.serialization",
651            RelayTimers::EventProcessingProcess => "event_processing.process",
652            RelayTimers::EnvelopeWaitTime => "event.wait_time",
653            RelayTimers::EnvelopeProcessingTime => "event.processing_time",
654            RelayTimers::EnvelopeTotalTime => "event.total_time",
655            RelayTimers::ProjectStateRequestDuration => "project_state.request.duration",
656            #[cfg(feature = "processing")]
657            RelayTimers::ProjectStateDecompression => "project_state.decompression",
658            RelayTimers::ProjectCacheUpdateLatency => "project_cache.latency",
659            RelayTimers::ProjectCacheFetchDuration => "project_cache.fetch.duration",
660            RelayTimers::ProjectStateReadyDuration => "project_state.ready",
661            RelayTimers::RequestsDuration => "requests.duration",
662            RelayTimers::MinidumpScrubbing => "scrubbing.minidumps.duration",
663            RelayTimers::ViewHierarchyScrubbing => "scrubbing.view_hierarchy_scrubbing.duration",
664            RelayTimers::AttachmentScrubbing => "scrubbing.attachments.duration",
665            RelayTimers::UpstreamRequestsDuration => "upstream.requests.duration",
666            RelayTimers::TimestampDelay => "requests.timestamp_delay",
667            RelayTimers::ReplayRecordingProcessing => "replay.recording.process",
668            RelayTimers::GlobalConfigRequestDuration => "global_config.requests.duration",
669            RelayTimers::ProcessMessageDuration => "processor.message.duration",
670            RelayTimers::ProjectCacheTaskDuration => "project_cache.task.duration",
671            RelayTimers::HealthCheckDuration => "health.message.duration",
672            #[cfg(feature = "processing")]
673            RelayTimers::RateLimitBucketsDuration => "processor.rate_limit_buckets",
674            RelayTimers::AggregatorServiceDuration => "metrics.aggregator.message.duration",
675            RelayTimers::MetricRouterServiceDuration => "metrics.router.message.duration",
676            #[cfg(feature = "processing")]
677            RelayTimers::StoreServiceDuration => "store.message.duration",
678            RelayTimers::BufferInitialization => "buffer.initialization.duration",
679            RelayTimers::BufferSpool => "buffer.spool.duration",
680            RelayTimers::BufferSqlWrite => "buffer.write.duration",
681            RelayTimers::BufferUnspool => "buffer.unspool.duration",
682            RelayTimers::BufferPush => "buffer.push.duration",
683            RelayTimers::BufferPeek => "buffer.peek.duration",
684            RelayTimers::BufferPop => "buffer.pop.duration",
685            RelayTimers::BufferDrain => "buffer.drain.duration",
686            RelayTimers::BufferEnvelopesSerialization => "buffer.envelopes_serialization",
687            RelayTimers::BufferEnvelopeCompression => "buffer.envelopes_compression",
688            RelayTimers::BufferEnvelopeDecompression => "buffer.envelopes_decompression",
689            RelayTimers::CheckNestedSpans => "envelope.check_nested_spans",
690            RelayTimers::SignatureCreationDuration => "signature.create.duration",
691            #[cfg(feature = "processing")]
692            RelayTimers::AttachmentUploadDuration => "attachment.upload.duration",
693            RelayTimers::StreamProducerLatency => "stream.producer.latency",
694            RelayTimers::StreamConsumerLatency => "stream.consumer.latency",
695        }
696    }
697}
698
699/// Counter metrics used by Relay
700pub enum RelayCounters {
701    /// Amount of times the configuration was reloaded.
702    ConfigReload,
703    /// Tracks the number of tasks driven to completion by the async pool.
704    ///
705    /// This metric is tagged with:
706    /// - `pool`: the name of the pool.
707    AsyncPoolFinishedTasks,
708    /// Number of Events that had corrupted (unprintable) event attributes.
709    ///
710    /// This currently checks for `environment` and `release`, for which we know that
711    /// some SDKs may send corrupted values.
712    EventCorrupted,
713    /// Number of envelopes accepted in the current time slot.
714    ///
715    /// This represents requests that have successfully passed rate limits and filters, and have
716    /// been sent to the upstream.
717    ///
718    /// This metric is tagged with:
719    ///  - `handling`: Either `"success"` if the envelope was handled correctly, or `"failure"` if
720    ///    there was an error or bug.
721    EnvelopeAccepted,
722    /// Number of envelopes rejected in the current time slot.
723    ///
724    /// This includes envelopes being rejected because they are malformed or any other errors during
725    /// processing (including filtered events, invalid payloads, and rate limits).
726    ///
727    /// To check the rejection reason, check `events.outcomes`, instead.
728    ///
729    /// This metric is tagged with:
730    ///  - `handling`: Either `"success"` if the envelope was handled correctly, or `"failure"` if
731    ///    there was an error or bug.
732    EnvelopeRejected,
733    /// Number of total envelope items we received.
734    ///
735    /// Note: This does not count raw items, it counts the logical amount of items,
736    /// e.g. a single item container counts all its contained items.
737    ///
738    /// This metric is tagged with:
739    ///  - `item_type`: The type of the items being counted.
740    ///  - `is_container`: Whether this item is a container holding multiple items.
741    ///  - `sdk`: The name of the Sentry SDK sending the envelope. This tag is only set for
742    ///    Sentry's SDKs and defaults to "proprietary".
743    EnvelopeItems,
744    /// Number of bytes we processed per envelope item.
745    ///
746    /// This metric is tagged with:
747    ///  - `item_type`: The type of the items being counted.
748    ///  - `is_container`: Whether this item is a container holding multiple items.
749    ///  - `sdk`: The name of the Sentry SDK sending the envelope. This tag is only set for
750    ///    Sentry's SDKs and defaults to "proprietary".
751    EnvelopeItemBytes,
752    /// Number of envelopes rejected because of size limits.
753    ///
754    /// This metric is tagged with:
755    ///  - `item`: The type of the items being counted.
756    ///  - `limit`: Which limit was breached.
757    EnvelopeSizeLimited,
758    /// Number of times an envelope from the buffer is trying to be popped.
759    BufferTryPop,
760    /// Number of envelopes spool to disk.
761    BufferSpooledEnvelopes,
762    /// Number of envelopes unspooled from disk.
763    BufferUnspooledEnvelopes,
764    /// Number of project changed updates received by the buffer.
765    BufferProjectChangedEvent,
766    /// Number of times one or more projects of an envelope were pending when trying to pop
767    /// their envelope.
768    BufferProjectPending,
769    /// Number of iterations of the envelope buffer service loop.
770    BufferServiceLoopIteration,
771    /// Number of outcomes and reasons for rejected Envelopes.
772    ///
773    /// This metric is tagged with:
774    ///  - `outcome`: The basic cause for rejecting the event.
775    ///  - `reason`: A more detailed identifier describing the rule or mechanism leading to the
776    ///    outcome.
777    ///  - `to`: Describes the destination of the outcome. Can be either 'kafka' (when in
778    ///    processing mode) or 'http' (when outcomes are enabled in an external relay).
779    ///
780    /// Possible outcomes are:
781    ///  - `filtered`: Dropped by inbound data filters. The reason specifies the filter that
782    ///    matched.
783    ///  - `rate_limited`: Dropped by organization, project, or DSN rate limit, as well as exceeding
784    ///    the Sentry plan quota. The reason contains the rate limit or quota that was exceeded.
785    ///  - `invalid`: Data was considered invalid and could not be recovered. The reason indicates
786    ///    the validation that failed.
787    Outcomes,
788    /// The number of individual outcomes including their quantity.
789    ///
790    /// While [`RelayCounters::Outcomes`] tracks the number of times aggregated outcomes
791    /// have been emitted, this counter tracks the total quantity of individual outcomes.
792    OutcomeQuantity,
793    /// Number of project state HTTP requests.
794    ///
795    /// Relay updates projects in batches. Every update cycle, Relay requests
796    /// `limits.max_concurrent_queries` batches of `cache.batch_size` projects from the upstream.
797    /// The duration of these requests is reported via `project_state.request.duration`.
798    ///
799    /// Note that after an update loop has completed, there may be more projects pending updates.
800    /// This is indicated by `project_state.pending`.
801    ProjectStateRequest,
802    /// Number of times a project state is requested from the central Redis cache.
803    ///
804    /// This metric is tagged with:
805    ///  - `hit`: One of:
806    ///     - `revision`: the cached version was validated to be up to date using its revision.
807    ///     - `project_config`: the request was handled by the cache.
808    ///     - `project_config_revision`: the request was handled by the cache and the revision did
809    ///       not change.
810    ///     - `false`: the request will be sent to the sentry endpoint.
811    #[cfg(feature = "processing")]
812    ProjectStateRedis,
813    /// Number of times a project had a fetch scheduled.
814    ProjectCacheSchedule,
815    /// Number of times an upstream request for a project config is completed.
816    ///
817    /// Completion can be because a result was returned or because the config request was
818    /// dropped after there still was no response after a timeout.  This metrics has tags
819    /// for `result` and `attempts` indicating whether it was succesful or a timeout and how
820    /// many attempts were made respectively.
821    ProjectUpstreamCompleted,
822    /// Number of times an upstream request for a project config failed.
823    ///
824    /// Failure can happen, for example, when there's a network error. Refer to
825    /// [`UpstreamRequestError`](crate::services::upstream::UpstreamRequestError) for all cases.
826    ProjectUpstreamFailed,
827    /// Number of Relay server starts.
828    ///
829    /// This can be used to track unwanted restarts due to crashes or termination.
830    ServerStarting,
831    /// Number of messages placed on the Kafka queues.
832    ///
833    /// When Relay operates as Sentry service and an Envelope item is successfully processed, each
834    /// Envelope item results in a dedicated message on one of the ingestion topics on Kafka.
835    ///
836    /// This metric is tagged with:
837    ///  - `event_type`: The kind of message produced to Kafka.
838    ///  - `namespace` (only for metrics): The namespace that the metric belongs to.
839    ///  - `is_segment` (only for event_type span): `true` the span is the root of a segment.
840    ///  - `has_parent` (only for event_type span): `false` if the span is the root of a trace.
841    ///  - `platform` (only for event_type span): The platform from which the span was spent.
842    ///  - `metric_type` (only for event_type metric): The metric type, counter, distribution,
843    ///    gauge or set.
844    ///  - `metric_encoding` (only for event_type metric): The encoding used for distribution and
845    ///    set metrics.
846    ///
847    /// The message types can be:
848    ///
849    ///  - `event`: An error or transaction event. Error events are sent to `ingest-events`,
850    ///    transactions to `ingest-transactions`, and errors with attachments are sent to
851    ///    `ingest-attachments`.
852    ///  - `attachment`: An attachment file associated with an error event, sent to
853    ///    `ingest-attachments`.
854    ///  - `user_report`: A message from the user feedback dialog, sent to `ingest-events`.
855    ///  - `session`: A release health session update, sent to `ingest-sessions`.
856    #[cfg(feature = "processing")]
857    ProcessingMessageEnqueued,
858    /// Number of spans produced in the new format.
859    #[cfg(feature = "processing")]
860    SpanV2Produced,
861    /// Number of events that hit any of the store-like endpoints: Envelope, Store, Security,
862    /// Minidump, Unreal.
863    ///
864    /// The events are counted before they are rate limited, filtered, or processed in any way.
865    ///
866    /// This metric is tagged with:
867    ///  - `version`: The event protocol version number defaulting to `7`.
868    EventProtocol,
869    /// The number of transaction events processed by the source of the transaction name.
870    ///
871    /// This metric is tagged with:
872    ///  - `platform`: The event's platform, such as `"javascript"`.
873    ///  - `source`: The source of the transaction name on the client. See the [transaction source
874    ///    documentation](https://develop.sentry.dev/sdk/event-payloads/properties/transaction_info/)
875    ///    for all valid values.
876    ///  - `contains_slashes`: Whether the transaction name contains `/`. We use this as a heuristic
877    ///    to represent URL transactions.
878    EventTransaction,
879    /// The number of transaction events processed grouped by transaction name modifications.
880    /// This metric is tagged with:
881    ///  - `source_in`: The source of the transaction name before normalization.
882    ///    See the [transaction source
883    ///    documentation](https://develop.sentry.dev/sdk/event-payloads/properties/transaction_info/)
884    ///    for all valid values.
885    ///  - `change`: The mechanism that changed the transaction name.
886    ///    Either `"none"`, `"pattern"`, `"rule"`, or `"both"`.
887    ///  - `source_out`: The source of the transaction name after normalization.
888    TransactionNameChanges,
889    /// Number of HTTP requests reaching Relay.
890    Requests,
891    /// Number of completed HTTP requests.
892    ///
893    /// This metric is tagged with:
894    ///
895    ///  - `status_code`: The HTTP status code number.
896    ///  - `method`: The HTTP method used in the request in uppercase.
897    ///  - `route`: Unique dashed identifier of the endpoint.
898    ResponsesStatusCodes,
899    /// Number of evicted stale projects from the cache.
900    ///
901    /// Relay scans the in-memory project cache for stale entries in a regular interval configured
902    /// by `cache.eviction_interval`.
903    ///
904    /// The cache duration for project states can be configured with the following options:
905    ///
906    ///  - `cache.project_expiry`: The time after which a project state counts as expired. It is
907    ///    automatically refreshed if a request references the project after it has expired.
908    ///  - `cache.project_grace_period`: The time after expiry at which the project state will still
909    ///    be used to ingest events. Once the grace period expires, the cache is evicted and new
910    ///    requests wait for an update.
911    EvictingStaleProjectCaches,
912    /// Number of refreshes for stale projects in the cache.
913    RefreshStaleProjectCaches,
914    /// Number of times that parsing a metrics bucket item from an envelope failed.
915    MetricBucketsParsingFailed,
916    /// Number of Events with an OpenTelemetry Context
917    ///
918    /// This metric is tagged with:
919    ///  - `platform`: The event's platform, such as `"javascript"`.
920    ///  - `sdk`: The name of the Sentry SDK sending the transaction. This tag is only set for
921    ///    Sentry's SDKs and defaults to "proprietary".
922    OpenTelemetryEvent,
923    /// Number of global config fetches from upstream. Only 2XX responses are
924    /// considered and ignores send errors (e.g. auth or network errors).
925    ///
926    /// This metric is tagged with:
927    ///  - `success`: whether deserializing the global config succeeded.
928    GlobalConfigFetched,
929    /// The number of attachments processed in the same envelope as a user_report_v2 event.
930    FeedbackAttachments,
931    /// All COGS tracked values.
932    ///
933    /// This metric is tagged with:
934    /// - `resource_id`: The COGS resource id.
935    /// - `app_feature`: The COGS app feature.
936    CogsUsage,
937    /// The amount of times metrics of a project have been flushed without the project being
938    /// fetched/available.
939    ProjectStateFlushMetricsNoProject,
940    /// Incremented every time a bucket is dropped.
941    ///
942    /// This should only happen when a project state is invalid during graceful shutdown.
943    ///
944    /// This metric is tagged with:
945    ///  - `aggregator`: The name of the metrics aggregator (usually `"default"`).
946    BucketsDropped,
947    /// Incremented every time a segment exceeds the expected limit.
948    ReplayExceededSegmentLimit,
949    /// Incremented every time the server accepts a new connection.
950    ServerSocketAccept,
951    /// Incremented every time the server aborts a connection because of an idle timeout.
952    ServerConnectionIdleTimeout,
953    /// The total delay of metric buckets in seconds.
954    ///
955    /// The delay is measured from initial creation of the bucket in an internal Relay
956    /// until it is produced to Kafka.
957    ///
958    /// Use [`Self::MetricDelayCount`] to calculate the average delay.
959    ///
960    /// This metric is tagged with:
961    /// - `namespace`: the metric namespace.
962    #[cfg(feature = "processing")]
963    MetricDelaySum,
964    /// The amount of buckets counted for the [`Self::MetricDelaySum`] metric.
965    ///
966    /// This metric is tagged with:
967    /// - `namespace`: the metric namespace.
968    #[cfg(feature = "processing")]
969    MetricDelayCount,
970    /// The amount of times PlayStation processing was attempted.
971    #[cfg(all(sentry, feature = "processing"))]
972    PlaystationProcessing,
973    /// The number of times the sampling project was unresolved.
974    ///
975    /// This metric is tagged with:
976    /// - `item`: what item the decision is taken for (transaction vs span).
977    SamplingProjectUnresolved,
978    /// The number of times a sampling decision was made.
979    ///
980    /// This metric is tagged with:
981    /// - `item`: what item the decision is taken for (transaction vs span).
982    SamplingDecision,
983    /// How often a call to the upload endpoint was rejected because of the global kill switch.
984    ///
985    /// This is intended as a temporary metric to debug 503 flakiness.
986    UploadKillswitched,
987    /// The number of times an upload location is created through the upload service.
988    ///
989    /// This metric is tagged with:
990    /// - `result`: `success` or the failure reason.
991    UploadCreate,
992    /// The number of times an upload location is created through the upload service.
993    ///
994    /// This metric is tagged with:
995    /// - `result`: `success` or the failure reason.
996    UploadUpload,
997    /// The number of times an objectstore upload of an attachment occurs.
998    ///
999    /// This metric is tagged with:
1000    /// - `result`: `success` or the failure reason.
1001    /// - `type`: `envelope` or `attachment_v2`
1002    #[cfg(feature = "processing")]
1003    AttachmentUpload,
1004    /// Whether a logs envelope has a trace context header or not
1005    ///
1006    /// This metric is tagged with:
1007    /// - `dsc`: yes or no
1008    /// - `sdk`: low-cardinality client name
1009    EnvelopeWithLogs,
1010    /// Amount of profile chunks without a platform item header.
1011    ///
1012    /// The metric is emitted when processing profile chunks, profile chunks which are fast path
1013    /// rate limited are not counted in this metric.
1014    ProfileChunksWithoutPlatform,
1015    /// Amount of errors have been processed by the error processing pipeline.
1016    ///
1017    /// This metric is tagged with:
1018    /// - `expansion`: What expansion was used to expand the error (e.g. unreal).
1019    ErrorProcessed,
1020    /// The number of times a trace metric has a nil trace ID.
1021    ///
1022    /// This metric is tagged with:
1023    /// - `sdk`: low-cardinality client name
1024    TraceMetricNilTraceId,
1025    /// Amount of standalone attachments processed.
1026    ///
1027    /// This metric is tagged with:
1028    /// - `sdk`: low-cardinality client name
1029    /// - `has_event_id`: whether the envelope contained an event ID
1030    StandaloneAttachment,
1031    /// Amount of user reports processed.
1032    ///
1033    /// This metric is tagged with:
1034    /// - `sdk`: low-cardinality client name
1035    /// - `has_event_id`: whether the envelope contained an event ID
1036    UserReport,
1037    /// Amount of replays processed.
1038    ///
1039    /// This metric is tagged with:
1040    /// - `sdk`: low-cardinality client name
1041    /// - `has_event_id`: whether the envelope contained an event ID
1042    Replay,
1043}
1044
1045impl CounterMetric for RelayCounters {
1046    fn name(&self) -> &'static str {
1047        match self {
1048            RelayCounters::ConfigReload => "config.reload",
1049            RelayCounters::AsyncPoolFinishedTasks => "async_pool.finished_tasks",
1050            RelayCounters::EventCorrupted => "event.corrupted",
1051            RelayCounters::EnvelopeAccepted => "event.accepted",
1052            RelayCounters::EnvelopeRejected => "event.rejected",
1053            RelayCounters::EnvelopeItems => "event.items",
1054            RelayCounters::EnvelopeItemBytes => "event.item_bytes",
1055            RelayCounters::EnvelopeSizeLimited => "envelope.rejected.size",
1056            RelayCounters::BufferTryPop => "buffer.try_pop",
1057            RelayCounters::BufferSpooledEnvelopes => "buffer.spooled_envelopes",
1058            RelayCounters::BufferUnspooledEnvelopes => "buffer.unspooled_envelopes",
1059            RelayCounters::BufferProjectChangedEvent => "buffer.project_changed_event",
1060            RelayCounters::BufferProjectPending => "buffer.project_pending",
1061            RelayCounters::BufferServiceLoopIteration => "buffer.service_loop_iteration",
1062            RelayCounters::Outcomes => "events.outcomes",
1063            RelayCounters::OutcomeQuantity => "events.outcome_quantity",
1064            RelayCounters::ProjectStateRequest => "project_state.request",
1065            #[cfg(feature = "processing")]
1066            RelayCounters::ProjectStateRedis => "project_state.redis.requests",
1067            RelayCounters::ProjectUpstreamCompleted => "project_upstream.completed",
1068            RelayCounters::ProjectUpstreamFailed => "project_upstream.failed",
1069            RelayCounters::ProjectCacheSchedule => "project_cache.schedule",
1070            RelayCounters::ServerStarting => "server.starting",
1071            #[cfg(feature = "processing")]
1072            RelayCounters::ProcessingMessageEnqueued => "processing.event.enqueued",
1073            #[cfg(feature = "processing")]
1074            RelayCounters::SpanV2Produced => "store.produced.span_v2",
1075            RelayCounters::EventProtocol => "event.protocol",
1076            RelayCounters::EventTransaction => "event.transaction",
1077            RelayCounters::TransactionNameChanges => "event.transaction_name_changes",
1078            RelayCounters::Requests => "requests",
1079            RelayCounters::ResponsesStatusCodes => "responses.status_codes",
1080            RelayCounters::EvictingStaleProjectCaches => "project_cache.eviction",
1081            RelayCounters::RefreshStaleProjectCaches => "project_cache.refresh",
1082            RelayCounters::MetricBucketsParsingFailed => "metrics.buckets.parsing_failed",
1083            RelayCounters::OpenTelemetryEvent => "event.opentelemetry",
1084            RelayCounters::GlobalConfigFetched => "global_config.fetch",
1085            RelayCounters::FeedbackAttachments => "processing.feedback_attachments",
1086            RelayCounters::CogsUsage => "cogs.usage",
1087            RelayCounters::ProjectStateFlushMetricsNoProject => "project_state.metrics.no_project",
1088            RelayCounters::BucketsDropped => "metrics.buckets.dropped",
1089            RelayCounters::ReplayExceededSegmentLimit => "replay.segment_limit_exceeded",
1090            RelayCounters::ServerSocketAccept => "server.http.accepted",
1091            RelayCounters::ServerConnectionIdleTimeout => "server.http.idle_timeout",
1092            #[cfg(feature = "processing")]
1093            RelayCounters::MetricDelaySum => "metrics.delay.sum",
1094            #[cfg(feature = "processing")]
1095            RelayCounters::MetricDelayCount => "metrics.delay.count",
1096            #[cfg(all(sentry, feature = "processing"))]
1097            RelayCounters::PlaystationProcessing => "processing.playstation",
1098            RelayCounters::SamplingProjectUnresolved => "sampling.project_unresolved",
1099            RelayCounters::SamplingDecision => "sampling.decision",
1100            RelayCounters::UploadKillswitched => "upload.killswitched",
1101            RelayCounters::UploadCreate => "upload.create",
1102            RelayCounters::UploadUpload => "upload.upload",
1103            #[cfg(feature = "processing")]
1104            RelayCounters::AttachmentUpload => "attachment.upload",
1105            RelayCounters::EnvelopeWithLogs => "logs.envelope",
1106            RelayCounters::ProfileChunksWithoutPlatform => "profile_chunk.no_platform",
1107            RelayCounters::ErrorProcessed => "event.error.processed",
1108            RelayCounters::TraceMetricNilTraceId => "trace_metric.nil_trace_id",
1109            RelayCounters::StandaloneAttachment => "processing.standalone_attachment",
1110            RelayCounters::UserReport => "processing.user_report",
1111            RelayCounters::Replay => "processing.replay",
1112        }
1113    }
1114}