Currently I am running my sanic(microframework) webservice with gunicorn as a daemon and I would like to save all logs in files(access and error)

My config:

reload = Truedaemon = Truebind = '0.0.0.0:6666'worker_class = 'sanic.worker.GunicornWorker'loglevel = 'debug'accesslog = 'access.log'access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'errorlog = 'error.log'

Next I start the webservice:

gunicorn --config config.py app:app

So, my errorlog works, but I get absolutely no accesslogs.

There are no hints in the documentation about this issue, could anybody help me?

5

Best Answer


could you try :

gunicorn --config config.py app:app --access-logfile '-'

And see if anything is logged on stdout(console output)?

I think you could simply from the sanic framework directly.

check the link

How to change the default sanic log directory to a custom directory?

You should pass a log config to the Sanic App and set the a file instead of sys.stdout as stream for the access log handler.

app = Sanic('test', log_config=CUSTOM_LOGIN_CONFIG)

You can copy the default config from log.py in the sanic folder

accesslog_file = open('accesslog_file.log','w')CUSTOM_LOGIN_CONFIG = dict(version=1,disable_existing_loggers=False,loggers={"root": {"level": "INFO","handlers": ["console"]},"sanic.error": {"level": "INFO","handlers": ["error_console"],"propagate": True,"qualname": "sanic.error"},"sanic.access": {"level": "INFO","handlers": ["access_console"],"propagate": True,"qualname": "sanic.access"}},handlers={"console": {"class": "logging.StreamHandler","formatter": "generic","stream": sys.stdout},"error_console": {"class": "logging.StreamHandler","formatter": "generic","stream": sys.stdout},"access_console": {"class": "logging.StreamHandler","formatter": "access","stream": accesslog_file},},formatters={"generic": {"format": "%(asctime)s [%(process)d] [%(levelname)s] %(message)s","datefmt": "[%Y-%m-%d %H:%M:%S %z]","class": "logging.Formatter"},"access": {"format": "%(asctime)s - (%(name)s)[%(levelname)s][%(host)s]: " +"%(request)s %(message)s %(status)d %(byte)d","datefmt": "[%Y-%m-%d %H:%M:%S %z]","class": "logging.Formatter"},})

This is gonna work even if you run the the app with gunicorn.

use supervisord to start the gunicorn service with logging parameters.

[program:sanic]directory=/home/ubuntu/apicommand=/home/ubuntu/api/venv/bin/gunicorn api:app --bind 0.0.0.0:8000 --worker-class sanic.worker.GunicornWorker -w 2stderr_logfile = log/api_stderr.logstdout_logfile = log/api_stdout.log

This works perfectly for me so I can just tail -f log/api_stderr.log

If You are using logging.config.fileConfig('someFile.conf'), make sure that You use disable_existing_loggers=False argument, so it will be:

logging.config.fileConfig('someFile.conf', disable_existing_loggers=False)

Documentation here: https://docs.python.org/3.7/library/logging.config.html#logging.config.fileConfig

Otherwise access logs are suppressed.

Leaving existing loggers alive might lead to appearing of other logs, for example, from requests or urllib3 library. Do not worry, just disable at the next line, if You do not need them:

logging.getLogger("urllib3").setLevel(logging.WARNING)