willsoto/nestjs-prometheus

Make it possible to inject a dependency into collect function

Opened this issue ยท 3 comments

slukes commented

We would like to be able to inject a dependency into the collect function in order to be able to monitor resources configured by another nest provider for example a queue.

We have done a POC to work around the fact there seems to be no way to do this as so:

{
      provide: getToken('queue_size_scheduled_queue'),
      inject: [getQueueToken('scheduledQueue')],
      useFactory: (queue) => {
        return getOrCreateMetric('Gauge', {
          name: 'queue_size_scheduled_queue',
          help: 'todo',
          collect: async function () {
            const value = await queue.getWaitingCount();
            this.set(value);
          },
        });
      },
    }

In an ideal world we would like to use an api such as:

makeGaugeProvider({
      name: 'queue_size_scheduled_queue',
      help: 'some help',
      collectInject: [getQueueToken('scheduledQueue')],
      collect: async function (queue) {
        const value = await queue.getWaitingCount();
        this.set(value);
      }
    })

@slukes To be honest, this seems like a very bespoke use case and I am not sure it's worth complicating the interface for it.

However, I am open to a proof of concept implementation that is backwards compatible if you are willing to contribute one. I can't guarantee it gets merged simply because I think this is a super narrow use case. With that said, if the implementation is simple, elegant and backwards compatible I will consider it with an open mind.

I also encountered a usecase where this feature would be useful:
I have a service which makes API call to an external API and I want to gave a Gauge which represents the percentage of used credits. I need to make an API call via my Service to get the number of credits left. Here is my implementation:

      provide: getToken(METRICS_CREDITS.name),
      inject: [MyService],
      useFactory: (myService: MyService) => {
        return getOrCreateMetric('Gauge', {
          ...METRICS_CREDITS,
          collect: async function () {
            const credits = await myService.getCredits();
            this.set(
              credits.used_credits / credits.total_credits,
            );
          },
        } as GaugeConfiguration<string>);
      },
    },

I'm happy with this implementation, so thank you @slukes but the API you suggested would be great!

Thanks for this lib @willsoto ! ๐Ÿ™

Looks like a nice feature to me too. I have a case similar to @arthurlenoir. the problem is the api creds are injected from a service that is managing secrets.
Did you manage to find a workaround for the time being?