Metrics¶
- class aerospike_sdk.metrics.MetricsPolicy[source]¶
Bases:
objectConfiguration for client metrics collection.
Enabling metrics records the always-on gauges only. The operational tier – latency and byte histograms, result codes, retry and error counters – is opt-in through
operational_enabled, so the cost of measuring every command is never paid by accident.That tier’s defaults are the cross-SDK metrics defaults: latency recorded in milliseconds across 7 logarithmic buckets whose boundaries double per column (
<= 1,> 1,> 2,> 4,> 8,> 16,> 32ms), with every command recorded. ChooseMICROSECONDSwith more columns when sub-millisecond resolution matters.Re-enabling metrics with a changed latency unit or histogram shape discards the accumulated latency samples (counters are retained).
Example:
from aerospike_sdk.metrics import LatencyUnit, MetricsPolicy, Sampler # Pool and membership gauges only -- no per-command measurement. cluster.enable_metrics(MetricsPolicy()) # Classic milliseconds view, sampling 10% of calls. policy = MetricsPolicy( operational_enabled=True, sampler=Sampler.probability(0.1), ) cluster.enable_metrics(policy) # Sub-millisecond resolution for a low-latency deployment. fine = MetricsPolicy( operational_enabled=True, latency_unit=LatencyUnit.MICROSECONDS, latency_columns=18, )
- Parameters:
latency_unit (
LatencyUnit) – Unit latency histograms are recorded in. Defaults to milliseconds.latency_columns (
int) – Number of histogram buckets. Defaults to 7.latency_shift (
int) – Bucket-boundary spacing exponent — each boundary after the first bucket multiplies by2**latency_shift. Defaults to 1 (no skipped powers of two). Must be at least 1.operational_enabled (
bool) – Record the operational tier – latency and byte histograms, result codes, the command count, and the command retry/error and connection failure counters. Off by default, leaving the always-on gauges: pool occupancy, connections opened and closed, tend counts and node membership. The histogram settings above shape this tier and do nothing while it is off.sampler (
Optional[Sampler]) – Record-time gate for the per-command metrics; a fractional sampler decides once per call (not per retry) whether the whole call is measured. Defaults to recording every command.usage_enabled (
bool) – Record which SDK features the application uses (aerospike_sdk.metrics.usage). Off by default. Recorded by this SDK rather than the client core, and independent of latency collection – usage counters ignore the sampler.labels (
Optional[Dict[str,str]]) – Static labels attached to every snapshot, e.g.{"team": "billing"}.
- Raises:
ValueError – If
latency_shiftis less than 1.
- __init__(*, operational_enabled=False, latency_unit=LatencyUnit.MILLISECONDS, latency_columns=_DEFAULT_LATENCY_COLUMNS, latency_shift=_DEFAULT_LATENCY_SHIFT, sampler=None, labels=None, usage_enabled=False)[source]¶
- operational_enabled¶
- latency_unit¶
- latency_columns¶
- latency_shift¶
- sampler¶
- labels¶
- usage_enabled¶
- class aerospike_sdk.metrics.MetricsSnapshot[source]¶
Bases:
objectA point-in-time view of accumulated client metrics.
Counter values are cumulative since metrics were enabled; connection gauges are point-in-time. The canonical detail is the per-node, per-command-type breakdown reachable through
nodesandcluster_aggregated;latency()adds the classic five-way grouped view on top.Example:
cluster.enable_metrics() ... snapshot = cluster.metrics_snapshot() reads = snapshot.latency(LatencyType.READ) print(f"{reads.count} reads, avg {reads.average:.1f} {reads.latency_unit}") for host, node in snapshot.nodes.items(): print(host, node.connections_attempts)
- __init__(pnc_metrics, *, policy=None, nodes=None, usage=None, command_count=None, app_id=None, process=None, metrics_enabled=False, usage_enabled=False)[source]¶
Wrap a raw PNC snapshot.
- Parameters:
pnc_metrics (
ClusterMetrics) – The snapshot from the underlying client.policy (
Optional[MetricsPolicy]) – Policy in effect, supplying the histogram shape that the snapshot itself does not carry.nodes (
Optional[List[Any]]) – Live cluster nodes, joined by host to name the nodes into_canonical_dict().usage (
Optional[Dict[str,int]]) – Feature-usage counters recorded by this SDK.command_count (
Optional[int]) – User API calls counted by this SDK, orNonewhen the caller has no count to report.app_id (
Optional[str]) – Application identity to report when the underlying client carries none, normally the authenticated user.Nonefalls back to"not-set".metrics_enabled (
bool) – Whether collection was on when the snapshot was taken.usage_enabled (
bool) – Whether the usage counters were being recorded.
- property cluster_aggregated: NodeMetricsSnapshot¶
All node snapshots aggregated into one view.
- property metrics_enabled: bool¶
Whether collection was on when the snapshot was taken.
A snapshot can be pulled while collection is off; its counters are then frozen at the values they had when collection was last on.
- property operational_metrics_enabled: bool¶
Whether the operational tier (latency, errors, bytes) was being recorded.
- property command_retries: int¶
Wire retries across the cluster, cumulative since metrics enable.
The per-node retry counters summed: every retry increments on the node it was sent to, and the aggregate retains departed hosts, so the total survives node churn. Retries happen inside the client core, so unlike
command_countthis covers all traffic on the client, however it was issued.Example:
snapshot = cluster.metrics_snapshot() retries_per_call = snapshot.command_retries / max(snapshot.command_count, 1)
- latency(latency_type, node=None)[source]¶
The derived latency histogram for one legacy grouping.
- Parameters:
latency_type (
LatencyType) – Which grouped view to compute (seeLatencyTypefor the category mapping).node (
Optional[str]) – Host address of a single node, orNonefor the cluster-aggregated view.
- Return type:
- Returns:
A
DerivedHistogramin the snapshot’s latency unit.CONNsums the connection-acquisition phase across all namespaces and command types.- Raises:
KeyError – If
nodenames a host not present in the snapshot.
Example:
writes = snapshot.latency(LatencyType.WRITE) slowest_bucket = writes.buckets[-1]
- property usage: Dict[str, int]¶
Feature-usage counters, cumulative since the client started.
Empty unless
MetricsPolicy.usage_enabledwas set. Counts calls made through this SDK, so traffic issued through the underlying client directly is not represented.- Returns:
Counter name to count, e.g.
{"feature.shape.point": 42}.
Example:
snapshot = cluster.metrics_snapshot() print(snapshot.usage.get("feature.filter.ael", 0))
- property command_count: int¶
User API calls counted while operational metrics were on, cumulative.
Counted by this SDK — one increment per data-path call (point, batch, query, UDF, background job) made through this API, whatever the sampler decides — so it is an exact total, and traffic issued through the underlying client directly is not represented.
0when the operational tier was never enabled.Example:
snapshot = cluster.metrics_snapshot() errors_per_call = errors / max(snapshot.command_count, 1)
- to_canonical_dict()[source]¶
The snapshot in the cross-SDK structured form exporters consume.
A stable,
snake_casedocument that a JSON, OTEL or Prometheus exporter can serialize directly, independent of how the underlying client happens to name its fields.The cluster section carries the pool occupancy split, recover-queue depth and invalid-node count the underlying client reports, this process’s CPU share and resident memory when the cluster sampled them, and each node its circuit-breaker
error_rateand thepool_exhaustedcount among its connection counters. The clustercommand_retriesis the per-node retry counters summed;command_countis present when this SDK counted calls — seecommand_countfor its scope.Each namespace’s
errorsis the remainder: failures not already counted undertimeouts,key_busy,record_too_bigordevice_overload, so summing the five never counts a failure twice.timeoutscounts server-reported timeouts; a command that expired on the client side has no result code and is counted once, cluster-wide, undercommand_timeout_client, whilecommand_timeout_serveris the namespacetimeoutssummed.app_idis always populated, so a consumer can group by application without a missing-field case: the identity the application set on the cluster definition, else the authenticated user, else"not-set".nodeslists the nodes still in the cluster. A node that left since the previous export appears once undernodes_departed– same shape, final counters – so an exporter can flush its series without a callback. Departure is tracked by the export timer; a snapshot pulled directly throughmetrics_snapshot()always carries an emptynodes_departed.- Returns:
timestamp,client_type,client_version,cluster_name,app_id,labels, the three tier flags, the histogram shape,cluster,nodesas a list, andnodes_departed.- Return type:
Example:
snapshot = cluster.metrics_snapshot() payload = json.dumps(snapshot.to_canonical_dict())
- class aerospike_sdk.metrics.LatencyType[source]¶
Bases:
EnumLegacy five-way latency grouping, derived from the command categories.
The canonical detail is the per-command-type breakdown (
CommandType); these groups exist for compatibility with the classic latency views (conn/write/read/batch/query) and are computed from the canonical histograms:READ= get + get-header + existsWRITE= put + delete + operate + udfBATCH= batch-read + batch-writeQUERY= query + scanCONN= connection acquisition (pool checkout; includes creation on a pool miss)
- CONN = 'conn'¶
- WRITE = 'write'¶
- READ = 'read'¶
- BATCH = 'batch'¶
- QUERY = 'query'¶
- class aerospike_sdk.metrics.DerivedHistogram[source]¶
Bases:
objectA latency histogram summed across command categories.
Produced by
MetricsSnapshot.latency(); bucket values are in the snapshot’s latency unit (seelatency_unit).- latency_unit: LatencyUnit¶
- __init__(buckets, count, min, max, sum, latency_unit)¶
- class aerospike_sdk.metrics.MetricsExporter[source]¶
Bases:
ProtocolReceives metrics snapshots from a synchronous cluster.
Implement this for
SyncCluster. The call runs on the export thread, so a slow exporter delays the next export but never a request.The snapshot argument is an owned copy: keeping a reference past the call is safe. Resources the exporter writes to are its own to manage – open them in the constructor or on first call, and close them from application code when done.
Example:
class JsonLinesExporter: def __init__(self, path): self._file = open(path, "a") def export(self, snapshot): self._file.write(json.dumps(snapshot.to_canonical_dict()) + "\n") self._file.flush() def close(self): self._file.close() exporter = JsonLinesExporter("/var/log/aerospike/metrics.jsonl") cluster.add_exporter(exporter) ... exporter.close() # the application closes it, never the client
See also
AsyncMetricsExporter: The same contract for the async client.add_exporter()- __init__(*args, **kwargs)¶
- class aerospike_sdk.metrics.AsyncMetricsExporter[source]¶
Bases:
ProtocolReceives metrics snapshots from an asynchronous cluster.
The same contract as
MetricsExporterwith an awaitable method, so an exporter can use an async HTTP client without blocking the event loop the cluster’s own operations run on.Example:
class OtelExporter: def __init__(self, client): self._client = client async def export(self, snapshot): await self._client.post("/v1/metrics", json=snapshot.to_canonical_dict()) cluster.add_exporter(OtelExporter(httpx.AsyncClient()))
See also
MetricsExporter: The same contract for the sync client.add_exporter()- __init__(*args, **kwargs)¶
- class aerospike_sdk.metrics.MetricsExporterType[source]¶
-
Where the periodic push goes: the
metrics.exportersetting.The values are the configuration-file spellings; construction is case-insensitive, so
MetricsExporterType("FILE")isFILE.- FILE¶
The built-in log writer under
report_dir, and nothing else. The default.
- CUSTOM¶
The exporters registered with
add_exporter, in registration order, and nothing else.
- NONE¶
No periodic push; snapshots remain available by polling.
Example:
settings = SystemSettings(metrics=MetricsSettings(exporter=MetricsExporterType.CUSTOM)) cluster = await ClusterDefinition(host).with_system_settings(settings).connect() cluster.add_exporter(my_exporter)
- FILE = 'file'¶
- CUSTOM = 'custom'¶
- NONE = 'none'¶
- __new__(value)¶
- class aerospike_sdk.metrics.MetricsWriter[source]¶
Bases:
objectWrites the line-oriented metrics log under a report directory.
Every line starts with a local timestamp. The first line of each file is a header declaring the schema; each export appends one positional
cluster[...]line carrying the cluster totals, its labels, and every node with its namespaces. A node that left the cluster since the previous export is written once more in that list, with its final counters.The four usage columns (
blocking_count,deferred_count,background_count,tran_count) carry the canonical snapshot’sfeature.api.*andfeature.transactioncounters, and read 0 unless usage counters are enabled.command_countandcommand_retriesread 0 unless operational metrics are enabled. A namespace’serrorsexcludes the failures counted undertimeoutsandkey_busy, andtimeoutscounts server-reported timeouts.The header names the latency unit, column count and shift. A file only ever describes one histogram shape: an export whose shape differs from the header’s starts a new file.
An ordinary exporter, not a client lifecycle: the first
export()creates the directory and opensmetrics-<timestamp>.log. The application callsclose()when done – the client never closes an exporter it did not install. IO errors propagate to the export timer, which logs them and suspends the exporter after repeated failures.- Parameters:
- Raises:
ValueError – If
report_size_limitis neither 0 nor at least 1,000,000.
Example:
exporter = MetricsWriter("/var/log/aerospike", 10_000_000) cluster.add_exporter(exporter) ... exporter.close()
See also
MetricsExporter: The protocol this implements.
- class aerospike_sdk.policy.system_settings.MetricsSettings[source]¶
Bases:
objectClient metrics configuration from the
system.<cluster>.metricsblock.Every field is
Nonewhen the file did not set it, so an absent block changes nothing and a partial block only overrides what it names.The two extended tiers each have their own
enabledflag, under the cross-SDK key names:metrics.extended.operational.enabledgates the latency histograms and per-command counters, and carries the histogram shape keys that only mean anything while it is on;metrics.extended.usage.enabledgates the feature-usage counters, which this SDK records itself rather than reading from the client core.metrics.enabledsits above both: it turns collection on at all, and on its own yields the always-on gauges.exporterselects where the periodic push goes, as aMetricsExporterType:file(the default; the built-in log writer underreport_dir),custom(the exporters registered withadd_exporter) ornone. A string in any case is accepted and stored as the enum member.Example:
# system: # DEFAULT: # metrics: # enabled: true # exporter: file # report_dir: /var/log/aerospike/metrics # labels: # owner: platform-team # extended: # operational: # enabled: true # latency_unit: microseconds # latency_columns: 18
- Raises:
ValueError – If
exporteris notfile,customornone, orreport_size_limitis neither 0 nor at least 1,000,000.
See also
MetricsPolicy: The runtime policy thesesettings build.
- exporter: MetricsExporterType | None = None¶
- __init__(*, enabled=None, latency_unit=None, latency_columns=None, latency_shift=None, export_interval=None, exporter=None, report_dir=None, report_size_limit=None, sampler_range=None, sampler_threshold=None, labels=None, operational_enabled=None, usage_enabled=None)¶