μstats sends tagged statsd metrics with UDP. The benefits of UDP
is that you can fire and forget, the beauty of statsd format is simplicity.
The recommended usecase is to first send the metrics to the stats-exporter, then let Prometheus periodically scrape data from the exporter.
ustats is a open source product by impersonate.pro
Prometheus is great, the query language is simple and expressive. But the scrape
behavior and "pull" model can be really annoying, especially in Python, where
setting up an additional thread in web framework is cumbersome. Moreover, the
Prometheus python client API is somewhat weird to me. From a pythonista's point of
view, python seems to be a second-class citizen in the Prometheus ecosystem.
What I really miss from previous experience is to use the "push" model and utilize UDP's send-and-forget behavior. Unfortunately, Prometheus does not support this.
However, there is an old UDP-based metric server/protocol called statsd, which
is UDP-based. And there are some extensions to the protocol that support tags,
a crucial feature.
To combine the best of two worlds, we can use statsd-exporter, which simulates
as a statsd server, but export metrics to an HTTP endpoint for Prometheus to
scrape.
Now, all we need is a Python library to send metrics in tagged statsd format,
and here comes ustats.
git clone https://github.com/lexiforest/ustats
cd deploy
docker-compose -n metrics up
Login to Grafana, and config the backend services.
Run the example scripts in a new shell for a little while.
Add the following query in Grafana.
rate(test_api_call_sum[1m]) / rate(test_api_call_count[1m])
Now you should see the generated metrics from the example script.
My primary usage pattern is to send the
import ustats
ustats.init(prefix="test")
ustats.timer()Asyncio is also supported.
import asyncio
import ustats
async def main():
await ustats.ainit()
if __name__ == "__main__":
asyncio.run(main())