Statistics, health, Prometheus¶
enocean.stats
¶
Runtime statistics and health of a communicator, always collected (no dependency, negligible cost).
Read them with communicator.stats.snapshot() and communicator.health(), or expose them to Prometheus with
enocean.prometheus.
SenderStats
dataclass
¶
SenderStats(
packets: int,
last_seen_at: float,
rorg: int,
dbm: int | None,
)
What was last heard from one device (per-sender tracking must be enabled).
StatsSnapshot
dataclass
¶
StatsSnapshot(
started_at: float,
packets_received: dict[PacketKind, int],
packets_sent: dict[PacketKind, int],
bytes_received: int,
bytes_sent: int,
parse_errors: dict[str, int],
teach_in_responses: int,
base_id_requests: int,
base_id_timeouts: int,
base_id_fetch_seconds: float | None,
transport_errors: int,
processing_errors: int,
last_packet_received_at: float | None,
packets_ignored: int = 0,
senders: dict[str, SenderStats] = dict(),
senders_evicted: int = 0,
)
A consistent copy of the statistics at one point in time. Timestamps are time.time() values.
CommunicatorStats
dataclass
¶
CommunicatorStats(
started_at: float = time.time(),
_lock: Lock = threading.Lock(),
_packets_received: Counter[PacketKind] = Counter(),
_packets_sent: Counter[PacketKind] = Counter(),
_bytes_received: int = 0,
_bytes_sent: int = 0,
_parse_errors: Counter[str] = Counter(),
_teach_in_responses: int = 0,
_base_id_requests: int = 0,
_base_id_timeouts: int = 0,
_base_id_fetch_seconds: float | None = None,
_transport_errors: int = 0,
_processing_errors: int = 0,
_last_packet_received_at: float | None = None,
_packets_ignored: int = 0,
_max_senders: int = 0,
_senders: OrderedDict[str, SenderStats] = OrderedDict(),
_senders_evicted: int = 0,
)
Counters updated by the communicator thread; safe to read from any thread through snapshot().
enable_sender_tracking
¶
enable_sender_tracking(max_senders: int = 500) -> None
Also keep per-device statistics (SenderStats), for up to max_senders devices.
Beyond that, the least recently heard devices are forgotten, so neighbours' devices picked up by the radio can't grow memory or metric cardinality forever.
record_bytes_received
¶
record_bytes_received(count: int) -> None
Count bytes read from the transport.
record_received
¶
record_received(packet: Packet) -> None
Count a received packet, and its sender when per-sender tracking is enabled.
record_ignored
¶
record_ignored() -> None
Count a packet dropped because its device is ignored by the DeviceRegistry.
record_sent
¶
record_sent(packet: Packet, byte_count: int) -> None
Count a packet written to the transport, and its bytes.
record_parse_error
¶
record_parse_error(kind: str) -> None
Count a parse error reported by Packet.parse_msg(on_error=...).
record_base_id_request
¶
record_base_id_request() -> None
Count a base ID request sent to the module.
record_base_id_received
¶
record_base_id_received(seconds: float) -> None
Record how long the module took to answer the base ID request.
record_base_id_timeout
¶
record_base_id_timeout() -> None
Count a base ID request the module did not answer in time.
record_transport_error
¶
record_transport_error() -> None
Count a transport failure (e.g. the serial port failing to read or write).
record_processing_error
¶
record_processing_error() -> None
Count an exception raised while processing received packets (e.g. by a callback).
snapshot
¶
snapshot() -> StatsSnapshot
A consistent copy of all the counters, safe to use from any thread.
Health
dataclass
¶
Health(
running: bool,
transport_ready: bool,
base_id_known: bool,
receive_queue_size: int,
transmit_queue_size: int,
seconds_since_last_packet: float,
problems: tuple[str, ...],
)
State of a communicator, for liveness/readiness probes. problems explains why it is not healthy.
packet_kind
¶
packet_kind(packet: Packet) -> PacketKind
The (packet type, RORG) statistics are counted by; RORG is None for non-radio packets.
enocean.prometheus
¶
Prometheus metrics for communicators. Requires the optional dependency: pip install enocean[prometheus].
from prometheus_client import start_http_server
from enocean.prometheus import register
register(communicator) # or register({'usb0': com0, 'usb1': com1}), registry=..., namespace=...
start_http_server(9100)
Metrics are computed from communicator.stats and communicator.health() when scraped: nothing is done between
scrapes.
EnOceanCollector
¶
EnOceanCollector(
communicators: Communicator
| Mapping[str, Communicator],
namespace: str = 'enocean',
const_labels: Mapping[str, str] | None = None,
max_silence: float | None = None,
per_sender: bool = False,
max_senders: int = 500,
)
Bases: Collector
Collects metrics from one communicator, or several given as {name: communicator} (adds a communicator label).
namespace prefixes every metric name; const_labels are added to every sample (e.g. {'site': 'home'});
max_silence (seconds) is passed to health() for the healthy gauge. per_sender enables per-device tracking
(bounded by max_senders) and exports it with a sender label: mind the cardinality.
collect
¶
collect() -> Iterator[Metric]
Metrics of the communicators, read from their stats and health (called by prometheus_client on scrape).
register
¶
register(
communicators: Communicator
| Mapping[str, Communicator],
registry: CollectorRegistry = REGISTRY,
namespace: str = 'enocean',
const_labels: Mapping[str, str] | None = None,
max_silence: float | None = None,
per_sender: bool = False,
max_senders: int = 500,
) -> EnOceanCollector
Creates an EnOceanCollector and registers it (in the default registry unless one is given).
enocean.consolelogger
¶
Logging setup for applications and examples using the library.
JsonFormatter
¶
Bases: Formatter
Formats records as one JSON object per line, including fields passed with extra=.
format
¶
format(record: LogRecord) -> str
Format a record as a JSON object: time, level, logger, message, extra fields, exception.
init_logging
¶
init_logging(
level: int = logging.DEBUG,
log_to_file: bool = False,
logsize: int = 1024,
logcount: int = 5,
json_format: bool = False,
) -> None
Send the library's logs to stderr, and optionally to a rotating enocean.log file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
int
|
Minimum level of the records emitted. |
DEBUG
|
log_to_file
|
bool
|
Also write to enocean.log in the working directory. |
False
|
logsize
|
int
|
Maximum size of enocean.log, in kB, before it is rotated. |
1024
|
logcount
|
int
|
Number of rotated files kept. |
5
|
json_format
|
bool
|
Emit one JSON object per record, carrying structured fields such as packet_type, rorg, sender. |
False
|