Operations / Observability¶
1. Goals¶
When an issue occurs, operators must be able to answer the following questions:
- Is the poller currently running?
- When was the last successful execution?
- How far behind is it?
- Is the failure caused by the source, handler, or commit?
- Are duplicates increasing?
2. Structured Logging¶
Emit structured logs at every major step.
Required fields: - poller_name - invocation_id - batch_id - source - fetched_count - batch_size - committed - checkpoint_before - checkpoint_after - lease_owner - duration_ms - fetch_duration_ms - handler_duration_ms - commit_duration_ms - lag_seconds - error_type - result
Optional / reserved fields: - schedule_time — reserved for future use and not populated in the current implementation
Stable event names:
- tick_start
- fetch_empty
- batch_complete
- tick_complete
- lease_acquire_failed
- checkpoint_load_failed
- source_descriptor_failed
- fetch_failed
- normalize_failed
- handler_failed
- commit_failed
- lease_release_failed
3. Metrics¶
| Type | Metric | Status | Notes |
|---|---|---|---|
| Counter | azfdb_batches_total |
implemented | result label is success or failure |
| Counter | azfdb_events_total |
implemented | Emits processed event count for successful batches |
| Counter | azfdb_failures_total |
implemented | error_type label only |
| Counter | azfdb_duplicates_total |
deferred | Requires duplicate detection strategy |
| Counter | azfdb_quarantined_total |
deferred | Requires quarantine sink support |
| Histogram | azfdb_fetch_duration_ms |
implemented | Fetch duration per successful batch |
| Histogram | azfdb_handler_duration_ms |
implemented | Handler duration per successful batch |
| Histogram | azfdb_commit_duration_ms |
implemented | Checkpoint commit duration per successful batch |
| Histogram | azfdb_batch_size |
implemented | Successful batch size |
| Gauge | azfdb_lag_seconds |
implemented | Timestamp cursor lag when cursor is ISO datetime |
| Gauge | azfdb_last_success_timestamp |
implemented | Successful tick timestamp in UTC epoch seconds |
| Gauge | azfdb_lease_staleness_seconds |
deferred | Requires lease age tracking |
Metrics labels stay low-cardinality:
- poller_name
- source
- result
- error_type
3.1. Custom MetricsCollector Example¶
from collections.abc import Mapping
from azure_functions_db import MetricsCollector, PollTrigger
class PrintMetricsCollector:
def increment(
self, name: str, value: float = 1, *, labels: Mapping[str, str] | None = None
) -> None:
print("increment", name, value, labels)
def observe(
self, name: str, value: float, *, labels: Mapping[str, str] | None = None
) -> None:
print("observe", name, value, labels)
def set_gauge(
self, name: str, value: float, *, labels: Mapping[str, str] | None = None
) -> None:
print("gauge", name, value, labels)
trigger = PollTrigger(
name="orders",
source=source,
checkpoint_store=checkpoint_store,
metrics=PrintMetricsCollector(),
)
3.2. Metric Query Examples¶
Examples below are deployment-agnostic and assume your metrics backend supports basic aggregation.
- Successful batches by poller:
sum(rate(azfdb_batches_total{result="success"}[5m])) by (poller_name) - Failure rate by error type:
sum(rate(azfdb_failures_total[5m])) by (poller_name, error_type) - Average batch size:
avg(azfdb_batch_size) by (poller_name, source) - Last successful tick age:
now() - azfdb_last_success_timestamp{poller_name="orders"} - Current lag:
azfdb_lag_seconds{poller_name="orders"}
4. Tracing¶
Tracing is deferred to azure-functions-db-python-otel so the base package keeps zero extra dependencies.
When tracing support lands, the expected shape remains: - poll tick - lease acquire - fetch - normalize - handler - checkpoint commit
5. Lag Definition¶
Lag definition varies by strategy.
Cursor timestamp-based¶
Current implementation details:
- Lag is emitted only after a successful checkpoint commit.
- The runner reads checkpoint["cursor"] from the just-committed checkpoint.
- If the cursor is an ISO 8601 datetime string, it is parsed directly.
- If the cursor is a tuple, only the first part is inspected for an ISO 8601 datetime string.
- Naive datetimes and non-datetime cursors are ignored.
Integer sequence-based¶
Use the difference between DB max(version) and the checkpoint.
6. Alerts¶
Minimum alerts: - No success for 15+ minutes - 5 consecutive failures - Sudden lag spike - Stale lease - Increasing quarantine count
7. Operational Commands¶
Supported via CLI or management scripts:
- checkpoint inspect
- checkpoint reset
- checkpoint clone
- force lease break (use with caution)
- dry-run fetch
- backfill preview
8. Quarantine¶
If a batch repeatedly fails, the payload can be sent to a quarantine sink.
MVP: - optional blob sink
Format:
9. Operations Dashboard¶
Recommended cards: - poller health table - last success - lag - events/min - failure rate - top error types
10. Runbook Examples¶
When a batch keeps failing¶
- Inspect checkpoint
- Dry-run source query
- Identify the offending row
- Decide whether to roll back handler code
- If necessary, send to quarantine — do not manually advance checkpoint
When lag spikes suddenly¶
- Consider increasing batch size
- Consider increasing max_batches_per_tick
- Adjust schedule
- Check for handler downstream bottlenecks