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