Metrics infrastructure - design choices
For #1726 (metrics for hidden services) we need to make some infrastructural decisions.
I looked at the crates ecosystem and propose:
-
Use
metrics
as the principal API throughout our codebaseThere is also a
prometheus
crate and framework which is a Prometheus-specific registry. The situation is explained in the description of metrics-prometheus. I think we should prefer the convenient and agnostic API for our principal functional code. -
Use
metrics-exporter-prometheus
. This useshyper
for its http server which seems like the right choice. It expects to have a "pet" hyper instance, which seems fine to me.Note that this implies only supporting metrics when Tokio is also enabled. AFAICT hyper is theoretically useable outside tokio but in practice this seems hard. hyper and tokio are very dominant nowadays and we should fate-share with the rest of the community. If we ever want to support metrics extraction in (eg) WASM I think we can reasonably say that hyper working in WASM is a prerequisite.
We should perhaps try to detect at compile-time a situation where the metrics system thinks it's using tokio but there is also another async runtime (but multiple Rust async runtimes can coexist with a process, so multiple runtimes might function correctly).
-
Have one single metrics port for the whole process which aggregates information from all that process's activities. In particular, from all hidden services.
-
Not compile this feature in by default. But make it part of "full". Enable it only explicitly (with similar warnings to the C Tor MetricsPort)
-
Not try particularly hard to replicate the precise metrics names etc. from C Tor.
Note that whatever design choices we make ought to be suitable for our other foreseeable uses of metrics collection, since otherwise we'd risk having to maintain and work with two incompatible setups. Eg, see #1003.