Optionally serve metrics in protocol buffer format?
See original GitHub issueThank for the great library!
Would you be interested in a pull request related to serving metrics to prometheus in the protocol buffer format?
My thought was to create a new function in lib/register.js
named something like getMetricsAsProtobuf()
which returns a buffer containing the 32-bit varint-encoded record length-delimited protocol buffer messages of type io.prometheus.client.MetricFamily
which prometheus expects. This buffer could be returned in the body of an HTTP response using something like Express or Koa.
There would be one added dependency, protobufjs.
The only issue is, you guys internally store the metrics in a format that is not compliant with prometheus’ metrics.proto messages, so either A), a conversion function is required, or B), we consider updating prom-client to internally store metrics as MetricFamily
compliant objects. (E.G. for metric.type
, we store 0
instead of counter
, etc.)
Here’s the conversion function we’re using, it would be nice not to have to do this. It returns an array of metric objects from which we create protobuf messages using protobufjs’s generated code’s MetricFamily.fromObject(metric)
function. (Note: support for Summary and Histogram is unfinished.)
// Convert prom-client metric objects to `io.prometheus.client.MetricFamily` compliant objects
function convertMetrics() {
let convertedMetrics = []
for (let metricFamily of prom.getMetricsAsJSON()) {
let newMetricFamily = {}
newMetricFamily.name = metricFamily.name
newMetricFamily.help = metricFamily.help
let newMetrics = []
for (let metric of metricFamily.values) {
let newMetric = {}
let newLabels = []
Object.keys(metric.labels).forEach(function (key) {
if (metric.labels[key].toString() != null)
newLabels.push({ "name": key, "value": metric.labels[key].toString() });
});
newMetric.label = newLabels;
switch (metricFamily.type) {
case "counter":
newMetricFamily.type = 0;
newMetric.counter = { "value": metric.value };
break;
case "gauge":
newMetricFamily.type = 1;
newMetric.gauge = { "value": metric.value };
break;
case "summary":
newMetricFamily.type = 2;
// TODO
break;
case "histogram":
newMetricFamily.type = 4;
// TODO
break;
}
// TODO timestamp_ms is not supported in prom-client? (confirm or contribute)
// newMetric.timestamp_ms = metric.timestamp_ms;
newMetrics.push(newMetric);
}
newMetricFamily.metric = newMetrics
convertedMetrics.push(newMetricFamily);
}
return convertedMetrics;
}
I’ve written code that successfully sends the protobuf messages to prometheus, I’d like to share it, but the conversion part feels hacky. Thoughts?
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:10 (3 by maintainers)
Prometheus 2.x does not support proto, so this can be closed.
This would be really nice! Timestamp is #69 btw (the todo in your sample code)