$ show pdreker/fritz_exporter
This is a Prometheus exporter for AVM Fritz! home network devices (routers, repeaters, mesh, DECT smart home) that exposes metrics via a TR-064 SOAP API and the AVM AHA HTTP API. Production deployment is a standalone Python service listening on a configurable address:port (default 127.0.0.1:9787) and registering Prometheus metric families (fritz_*). The architecture is a single-process monolith with a clean capability discovery framework: each metric group is defined as a FritzCapability subclass that declares its TR-064 requirements, probes the device at startup, and generates metrics on each scrape. Devices are configured via a YAML file or environment variables, validated through attrs-based data classes. The exporter handles multi-device mesh scenarios, connection timeouts, offline devices with retry logic, and a concurrent scrape lock to avoid deadlocks. It also includes a data donation mode (--donate-data) that collects all available TR-064 actions from a device, sanitizes sensitive fields, and uploads anonymously to a project endpoint — a hybrid feature supporting both operational monitoring and community-driven compatibility research. External dependencies include the fritzconnection library for TR-064, prometheus_client for metric exposition, defusedxml for secure XML parsing, PyYAML for configuration, and requests for HTTP transport.
The LLM identified 3 files worth highlighting for reuse:
Implements an extensible capability framework via an abstract base class `FritzCapability` that uses `__init_subclass__` for automatic registration in a central registry. Each concrete capability declares its `requirements` (list of `(service, action)` tuples) and undergoes a two-stage probe: static check for service/action existence in the device's TR-064 service inventory, then a live call verification. The uniform lifecycle (`check_capability` -> `create_metrics` -> `_generate_metric_values` -> `_get_metric_values`) allows adding new metric groups without modifying the collector. This pattern is safely extractable for any API-driven metric discovery system, separating capability definitions from orchestration logic.
Provides a dual-path configuration system (YAML file OR environment variables) that converges to a single validated data model using attrs classes (`ExporterConfig`, `DeviceConfig`). Includes converters for type coercion, validators for bounds and cross-field constraints (e.g., `password` vs `password_file` mutual exclusion, `remote_access` requires TLS). The `get_config()` factory function abstracts away the source. This pattern is reusable for any application needing robust, validated configuration from multiple sources with minimal coupling.
Contains `create_fritz_connection`, a factory function that builds a TR-064 connection (via the `fritzconnection` library) with configurable timeout and optional URL rewriting for remote WAN access. It injects timeouts by monkey-patching `requests.Session.request` per-connection (restored in a `finally` block) and handles `/tr064` path prefix for non-local connections. This pattern of creating a short-lived, customized connection with timeout guarantees is reusable for any SOAP/HTTP API client that lacks native timeout support in its session.