Search code examples
pythonlogginggunicornpython-logging

How to filter logs from gunicorn?


I have a Flask API with gunicorn. Gunicorn logs all the requests to my API, i.e.

172.17.0.1 - - [19/Sep/2018:13:50:58 +0000] "GET /api/v1/myview HTTP/1.1" 200 16 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"

However, I want to filter the logs to exclude a certain endpoint which is called from some other service all few seconds.

I wrote a filter to exclude this endpoint from being logged:

class NoReadyFilter(logging.Filter):
    def filter(self, record):
        return record.getMessage().find('/api/v1/ready') == -1

and if I add this filter to the werkzeuglogger and use the Flask development server, the filter works. Requests to /api/v1/ready won't appear in the log files. However, I can't seem to add the filter to the gunicornlogger. With the following code, requests to /api/v1/ready still appear:

if __name__ != '__main__':
    gunicorn_logger = logging.getLogger('gunicorn.glogging.Logger')
    gunicorn_logger.setLevel(logging.INFO)
    gunicorn_logger.addFilter(NoReadyFilter())

How can you add a filter to the gunicorn logger? I tried adding it to the gunicorn.error-logger as suggested here, but it didn't help.


Solution

  • I finally found a way of doing it by creating a subclass

    class CustomGunicornLogger(glogging.Logger):
    
        def setup(self, cfg):
            super().setup(cfg)
    
            # Add filters to Gunicorn logger
            logger = logging.getLogger("gunicorn.access") 
            logger.addFilter(NoReadyFilter())
    

    that inherits from gunicorn.glogging.Logger. You can then provide this class as a parameter for gunicorn, e.g.

    gunicorn --logger-class "myproject.CustomGunicornLogger" app