New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose metrics for external consumption #627
Comments
Hi @avanier, what kind of metrics are you proposing? Can you give some examples? Prometheus format should be fine. |
For my particular use-case I know could use exporting something like The Go Prometheus client also has a bunch of "free" ones like I'm open to suggestions if there anything that you feel should be part of a first pass. |
Hey, status update with good new and bad news. Good news: I got started and it's looking good. You can check the branch I've got going on here. Bad news: I likely won't be able to use very many of the queries due to the way Prometheus groks about counters. I mean, I probably could, but making a blocking metrics request is usually an anti-pattern for Prometheus metrics. (It can lead to significant problems at scrape-time which can screw up the metrics themselves once aggregated.) Silver lining: There's some really nice hooks in Listmonk to latch on, so it shouldn't be too hard to get the metrics we want exposed provided no one objects to me strewing around a bunch of counters all over the place. Context: I'm a sysadmin by trade, so the engineering part of software engineering is really not my forte. I could absolutely use feedback on how to structure this so it makes sense to maintain in the long run. |
Was checking out the WIP. The bounce counters increment, but on changing a setting somewhere, listmonk will restart resetting it to 0. Are the metrics supposed to be ephemeral like that? To return accurate states, eg: sending stats of running campaigns or total bounce counts per campaign etc., a separate goroutine could query the DB for metrics periodically and keep it in a global state somewhere and return on |
@knadh Okay, so as I understand going through the thread, these metrics are different from instrumentation metrics that you would typically write. Instrumentation of code via metrics means that, when a thing happens, you notify the metrics collector to update a certain value that it keeps in memory. A very simple example:
The key thing to note here is that, we add metrics in the code path as and when real world state changes and not poll for it (like an external Goroutine). This is because here, source of truth is the app itself and not a DB. However, in case of Listmonk, things like bounces and some other metrics aren't instrumentation metrics but more like analytical. And since they can't be pre-determined (inside the code path), we'll need to do what @knadh suggested:
This is not a pattern I've observed usually however. I think this also warrants the usage of https://github.com/mr-karan/store-exporter (self plug 😄), if these metrics can be pulled from DB. However, if there are certain metrics that aren't recorded on DB but only held within the app, then I think we can bundle the metrics exposition inside Sidenote
@avanier Yeah, that's correct. But in the above proposed solution, we can have a separate Goroutine to update the |
The whole idea is tickling my spider-senses, but I can't find any issue with @mr-karan 's suggestion. I've never done it this way and that A few random thoughts:
|
If we're just counting bounces as they come, campaign messages as they're sent, subscribers as they're inserted etc., that's all instrumentation I guess? If that's the case, then we can just add counters instead of depending on the DB states.
The |
That's usually how I've seen it used. I think if we mean to do "transactional-level accuracy analytics", I think #660 makes more sense for that use-case. Not that you can't use Prometheus for business intelligence, but it wasn't designed for that. |
the |
Yep, that should be possible ^ I'd also add that maybe using https://github.com/VictoriaMetrics/metrics is a better idea than https://github.com/prometheus/client_golang/ because of a much simpler API and a lot less dependencies. |
+1 |
Ooh, yeah, I'm liking where this is going.
It will take me a while to scrounge up time to put this together, but I'll likely report back within a week or two with something. |
Here's an update as promised. General thoughts:
@knadh && @mr-karan , I could use your feedback before I proceed butchering this thing some more. 😈 😁 |
Nice work @avanier and thanks for this! Can you create a PR (Draft is fine too). I am unable to leave comments on the diff link. |
@mr-karan I've collected this into a PR and gave it a once-over. It should be a bit more readable now. |
As a listmonk administrator,
I want to have metrics available externally
So that I can consume them and implement things like alerting with outboard systems.
Context
In our particular deployment of listmonk we're processing bounces from SES and the relevant subscribers are not being blocklisted automatically. Exporting metrics that we could hook into our monitoring system would help bring issues to our attention as they arise.
Misc
I'm specifically thinking of opening a PR to expose Prometheus metrics. I've seen that some of the stuff is already instrumented with
go-metrics
for internal dashboards, so building on that should be no biggie.Do note, I'm suggesting exposing Prometheus metrics since I'm used to the tooling but we could just as well do something else like Influx, or Statsd. Whichever the community feels is the best common denominator.
The text was updated successfully, but these errors were encountered: