Metrics¶
See the Instrumentation & metrics guide for usage.
asyncly.client.metrics.sinks.base.MetricsSink
¶
Bases: Protocol
Protocol for metrics backends used by InstrumentableHttpClient.
Implement observe_request to record completed requests in any backend.
on_request_start / on_request_end are optional: they bracket the
in-flight window (increment on start, decrement on end). The client detects
their presence once, when the sink is enabled, and only calls them if both
are defined — so an existing sink that implements only observe_request
keeps working unchanged. New sinks can inherit BaseMetricsSink to get no-op
defaults for the optional hooks.
observe_request
¶
observe_request(
*,
client: str,
method: str,
route: str,
operation: str,
status: int | str,
outcome: str,
duration_seconds: float,
error_type: str | None = None,
) -> None
Record a single completed request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client
|
str
|
The client name ( |
required |
method
|
str
|
HTTP method. |
required |
route
|
str
|
Normalized, low-cardinality route label. |
required |
operation
|
str
|
Logical operation name; falls back to |
required |
status
|
int | str
|
Response status code, or a string marker on error. |
required |
outcome
|
str
|
One of |
required |
duration_seconds
|
float
|
Total time including response handling. |
required |
error_type
|
str | None
|
Normalized error taxonomy value on failure, else None. |
None
|
Source code in asyncly/client/metrics/sinks/base.py
on_request_start
¶
on_request_end
¶
observe_phase
¶
Record the duration of a network phase (dns, connect, ttfb, ...).
Fed by the aiohttp TraceConfig from
build_trace_config.
Optional: the client only wires trace context through when the sink
defines this method.
Source code in asyncly/client/metrics/sinks/base.py
asyncly.client.metrics.sinks.base.BaseMetricsSink
¶
Convenience base with no-op optional hooks for sinks authored here.
Note
This is a convenience for new sinks. It is not the
backward-compatibility mechanism: because MetricsSink is a structural
Protocol, an external sink that implements only observe_request
inherits nothing from this class. Compatibility is guaranteed at the
call site, where InstrumentableHttpClient feature-detects the optional
hooks before calling them.
asyncly.client.metrics.sinks.noop.NoopSink
¶
asyncly.client.metrics.sinks.prometheus.PrometheusSink
¶
PrometheusSink(
namespace: str = "http",
subsystem: str = "client",
buckets: Iterable[float] = (
0.005,
0.01,
0.025,
0.05,
0.1,
0.25,
0.5,
1.0,
2.5,
5.0,
10.0,
),
phase_buckets: Iterable[float] = _DEFAULT_PHASE_BUCKETS,
registry: CollectorRegistry = REGISTRY,
)
Bases: BaseMetricsSink
Metrics sink that records to Prometheus (needs the prometheus extra).
Exposes:
{prefix}_request_seconds— duration histogram, labeled by client, method, route, operation, and a compactoutcome(responseorerror).statusis intentionally kept off the histogram: each extra label multiplies the number of time series by the bucket count.{prefix}_requests_total— request counter, labeled by client, method, route, operation, status, and the fulloutcome.{prefix}_errors_total— error counter, labeled by client, method, route, operation, and normalizederror_type.{prefix}_in_flight— gauge of in-progress requests.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
namespace
|
str
|
Prometheus metric namespace prefix. Defaults to |
'http'
|
subsystem
|
str
|
Prometheus metric subsystem prefix. |
'client'
|
buckets
|
Iterable[float]
|
Histogram bucket boundaries in seconds. |
(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0)
|
registry
|
CollectorRegistry
|
Collector registry to register the metrics on. |
REGISTRY
|
Source code in asyncly/client/metrics/sinks/prometheus.py
asyncly.client.metrics.sinks.prometheus.PrometheusPoolCollector
¶
Bases: Collector
Exposes aiohttp TCPConnector pool stats as Prometheus gauges.
Emits {prefix}_pool_connections{upstream, state} for active and
idle connections. Bind it to a connector once the session exists::
collector = PrometheusPoolCollector(upstream="bybit")
collector.bind(session.connector)
Warning
This reads private aiohttp attributes (_acquired, _conns), which
may change between aiohttp versions. Access is guarded: if the internals
are absent, the collector degrades to emitting nothing rather than
raising during a scrape.
Note
Pool stats are connector-scoped, not client-scoped: a connector
shared by several clients cannot attribute connections to one of them.
The upstream label names the connector, not a single operation.
Source code in asyncly/client/metrics/sinks/prometheus.py
asyncly.client.metrics.sinks.opentelemetry.OpenTelemetrySink
¶
Bases: BaseMetricsSink
Metrics sink backed by OpenTelemetry (needs the opentelemetry extra).
Records request counts, durations, errors, and in-flight requests through the
given Meter. Metric names match the Prometheus sink defaults
(http_client_*). status is kept off the duration histogram; the
counter carries it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
meter
|
Meter
|
An OpenTelemetry |
required |
Source code in asyncly/client/metrics/sinks/opentelemetry.py
asyncly.client.metrics.trace_config.build_trace_config
¶
build_trace_config(sink: MetricsSink) -> TraceConfig
Build an aiohttp TraceConfig that reports network phases to sink.
Attach the result to a ClientSession(trace_configs=[...]). Phases are only
emitted for requests carrying a trace_request_ctx with client and
operation keys — which InstrumentableHttpClient sets automatically.
Reused connections skip the dns/connect phases entirely (aiohttp fires no callback), so no misleading zero-duration samples are recorded.
Source code in asyncly/client/metrics/trace_config.py
asyncly.client.metrics.taxonomy.classify_exception
¶
Return (outcome, error_type) for a failed request.
A successful request never reaches this function; the caller reports
("response", "none") directly.
The isinstance ladder is ordered most-specific first because the aiohttp
hierarchy overlaps: ServerTimeoutError is both a ClientConnectionError
and a TimeoutError, and ClientConnectorSSLError is a subclass of
ClientConnectorError which is a subclass of ClientOSError. Reordering
these branches silently changes the emitted labels.
Source code in asyncly/client/metrics/taxonomy.py
asyncly.client.metrics.route_resolver.default_route_resolver
¶
Normalize a URL path into a low-cardinality route label.
Numeric and UUID-like path segments are replaced with :id so that, for
example, /cats/42 and /cats/7 both map to /cats/:id. Used as the
default route label for client metrics.