client_python
client_python copied to clipboard
Allow count_exceptions to add the error type as a label
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.
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.
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.