Prometheus-client multiprocessing mode ASGI gunicorn basic setup

443 Views Asked by At

I'm trying to add prometheus-client to my very basic API what is powered by gunicorn with multiple processes and Uvicorn workers.

I have no flask, nor fastapi here as it is very minimalistic piece of code.

I managed to get single process version to work by codding:

// app is actually generated via factory that instantiates the following class

class AppPattern:
def __init__(self, config):
    self.config = config
    self.promapp = make_asgi_app(disable_compression=True)

async def __call__(self, scope, receive, send):
   
    if scope['path'] == '/metrics':
        logger.debug("METRICS")
        return await self.promapp(scope, receive, send)

but I got confused how should it look like for multi processing mode? My stub looks like this:

class AppPattern:
def __init__(self, config):
    self.config = config

    self.registry = CollectorRegistry()
    multiprocess.MultiProcessCollector(self.registry)
    # self.promapp = make_asgi_app(disable_compression=True)

async def __call__(self, scope, receive, send):
    """ React on call from parse
    """
    # body = f'Received {scope["method"]} request to {scope["path"]}'
    if scope['path'] == '/metrics':
        logger.debug("METRICS")
        data = generate_latest(self.registry)
        status = '200 OK'
        response_headers = [
            ('Content-type', CONTENT_TYPE_LATEST),
            ('Content-Length', str(len(data)))
        ]
        await send({
        'type': 'http.response.start',
        'status': 200,
        'headers': response_headers})
        await send({
        'type': 'http.response.body',
        'body': iter([data])})

        return 

But actually I have no idea how to send the data as the above code does not work.

I did managed to have it working by passing registry to make_asgi_app but I don't know if it is the righ way to do it

    def __init__(self, config):
    self.config = config

    registry = CollectorRegistry()
    multiprocess.MultiProcessCollector(registry)
    self.promapp = make_asgi_app(registry=registry,disable_compression=True)

async def __call__(self, scope, receive, send):
    """ React on call from parse
    """
    # body = f'Received {scope["method"]} request to {scope["path"]}'
    if scope['path'] == '/metrics':
        return await self.promapp(scope, receive, send)

Would someone be so kind and guide me a little bit more as this docs (https://github.com/prometheus/client_python#multiprocess-mode-eg-gunicorn) are not clear for me.

Thanks!

0

There are 0 best solutions below