client_python icon indicating copy to clipboard operation
client_python copied to clipboard

Allow count_exceptions to add the error type as a label

Open JamesTimms opened this issue 3 years ago • 2 comments

I'd like count_exceptions to add the error type as a label so I can track what errors are occurring against what endpoints for my application.

I'd like to do this via the with method.

from prometheus_client import Counter

ERRORS = Counter(
    'http_request_errors_count',
    'Count of  exceptions that happen during an HTTP request',
    ['method', 'endpoint', 'error']
)

async def error_middleware(request, handler):
    try:
        with ERRORS.count_exceptions(request.method, request.path):
            return await handler(request)
    except SomeHTTPException as e:
        ...

To do this I've created my own custom Counter classes.

from prometheus_client import Counter, context_managers


class CustomExceptionCounter(context_managers.ExceptionCounter):
    def __init__(self, counter, exception, *labels):
        self._counter = counter
        self._exception = exception
        self._labels = labels

    def __exit__(self, typ, value, traceback):
        if isinstance(value, self._exception):
            self._counter.labels(*(*self._labels, typ.__name__)).inc()  # Append exception's name as a label


class CustomCounter(Counter):
    def count_exceptions(self, *labels, exception=Exception):
        return CustomExceptionCounter(self, exception, *labels)


ERRORS = CustomCounter(
    'http_request_errors_count',
    'Count of CancelledError exceptions',
    ['method', 'endpoint', 'error']
)

I think there is a general solution that's backward compatible, I've just not figured it out. Is this something you'd support? I'd be happy to submit a PR if I can figure out how to make this backward compatible.

JamesTimms avatar Jan 09 '22 14:01 JamesTimms

Hello,

Thank you for opening this issue, it presents some interesting ideas. I am not sure if I want to support this behavior in the client library or not, mostly because this library doesn't usually fill in labelvalues for you. I am also a bit concerned that there might be a way to explode cardinality (I have seen that done with error strings for sure), but the type might be safe.

My gut says if we do want to implement this to have it be a second function/context manager and mark it as experimental.

csmarchbanks avatar Jan 10 '22 20:01 csmarchbanks

Thanks @csmarchbanks , I think this is a good feature as the only other way to do it is in each except block which is more tedious.

I'll consider throwing something together if I have the time but I'm still relatively new to Python and client_python so can't promise anything.

JamesTimms avatar Jan 11 '22 15:01 JamesTimms