I wanted to post some details about getting Prometheus metrics working. ⚠️ This post will bit-rot like other things on the Internet.
I found this post to be a good starting point but it relies on an archived express middleware. https://scottsmerchek.com/blog/setting-up-production-monitoring-for-remix-on-fly-io
I liked its use of an ENV and used that to start it up locally so we can test it out even in dev.
This will expose a /metrics route which prometheus can scrape. Ultimately, I do not want my metrics to be public so this config will not work verbatim. We need to start another server on a different port and then it's up to you how to protect this. You could, alternatively protect this port based off a path. I'm assuming a very plain server environment and not from a PaaS or something.
So I want :3001/metrics to be my host. Easy enough to do with express. Create another express app and treat it as another app listening on another port. Unfortunately, this will have side-effects which I will address later.
First, let's talk about a faster feedback loop. You might think we need a prometheus + grafana instance to see if this is working (I did). In the end, I realized that this is just HTTP. curl localhost:3001/metrics | grep foo_counter will be a realistic test to see if our Counter named foo_counter is working. We don't need to test with Grafana.
My first attempt involved configuring express-prometheus-middleware and following along with the server.ts from the blues stack. It works fine for a default config and prometheus setup but it did not show how to configure a custom Gauge or Counter. This leads me to the core of this post.
We need a global.
The prometheus client really, really wants to use globals. It has a Registry API that lets you register different metrics. If you register a metric twice, it explodes. In other words: you can't create a metric in a loader.