Skip to content
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

Add async/callback mode to instruments? #702

Open
timwoj opened this issue Mar 5, 2024 · 3 comments
Open

Add async/callback mode to instruments? #702

timwoj opened this issue Mar 5, 2024 · 3 comments

Comments

@timwoj
Copy link

timwoj commented Mar 5, 2024

I'd like to propose a new feature for prometheus-cpp that would add an async or callback mode to the instrument types. This would allow a user to add a callback method (such as a std::function) to an instrument. The callback would be called during Collect() to set the value of the instrument before it’s exported to prometheus. The difference here with normal operation is that it avoids needing to directly record a value periodically, and lets the prometheus export set it only when it’s actually needed.

Does this seem like something worthwhile to add? I don’t mind doing the work, but I just wanted to gauge the interest before I got started on it.

If you need a (possibly overly-complicated) example, opentelemetry-cpp has a similar feature in their “Observable” instruments.

@ganli
Copy link

ganli commented Apr 11, 2024

I have same requirement, to implement sth like GaugeAdapter to collect metric from our internal statistics data on demand.
It's too complex & inefficient to sync such data with prometheus-cpp's internal registry.
For example, we have one counter to track the number of objects. Internally we use std::atomic_int to count, but it's so inefficient to call Gauge::Set in object's constructor/destructor.

@ganli
Copy link

ganli commented Jun 21, 2024

Finally I implemented simple customized registry to do this job:

typedef std::function<double()> GaugeValueGetter;

class PassiveMetricsRegistry: public prometheus::Collectable
{
public:
    bool registerGaugeSource(
        std::string_view measureName,
        std::string_view help,
        const Labels& labels,
        GaugeValueGetter valueGetter);

    bool deregisterGaugeSource(
        std::string_view measureName,
        const Labels& labels);

    std::vector<prometheus::MetricFamily> Collect() const override;
};

auto pmr = std::make_shared<PassiveMetricsRegistry>();
prometheus::Exposer exposer(// endpoint);
exposer.RegisterCollectable(// normal registry);
exposer.RegisterCollectable(pmr);

But it's worth that opentelemetry-cpp provides this feature officially.

@timwoj
Copy link
Author

timwoj commented Jun 21, 2024

We're not using otel-cpp for various reasons, instead preferring to use prometheus-cpp directly. I implemented this in a fork as zeek@2fec720, but never got around to opening a PR for it.

I agree that it's good for otel-cpp to provide this functionality directly themselves as well, since it has more uses there than just with Prometheus.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants