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

Initial values for metrics should be supported #545

Open
NaomiLYJ opened this issue Mar 7, 2023 · 2 comments
Open

Initial values for metrics should be supported #545

NaomiLYJ opened this issue Mar 7, 2023 · 2 comments

Comments

@NaomiLYJ
Copy link

NaomiLYJ commented Mar 7, 2023

We tried out the library, here's our sample code

import express from 'express'
import * as prom from 'prom-client';
import moment from 'moment';

// Initialize registry
const promRegistry = new prom.Registry();
const defaultLabels = { machineId: 'test-pc', appName: 'nodejs-app' };
promRegistry.setDefaultLabels(defaultLabels);

// Initialize a Counter
const httpRequests = new prom.Counter({
  name: 'http_requests',
  help: 'Count of successful requests',
  labelNames: ['endpoint', 'status'],
  registers: [promRegistry] // specify a non-default registry
});

// Instantiate the Counter with specific labels
const helloWorldHttpSuccess = httpRequests.labels({ "endpoint": "hello-world", "status": "2xx" })

// Initialize a Summary
const httpRequestsProcessTimesSummary = new prom.Summary({
  name: 'http_requests_process_times',
  help: 'How long does it take to process the request',
  labelNames: ['endpoint'],
  maxAgeSeconds: 60,
  ageBuckets: 6,
  percentiles: [0, 0.5, 0.95, 0.99, 1],
  registers: [promRegistry] // specify a non-default registry
});

// Instantiate the Sumary with specific labels
const helloWorldHttpProcessTimesSummary = httpRequestsProcessTimesSummary.labels({ "endpoint": "hello-world" })

// Expose metrics in prometheus format
// Listening on port 9090 for metrics
const prometheus = express();
const prometheusPort = 8090;
prometheus.get('/metrics', async (req, res) => {
  res.type('text/plain');
  res.send(await promRegistry.metrics())
})
prometheus.listen(prometheusPort, () => {
  console.log(`Prometheus metrics listening on port ${prometheusPort}`)
})

Current Behavior

The metrics endpoint output does not show the metrics which are not triggered even though they are already instantiated with labels, e.g.,

# HELP http_requests Count of successful requests
# TYPE http_requests counter

# HELP http_requests_process_times How long does it take to process the request
# TYPE http_requests_process_times summary

Expected

The metrics endpoint outputs initial values (e.g., 0 for a counter) for instantiated metrics

# HELP http_requests Count of successful requests
# TYPE http_requests counter
http_requests{endpoint="hello-world",status="2xx",machineId="test-pc",appName="nodejs-app"} 0

# HELP http_requests_process_times How long does it take to process the request
# TYPE http_requests_process_times summary
http_requests_process_times{quantile="0",endpoint="hello-world",machineId="test-pc",appName="nodejs-app"} NaN
http_requests_process_times{quantile="0.5",endpoint="hello-world",machineId="test-pc",appName="nodejs-app"} NaN
http_requests_process_times{quantile="0.95",endpoint="hello-world",machineId="test-pc",appName="nodejs-app"} NaN
http_requests_process_times{quantile="0.99",endpoint="hello-world",machineId="test-pc",appName="nodejs-app"} NaN
http_requests_process_times{quantile="1",endpoint="hello-world",machineId="test-pc",appName="nodejs-app"} NaN
http_requests_process_times_sum{endpoint="hello-world",machineId="test-pc",appName="nodejs-app"} 0
http_requests_process_times_count{endpoint="hello-world",machineId="test-pc",appName="nodejs-app"} 0

The initial values make sure that the defined metrics always show up at the metrics output, which would avoid a lot of issues (e.g., data not found) when used together with Grafana for visualization.

The initial values are supported in other languages such as C++, Golang, Python etc..

@zbjornson
Copy link
Collaborator

#438 (comment) has a suggested fix for this and background documentation: call inc(0). I think that's the best option, as this library can't generally know the full set of label values.

Histograms additionally have a .zero() method, and summaries are maybe supposed to have one also (#481).

The initial values are supported in other languages such as C++, Golang, Python etc..

I looked through the golang and python libraries and didn't see a specific initialization method. If inc(0) doesn't work for you, can you point me to the specific methods there please?

@NaomiLYJ
Copy link
Author

NaomiLYJ commented Mar 8, 2023

Thanks a lot @zbjornson for your prompt reply!

Not sure if I explained it properly. The initialization here I meant is that initial values are provided once we instantiated the metric with labels, e.g.

// Instantiate the Counter with specific labels
const helloWorldHttpSuccess = httpRequests.labels({ "endpoint": "hello-world", "status": "2xx" })

We do not need to call extra functions afterwards. This feature is implemented in C++, Golang and Python.

The way you proposed is working, but probably not clean. It would be great if this feature could be implemented.

@zbjornson zbjornson removed the question label Mar 8, 2023
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