{"data":{"allRelayMetric":{"nodes":[{"name":"connector.closed","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of upstream connections closed due to connection timeouts.</p>\n<p>Relay employs connection keep-alive whenever possible. Connections are kept open for <em>15</em>\nseconds of inactivity or <em>75</em> seconds of activity.</p>"}}},{"name":"connector.errors","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of upstream connections that experienced errors.</p>"}}},{"name":"connector.opened","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of upstream connections opened.</p>"}}},{"name":"connector.reused","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of requests that reused an already open upstream connection.</p>\n<p>Relay employs connection keep-alive whenever possible. Connections are kept open for <em>15</em>\nseconds of inactivity or <em>75</em> seconds of activity.</p>"}}},{"name":"connector.timeouts","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of upstream connections that experienced a timeout.</p>"}}},{"name":"connector.wait_queue","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>The number of upstream requests queued up for a connection in the connection pool.</p>\n<p>Relay uses explicit queueing for most requests. This wait queue should almost always be\nempty, and a large number of queued requests indicates a severe bug.</p>"}}},{"name":"event.accepted","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of envelopes accepted in the current time slot.</p>\n<p>This represents requests that have successfully passed rate limits and filters, and have\nbeen sent to the upstream.</p>"}}},{"name":"event.processing_time","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Time in milliseconds spent in synchronous processing of envelopes.</p>\n<p>This timing covers the end-to-end processing in the CPU pool and comprises:</p>\n<ul>\n<li><code>event_processing.deserialize</code></li>\n<li><code>event_processing.pii</code></li>\n<li><code>event_processing.serialization</code></li>\n</ul>\n<p>With Relay in processing mode, this also includes the following timings:</p>\n<ul>\n<li><code>event_processing.process</code></li>\n<li><code>event_processing.filtering</code></li>\n<li><code>event_processing.rate_limiting</code></li>\n</ul>"}}},{"name":"event.protocol","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of events that hit any of the store-like endpoints: Envelope, Store, Security,\nMinidump, Unreal.</p>\n<p>The events are counted before they are rate limited, filtered, or processed in any way.</p>\n<p>This metric is tagged with:</p>\n<ul>\n<li><code>version</code>: The event protocol version number defaulting to <code>7</code>.</li>\n</ul>"}}},{"name":"event.queue_size","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>The number of envelopes in the queue.</p>\n<p>The queue holds all envelopes that are being processed at a particular time in Relay:</p>\n<ul>\n<li>When Relay receives a Request, it ensures the submitted data is wrapped in a single\nenvelope.</li>\n<li>The envelope receives some preliminary processing to determine if it can be processed or\nif it must be rejected.</li>\n<li>Once this determination has been made, the HTTP request that created the envelope\nterminates and, if the request is to be further processed, the envelope enters a queue.</li>\n<li>After the envelope finishes processing and is sent upstream, the envelope is considered\nhandled and it leaves the queue.</li>\n</ul>\n<p>The queue size can be configured with <code>cache.event_buffer_size</code>.</p>"}}},{"name":"event.queue_size.pct","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>The number of envelopes in the queue as a percentage of the maximum number of envelopes that\ncan be stored in the queue.</p>\n<p>The value ranges from <code>0</code> when the queue is empty to <code>1</code> when the queue is full and no\nadditional events can be added. The queue size can be configured using <code>event.queue_size</code>.</p>"}}},{"name":"event.rejected","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of envelopes rejected in the current time slot.</p>\n<p>This includes envelopes being rejected because they are malformed or any other errors during\nprocessing (including filtered events, invalid payloads, and rate limits).</p>\n<p>To check the rejection reason, check <code>events.outcomes</code>, instead.</p>"}}},{"name":"event.size_bytes.raw","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>The size of the HTTP request body as seen by Relay after it is extracted from a request in\nbytes.</p>\n<ul>\n<li>For envelope requests, this is the full size of the envelope.</li>\n<li>For JSON store requests, this is the size of the JSON body.</li>\n<li>For multipart uploads of crash reports and attachments, this is the size of the multipart\nbody including boundaries.</li>\n</ul>\n<p>If this request contains a base64 zlib compressed payload without a proper\n<code>content-encoding</code> header, then this is the size before decompression.</p>\n<p>The maximum request body size can be configured with <code>limits.max_envelope_size</code>.</p>"}}},{"name":"event.size_bytes.uncompressed","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>The size of the request body as seen by Relay after decompression and decoding in bytes.</p>\n<p>JSON store requests may contain a base64 zlib compressed payload without proper\n<code>content-encoding</code> header. In this case, this metric contains the size after decoding.\nOtherwise, it is always equal to <code>event.size_bytes.raw</code>.</p>"}}},{"name":"event.total_time","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Total time in milliseconds an envelope spends in Relay from the time it is received until it\nfinishes processing and has been submitted to the upstream.</p>"}}},{"name":"event.wait_time","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Time spent between receiving a request in Relay (that is, beginning of request handling) and\nthe start of synchronous processing in the EventProcessor. This metric primarily indicates\nbacklog in event processing.</p>"}}},{"name":"event_processing.deserialize","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Time in milliseconds spent deserializing an event from JSON bytes into the native data\nstructure on which Relay operates.</p>"}}},{"name":"event_processing.filtering","type":"Timer","features":["processing"],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Time in milliseconds spent running inbound data filters on an event.</p>"}}},{"name":"event_processing.pii","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Time in milliseconds spent in data scrubbing for the current event. Data scrubbing happens\nlast before serializing the event back to JSON.</p>"}}},{"name":"event_processing.process","type":"Timer","features":["processing"],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Time in milliseconds spent running event processors on an event for normalization. Event\nprocessing happens before filtering.</p>"}}},{"name":"event_processing.rate_limiting","type":"Timer","features":["processing"],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Time in milliseconds spent checking for organization, project, and DSN rate limits.</p>\n<p>Not all events reach this point. After an event is rate limited for the first time, the rate\nlimit is cached. Events coming in after this will be discarded earlier in the request queue\nand do not reach the processing queue.</p>"}}},{"name":"event_processing.serialization","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Time spent converting the event from its in-memory reprsentation into a JSON string.</p>"}}},{"name":"events.outcomes","type":"Counter","features":["processing"],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of outcomes and reasons for rejected Envelopes.</p>\n<p>This metric is tagged with:</p>\n<ul>\n<li><code>outcome</code>: The basic cause for rejecting the event.</li>\n<li><code>reason</code>: A more detailed identifier describing the rule or mechanism leading to the\noutcome.</li>\n</ul>\n<p>Possible outcomes are:</p>\n<ul>\n<li><code>filtered</code>: Dropped by inbound data filters. The reason specifies the filter that\nmatched.</li>\n<li><code>rate_limited</code>: Dropped by organization, project, or DSN rate limit, as well as exceeding\nthe Sentry plan quota. The reason contains the rate limit or quota that was exceeded.</li>\n<li><code>invalid</code>: Data was considered invalid and could not be recovered. The reason indicates\nthe validation that failed.</li>\n</ul>"}}},{"name":"http_queue.size","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>The number of upstream requests queued up for sending.</p>\n<p>Relay employs connection keep-alive whenever possible. Connections are kept open for <em>15</em>\nseconds of inactivity or <em>75</em> seconds of activity. If all connections are busy, they are\nqueued, which is reflected in this metric.</p>\n<p>This metric is tagged with:</p>\n<ul>\n<li><code>priority</code>: The queueing priority of the request, either <code>\"high\"</code> or <code>\"low\"</code>. The\npriority determines precedence in executing requests.</li>\n</ul>\n<p>The number of concurrent connections can be configured with:</p>\n<ul>\n<li><code>limits.max_concurrent_requests</code> for the overall number of connections</li>\n<li><code>limits.max_concurrent_queries</code> for the number of concurrent high-priority requests</li>\n</ul>"}}},{"name":"processing.event.produced","type":"Counter","features":["processing"],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of messages placed on the Kafka queues.</p>\n<p>When Relay operates as Sentry service and an Envelope item is successfully processed, each\nEnvelope item results in a dedicated message on one of the ingestion topics on Kafka.</p>\n<p>This metric is tagged with:</p>\n<ul>\n<li><code>event_type</code>: The kind of message produced to Kafka.</li>\n</ul>\n<p>The message types can be:</p>\n<ul>\n<li><code>event</code>: An error or transaction event. Error events are sent to <code>ingest-events</code>,\ntransactions to <code>ingest-transactions</code>, and errors with attachments are sent to\n<code>ingest-attachments</code>.</li>\n<li><code>attachment</code>: An attachment file associated with an error event, sent to\n<code>ingest-attachments</code>.</li>\n<li><code>user_report</code>: A message from the user feedback dialog, sent to <code>ingest-events</code>.</li>\n<li><code>session</code>: A release health session update, sent to <code>ingest-sessions</code>.</li>\n</ul>"}}},{"name":"processing.produce.error","type":"Counter","features":["processing"],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of producer errors occurred after an envelope was already enqueued for sending to\nKafka.</p>\n<p>These errors include, for example, <em>\"MessageTooLarge\"</em> errors when the broker does not\naccept the requests over a certain size, which is usually due to invalid or inconsistent\nbroker/producer configurations.</p>"}}},{"name":"project_cache.eviction","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of evicted stale projects from the cache.</p>\n<p>Relay scans the in-memory project cache for stale entries in a regular interval configured\nby <code>cache.eviction_interval</code>.</p>\n<p>The cache duration for project states can be configured with the following options:</p>\n<ul>\n<li><code>cache.project_expiry</code>: The time after which a project state counts as expired. It is\nautomatically refreshed if a request references the project after it has expired.</li>\n<li><code>cache.project_grace_period</code>: The time after expiry at which the project state will still\nbe used to ingest events. Once the grace period expires, the cache is evicted and new\nrequests wait for an update.</li>\n</ul>"}}},{"name":"project_cache.hit","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of times a project is looked up from the cache.</p>\n<p>The cache may contain and outdated or expired project state. In that case, the project state\nis updated even after a cache hit.</p>"}}},{"name":"project_cache.miss","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of times a project lookup failed.</p>\n<p>A cache entry is created immediately and the project state requested from the upstream.</p>"}}},{"name":"project_cache.size","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of project states currently held in the in-memory project cache.</p>\n<p>The cache duration for project states can be configured with the following options:</p>\n<ul>\n<li><code>cache.project_expiry</code>: The time after which a project state counts as expired. It is\nautomatically refreshed if a request references the project after it has expired.</li>\n<li><code>cache.project_grace_period</code>: The time after expiry at which the project state will still\nbe used to ingest events. Once the grace period expires, the cache is evicted and new\nrequests wait for an update.</li>\n</ul>\n<p>There is no limit to the number of cached projects.</p>"}}},{"name":"project_id.request","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of project ID HTTP requests.</p>\n<p>Relay resolves the Sentry project ID for requests sent to the legacy <code>/api/store/</code> endpoint.\nThis process blocks the downstream request handler. The timing for this request is reported\nvia <code>project_id.request.duration</code>. After this, the project ID is cached until Relay\nrestarts.</p>\n<p>Note that official Sentry SDKs do not send data to this endpoint.</p>"}}},{"name":"project_id.request.duration","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Total time in milliseconds spent fetching a project ID from upstream.</p>\n<p>Relay resolves the Sentry project ID for requests sent to the legacy <code>/api/store/</code> endpoint.\nThis process blocks the downstream request handler. After this, the project ID is cached\nuntil Relay restarts.</p>\n<p>Note that official Sentry SDKs do not send data to this endpoint.</p>"}}},{"name":"project_state.eviction.duration","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Total time in milliseconds spent evicting outdated and unused projects happens.</p>"}}},{"name":"project_state.get","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of times a project state is looked up from the cache.</p>\n<p>This includes lookups for both cached and new projects. As part of this, updates for\noutdated or expired project caches are triggered.</p>\n<p>Related metrics:</p>\n<ul>\n<li><code>project_cache.hit</code>: For successful cache lookups, even for outdated projects.</li>\n<li><code>project_cache.miss</code>: For failed lookups resulting in an update.</li>\n</ul>"}}},{"name":"project_state.pending","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of projects in the in-memory project cache that are waiting for their state to be\nupdated.</p>\n<p>See <code>project_cache.size</code> for more description of the project cache.</p>"}}},{"name":"project_state.received","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of project states <strong>returned</strong> from the upstream for each batch request.</p>\n<p>If multiple batches are updated concurrently, this metric is reported multiple times.</p>\n<p>See <code>project_cache.size</code> for more description of the project cache.</p>"}}},{"name":"project_state.request","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of project state HTTP requests.</p>\n<p>Relay updates projects in batches. Every update cycle, Relay requests\n<code>limits.max_concurrent_queries</code> batches of <code>cache.batch_size</code> projects from the upstream.\nThe duration of these requests is reported via <code>project_state.request.duration</code>.</p>\n<p>Note that after an update loop has completed, there may be more projects pending updates.\nThis is indicated by <code>project_state.pending</code>.</p>"}}},{"name":"project_state.request.batch_size","type":"Histogram","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of project states <strong>requested</strong> from the upstream for each batch request.</p>\n<p>If multiple batches are updated concurrently, this metric is reported multiple times.</p>\n<p>The batch size can be configured with <code>cache.batch_size</code>. See <code>project_cache.size</code> for more\ndescription of the project cache.</p>"}}},{"name":"project_state.request.duration","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Total time in milliseconds spent fetching queued project configuration updates requests to\nresolve.</p>\n<p>Relay updates projects in batches. Every update cycle, Relay requests\n<code>limits.max_concurrent_queries * cache.batch_size</code> projects from the upstream. This metric\nmeasures the wall clock time for all concurrent requests in this loop.</p>\n<p>Note that after an update loop has completed, there may be more projects pending updates.\nThis is indicated by <code>project_state.pending</code>.</p>"}}},{"name":"requests","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of HTTP requests reaching Relay.</p>"}}},{"name":"requests.duration","type":"Timer","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Total duration in milliseconds for handling inbound web requests until the HTTP response is\nreturned to the client.</p>\n<p>This does <strong>not</strong> correspond to the full event ingestion time. Requests for events that are\nnot immediately rejected due to bad data or cached rate limits always return <code>200 OK</code>. Full\nvalidation and normalization occur asynchronously, which is reported by\n<code>event.processing_time</code>.</p>\n<p>This metric is tagged with:</p>\n<ul>\n<li><code>method</code>: The HTTP method of the request.</li>\n<li><code>route</code>: Unique dashed identifier of the endpoint.</li>\n</ul>"}}},{"name":"responses.status_codes","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of completed HTTP requests.</p>\n<p>This metric is tagged with:</p>\n<ul>\n<li><code>status_code</code>: The HTTP status code number.</li>\n<li><code>method</code>: The HTTP method used in the request in uppercase.</li>\n<li><code>route</code>: Unique dashed identifier of the endpoint.</li>\n</ul>"}}},{"name":"server.starting","type":"Counter","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Number of Relay server starts.</p>\n<p>This can be used to track unwanted restarts due to crashes or termination.</p>"}}},{"name":"unique_projects","type":"Set","features":[],"childRelayMetricDescription":{"childMarkdownRemark":{"html":"<p>Represents the number of active projects in the current slice of time</p>"}}}]}}}