Starlette: Is it possible to disable access logging on certain endpoints?

Created on 16 Mar 2020  路  9Comments  路  Source: encode/starlette

I have a /health endpoint that is checked every minute and it bloats the logs. I'd like to turn off that off, but keep logging the accesses to other endpoints (and especially any exceptions). Is that possible currently?

Most helpful comment

@euri10 your great solution can be implemented like that as well :smile:

class EndpointFilter(logging.Filter):
    def filter(self, record: logging.LogRecord) -> bool:
        return record.getMessage().find("/endpoint") == -1

# Filter out /endpoint
logging.getLogger("uvicorn.access").addFilter(EndpointFilter())

Will leave it here for reference in case there are people who don't want to deal with log config file

All 9 comments

I had the same issue, so I switched gunicorn and uvicorn loggers to warn:

[logger_gunicorn]
level=WARNING
handlers=access_handler
propagate=0
qualname=gunicorn

[logger_uvicorn]
level=WARNING
handlers=access_handler
propagate=0
qualname=uvicorn

In my own custom loggers used by my app, I have a logging config like this:

PRODUCTION_LOGGING_CONFIG = {
    "version": 1,
    "disable_existing_loggers": True,
    "formatters": {"json": {"class": "my_app.plumbing.loggers.MyJsonLogFormatter"}},
    "handlers": {
        "info": {"level": "INFO", "class": "logging.StreamHandler", "formatter": "json"},
        "warn": {"level": "WARNING", "class": "logging.StreamHandler", "formatter": "json"}
    },
    "loggers": {
        "": {"handlers": ["info"], "level": "INFO", "propagate": False,},
        "uvicorn": {"handlers": ["warn"], "level": "INFO", "propagate": False,},
    },
}

@erewok Does that disable all the logging at the INFO level?

No, because the root-level logger is still at INFO:

"": {"handlers": ["info"], "level": "INFO", "propagate": False,},

Also, for completeness, I instantiate it in my app like this:

import logging.config
logging.config.dictConfig(PRODUCTION_LOGGING_CONFIG)

@erewok I'm sorry, I'm just not seeing where you specify the endpoint to not log in the config(s).

Apologies, but I probably misunderstood. You want to keep access logging but just not log for /health? My mistake: I turned off access logging entirely because my application has a lot of other logs inside the endpoints and also have logs from our reverse proxy for access.

Well, now I know to look at uvicorn's logging instead of starlette's. Thanks, @erewok!

It's totally possible
Just do something like this

class HealthCheckFilter(logging.Filter):
    def filter(self, record):
        return record.getMessage().find("/healthcheck") == -1

then use it in your logging dict or yaml with

filters:
  healthcheck_filter:
    "()": applog.utils.HealthCheckFilter
handlers:
    console:
        class: logging.StreamHandler
        level: DEBUG
        formatter: simple
        filters:
            - healthcheck_filter
        stream: ext://sys.stdout

@euri10 your great solution can be implemented like that as well :smile:

class EndpointFilter(logging.Filter):
    def filter(self, record: logging.LogRecord) -> bool:
        return record.getMessage().find("/endpoint") == -1

# Filter out /endpoint
logging.getLogger("uvicorn.access").addFilter(EndpointFilter())

Will leave it here for reference in case there are people who don't want to deal with log config file

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jordic picture jordic  路  4Comments

Ekuzkamaza picture Ekuzkamaza  路  3Comments

tomchristie picture tomchristie  路  5Comments

koddr picture koddr  路  6Comments

jordic picture jordic  路  6Comments