Search code examples
pythonprometheuspython-unittest

Unittests for prometheus gauge metrics


Here is my metrics code:

from prometheus_client import Gauge

probe = Gauge('probe_success', '1 - probe success, 0 - probe failure'                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
          ['probe_type', 'target', 'timeout', 'service', 'namespace', 'reason'])

If request to the address is successful the value in the end is 1, if some error occurs the value is 0.

def probe_success(probe_type, target, timeout, service, namespace, reason, value):
    probe.labels(probe_type, target, timeout, service, namespace, reason).set(value)

And this is how my metrics look like:

  probe_success{namespace="test",probe_type="http",reason="MissingSchema",service="servicename",target="ddress-test1",timeout="5"} 0.0
probe_success{namespace="test",probe_type="http",reason="ConnectionError",service="servicename",target="http://address-test2",timeout="10"} 0.0
probe_success{namespace="test-2",probe_type="http",reason="",service="servicename",target="https://www.google.com",timeout="5"} 1.0

So how could I test these metrics. I read about REGISTRY.get_sample_value but I didn't see how can I use it on gauge set method. In general I don't have idea how to build appropriate test cases. If anyone has suggestions I will be pleased to read them.


Solution

  • Here is my solution:

    from prometheus_client import REGISTRY
    from utils.metrics import probe_success
    
    
    
    def test_probe_success_metric_when_the_probe_fails():
       
        # calling the metrics function, passing the needed parameters
        # setting the gauges value to be equal to 0 (which means 'False', by default it is 1 'True')
        probe_success(
            'http',
            'http://127.0.0.1:8000/',
            1,
            'test_service',
            'test_namespace',
            'Timeout',
            0,
        )
    
        # searching in prometheus_client REGISTRY by metrics function name, and certain arguments (passed above)
    
        after = REGISTRY.get_sample_value(
            'probe_success',
            {
                'probe_type': 'http',
                'target': 'http://127.0.0.1:8000/',
                'timeout': '1',
                'service': 'test_service',
                'namespace': 'test_namespace',
                'reason': 'Timeout',
            },
        )
        
        # assert whether found gauge value of after is equal to 0.0 (the value which we passed above)
        assert 0.0 == after
    
    
     # Here the procedure is the same as above, but with the difference that here the gauge value is set to 1 'True'.
    def test_probe_success_metric_when_the_probe_success():
    
        probe_success(
            'http', 'http://127.0.0.1:8000/', 1, 'test_service',
            'test_namespace', '', 1
        )
    
       after = REGISTRY.get_sample_value(
            'probe_success',
            {
                'probe_type': 'http',
                'target': 'http://127.0.0.1:8000/',
                'timeout': '1',
                'service': 'test_service',
                'namespace': 'test_namespace',
                'reason': '',
            },
        )
    
    assert 1.0 == after
    

    Here is an example with explanation but with Counter metrics: https://www.robustperception.io/how-to-unit-test-prometheus-instrumentation