Discovering function names before real metrics are produced #31
Replies: 6 comments 17 replies
-
I don't think it's actually possible, as I noted in the Go issue:
So the initialization to I think the only solution is to collect all the autometricized functions (as their annotations are being processed) into some project-global state that could be used by the This is already what we are probably doing with the Being able to do it through metrics has the advantage of being able to rely on Prometheus to query the list of known functions (and since we query the data to Prometheus eventually, that means we'd keep a single source of truth) |
Beta Was this translation helpful? Give feedback.
-
I just had a thought on how this could work in dynamic languages like Typescript and Python. In dynamic languages, I think the wrappers and decorator functions are evaluated right away, rather than when the wrapped function is actually called. This means that in the logic of the wrapper/decorator, we might be able to increment the counters by zero. This should theoretically mean that all the metrics will start at zero, so the UI would be able to use Prometheus data (rather than static analysis) to list all the functions. One further detail on this: we need to think about whether we can make the set of labels perfectly match a set of labels that will actually be produced at runtime. If we can (for example, we can set If we can't make the labels match 100%, because there are some we just won't know at startup but would know later when it's called for real, we might want to make this behavior only trigger during development as opposed to in production. We don't really want to create additional time series in Prometheus that will never be used beyond the initial moment. In Rust, I would disable this behavior in release builds while in other languages you'd probably rely on environment variables or something like that to determine whether it's running in production or not. |
Beta Was this translation helpful? Give feedback.
-
An advantage of setting the metrics to zero to start, instead of using static analysis to find all of the functions, has to do with discovering which functions are part of SLOs. @mies and @brettimus raised this issue. Our current approach for static analysis relies on tree sitter, which I believe is only meant to operate on a single file. That's fine for finding plain autometrics annotations, but it wouldn't allow you to determine which functions were part of which SLO because the objective would likely be defined in another file. If we rely on the libraries themselves to produce dummy metrics at startup, they would be able to access the objective details and could attach the right labels. |
Beta Was this translation helpful? Give feedback.
-
FTR, calling The code that check for resets for counters when calling Footnotes
|
Beta Was this translation helpful? Give feedback.
-
on my python branch that initializes calls at zero, i've been getting a lot of "NaN" results back from prometheus. could this be from dividing by zero in, e.g., the error query? (if intuition says this might be happening, i can try to reproduce tomorrow) |
Beta Was this translation helpful? Give feedback.
-
Implementation of this is being tracked in #59 |
Beta Was this translation helpful? Give feedback.
-
We have some use cases where it would be nice to see all the functions that have been "autometricized" (as @mies calls it), before you actually have traffic that would produce metrics. For example, autometrics-dev/vscode-autometrics#11
One suggestion was to try to start all of the counters at 0 (autometrics-dev/autometrics-rs#70), but most of the metrics libraries don't actually allow you to start counters at 0 and instead only appear when you increment them. (Open question: how would Prometheus itself handle if the counters start at zero? Would it care?)
The other options would involve having autometrics collect up all the function names and either writing them to a file or exposing them on some other endpoint. This is doable (with a kind of crazy trick) in Rust. I'm not sure how it would work in other languages.
Any ideas how we could make this work?
Beta Was this translation helpful? Give feedback.
All reactions