I am working in a Flask application which is wrapped by Gunicorn. My custom log configuration below seems to work as long as I remove the references to my custom filter. But as soon as I add the filter into the config, then I get the following error: Error: Working outside of application context. I have also tried:

with app.app_context():
    logging.config.dictConfig(logging_cfg)

But it changed nothing. Here is my app factory class:

def create_app(testing=False):
    app = Flask(__name__)

    class CustomApi(flask_restful.Api):
        def handle_error(self, error):
            return global_error_handler(error)

    class DeeIdFilter(logging.Filter):
        def filter(self, record):
            record.some_id = g.get("some_id")
            return True

    logging_cfg = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'KeyValueFormatter': {
                'format': 'loglevel=%(levelname)s id=%(some_id)s msg=%(message)s'
            },
        },
        'handlers': {
            'console': {
                'level': 'INFO',
                'class': 'logging.StreamHandler',
                'formatter': 'KeyValueFormatter',
                'filters': ['IdFilter']
            }
        },
        'loggers': {
            'gunicorn.access': {
                'propagate': True
            },
            'gunicorn.error': {
                'propagate': True
            },
        },
        'root': {
            'level': 'INFO',
            'handlers': ['console']
        },
        'filters': {
            'IdFilter': {
                '()': IdFilter
            }
        }
    }
    
    logging.config.dictConfig(logging_cfg)
    return app
1

There are 1 best solutions below

0
Justin Furuness On

I can't seem to get the code to run or reproduce the error, so it's difficult to test this. However, my guess would be that you need to use the app context within the filter, as such:

    class DeeIdFilter(logging.Filter):
        def filter(self, record):
            with app.app_context():
                record.some_id = g.get("some_id")
                return True