Sanic: disable access logger for specific routes/blueprints?

Created on 26 Aug 2018  路  6Comments  路  Source: sanic-org/sanic

Hi everyone,

we have a /ping route for health checks, and we do want to have access logs, however outside the formatting rules for the logger is there a away (using a decorator maybe) to disable just for that route/blueprint ?

documentation stale

Most helpful comment

@reifba

from sanic import Sanic
from sanic.log import access_logger
from sanic.response import json
from logging import Filter


class CustomSanic(Sanic):
    def route(
        self,
        uri,
        methods=frozenset({"GET"}),
        host=None,
        strict_slashes=None,
        stream=False,
        version=None,
        name=None,
        no_access_log_on_success=False
    ):
        if no_access_log_on_success:
            class _Filter(Filter):
                def filter(self, record):
                    return not (record.request.endswith(uri) and record.status == 200)
            access_logger.addFilter(_Filter())

        return super(CustomSanic, self).route(
            uri=uri, methods=methods, host=host, strict_slashes=strict_slashes,
            stream=stream, version=version, name=name
        )


app = CustomSanic(__name__)

@app.route("/", no_access_log_on_success=True)
def default(request):
    return json({
        "msg": "TEST"
    })

This modifies the route registration mechanism to do the same operation you are doing but avoids having to write custom filters manually for each of your APIs. This can be used as a generic banket extension mechanism

All 6 comments

Have you looked at using middleware? Will ook into decorator, but currently I have a if statement looking like:

class RequestLogging(object):
    def request(self, request):
        # print(request)
        if not request.headers.get('user-agent') == 'ELB-HealthChecker/2.0':
            print('\n[request] - {}'.format(request))
            print('[Request HEADERS] {}'.format(request.headers))

request_logging = RequestLogging()
response_logging = ResponseLogging()
# logging
@app.middleware('request')
async def print_on_request(request):
    # request.headers['Ctrl-Request-Id'] = str(uuid.uuid1())
    request_logging.request(request)

This is what we ended up with:

import logging
from sanic.log import access_logger

class PingFilter(logging.Filter):
    def filter(self, record):
        return not (record.request.endswith("/ping") and record.status == 200)


def setup_log_filtering():
    access_logger.addFilter(PingFilter())

Not a bad idea. In the future we may add some changes to the config to allow for route specific changes. Until then, it looks like this has been answered so I am closing.

@ahopkins We should probably add this to the documentation section under logging, @reifba 's solution can be super useful.

@reifba

from sanic import Sanic
from sanic.log import access_logger
from sanic.response import json
from logging import Filter


class CustomSanic(Sanic):
    def route(
        self,
        uri,
        methods=frozenset({"GET"}),
        host=None,
        strict_slashes=None,
        stream=False,
        version=None,
        name=None,
        no_access_log_on_success=False
    ):
        if no_access_log_on_success:
            class _Filter(Filter):
                def filter(self, record):
                    return not (record.request.endswith(uri) and record.status == 200)
            access_logger.addFilter(_Filter())

        return super(CustomSanic, self).route(
            uri=uri, methods=methods, host=host, strict_slashes=strict_slashes,
            stream=stream, version=version, name=name
        )


app = CustomSanic(__name__)

@app.route("/", no_access_log_on_success=True)
def default(request):
    return json({
        "msg": "TEST"
    })

This modifies the route registration mechanism to do the same operation you are doing but avoids having to write custom filters manually for each of your APIs. This can be used as a generic banket extension mechanism

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If this is incorrect, please respond with an update. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings