0
votes

I'm new to python and prometheus. I'm currently testing a script to scrape metrics and send to a prom file.

The code is:

from prometheus_client import CollectorRegistry, Gauge, write_to_textfile
import re,os
registry = CollectorRegistry()

textfile = 'C:\\Users\\Test\\Desktop\\Python\\'
d = {u'com.testserver.yyy:test-config-server': [u'clog,251', u'temp,33.3', u'violations,1', 
u'errors,0', u'code,1', u'leaks,0']}


for x in d['com.testserver.yyy:test-config-server']:
    ndx = d['com.testserver.yyy:test-config-server'].index(x)
    metric = d['com.testserver.yyy:test-config-server'][ndx].split(',')[0]
    value = float(d['com.testserver.yyy:test-config-server'][ndx].split(',')[1])
    metric_name = re.sub("[^A-Za-z0-9]","_",'com.testserver.yyy:test-config-server')
    test_metric = metric_name+"_"+metric
    final_metric = Gauge(test_metric, 'Metrics scraped from test',['Type'] ,registry=registry)
    final_metric.labels(metric).set(value)

output = textfile + "test_metrics.prom"
write_to_textfile(output, registry)

This is the output:

com_testserver_yyy_test_config_server_ncloc{Type="clog"} 251.0
com_testserver_yyy_test_config_server_coverage{Type="temp"} 33.3
com_testserver_yyy_test_config_server_violations{Type="violations"} 1.0
com_testserver_yyy_test_config_server_vulnerabilities{Type="errors"} 0.0
com_testserver_yyy_test_config_server_code_smells{Type="code"} 1.0
com_testserver_yyy_test_config_server_bugs{Type="leaks"} 0.0

However, there are around 100 dictionary keys(equals 100 metric_names) with 6 metrics each so there will be approximately 600 unique "final_metric"s. Is it possible to have same metric name but distinguished by the labels?

This is the desired output if possible:

com_testserver_yyy_test_config_server{Type="clog"} 251.0
com_testserver_yyy_test_config_server{Type="temp"} 33.3
com_testserver_yyy_test_config_server{Type="violations"} 1.0
com_testserver_yyy_test_config_server{Type="errors"} 0.0
com_testserver_yyy_test_config_server{Type="code"} 1.0
com_testserver_yyy_test_config_server{Type="leaks"} 0.0

When I change the code to this:

for x in d['com.testserver.yyy:test-config-server']:
   ndx = d['com.testserver.yyy:test-config-server'].index(x)
   metric = d['com.testserver.yyy:test-config-server'][ndx].split(',')[0]
   value = float(d['com.testserver.yyy:test-config-server'][ndx].split(',')[1])
   metric_name = re.sub("[^A-Za-z0-9]","_",'com.testserver.yyy:test-config-server')
   final_metric = Gauge(metric_name, 'Metrics scraped from test',['Type'] ,registry=registry)
   final_metric.labels(metric).set(value)

output = textfile + "test_metrics.prom"
write_to_textfile(output, registry)'''

There is error in the output: ValueError: Duplicated timeseries in CollectorRegistry: {'com_testserver_yyy_test_config_server'}

It seems the labels do not distinguish each metric.

2

2 Answers

0
votes

From Prometheus side, metrics can be distinguished by their label and saved separately, although the more you get the worse scrape performance you will have if that matters for you.

0
votes

Declaring the Gauge metric inside the for loop caused the duplicate error. My workaround is, put the Gauge declaration before for loop, set a static metric name: 'test_metric' and add a label for the server name. Only left to do is to manipulate the server name to make it shorter and readable.

from prometheus_client import CollectorRegistry, Gauge, write_to_textfile
import re,os
registry = CollectorRegistry()

textfile = 'C:\\Users\\Test\\Desktop\\Python\\'
d = {u'com.testserver.yyy:test-config-server': [u'clog,251', u'temp,33.3', u'violations,1',u'errors,0', u'code,1', u'leaks,0']}

final_metric = Gauge("test_metric", 'Metrics scraped from test','server','server_metric'] ,registry=registry)
   for x in d['com.testserver.yyy:test-config-server']:
   ndx = d['com.testserver.yyy:test-config-server'].index(x)
   metric = d['com.testserver.yyy:test-config-server'][ndx].split(',')[0]
   value = float(d['com.testserver.yyy:test-config-server'][ndx].split(',')[1])
   metric_name = re.sub("[^A-Za-z0-9]","_",'com.testserver.yyy:test-config-server')
   final_metric.labels(metric_name,metric).set(value)

output = textfile + "test_metrics.prom"
write_to_textfile(output, registry)

New Output

# HELP test_metric Metrics scraped from test
# TYPE test_metric gauge
test_metric{server="com_testserver_yyy_test_config_server",server_metric="clog"} 251.0
test_metric{server="com_testserver_yyy_test_config_server",server_metric="temp"} 33.3
test_metric{server="com_testserver_yyy_test_config_server",server_metric="violations"} 1.0
test_metric{server="com_testserver_yyy_test_config_server",server_metric="errors"} 0.0
test_metric{server="com_testserver_yyy_test_config_server",server_metric="code"} 1.0
test_metric{server="com_testserver_yyy_test_config_server",server_metric="leaks"} 0.0