add an option to change access_log using gunicorn

This commit is contained in:
Sergey Fedoruk 2018-12-29 23:56:01 +01:00 committed by Sergey Fedoruk
parent cea1547e08
commit d76d5e2c5f
3 changed files with 97 additions and 0 deletions

View File

@ -15,6 +15,7 @@ keyword arguments:
- `protocol` *(default `HttpProtocol`)*: Subclass
of
[asyncio.protocol](https://docs.python.org/3/library/asyncio-protocol.html#protocol-classes).
- `access_log` *(default `True`)*: Enables log on handling requests (significantly slows server).
## Workers
@ -63,6 +64,20 @@ of the memory leak.
See the [Gunicorn Docs](http://docs.gunicorn.org/en/latest/settings.html#max-requests) for more information.
## Disable debug logging
To improve the performance add `debug=False` and `access_log=False` in the `run` arguments.
```python
app.run(host='0.0.0.0', port=1337, workers=4, debug=False, access_log=False)
```
Running via Gunicorn you can set `--log-level` higher than `info` to not get any access logs anymore.
```
gunicorn myapp:app --bind 0.0.0.0:1337 --worker-class sanic.worker.GunicornWorker --log-level warning
```
## Asynchronous support
This is suitable if you *need* to share the sanic process with other applications, in particular the `loop`.
However be advised that this method does not support using multiple processes, and is not the preferred way

View File

@ -57,6 +57,10 @@ class GunicornWorker(base.Worker):
if self.app.callable.websocket_enabled
else self.http_protocol
)
# set ACCESS_LOG on base of logging level
self.app.callable.config.ACCESS_LOG = self.log.loglevel <= logging.INFO
self._server_settings = self.app.callable._helper(
loop=self.loop,
debug=is_debug,

View File

@ -4,6 +4,7 @@ import shlex
import subprocess
import urllib.request
from unittest import mock
from urllib.error import HTTPError
from sanic.worker import GunicornWorker
from sanic.app import Sanic
import asyncio
@ -24,12 +25,89 @@ def gunicorn_worker():
worker.kill()
@pytest.fixture(scope='module')
def gunicorn_worker_log_level_info():
command = (
'gunicorn '
'--bind 127.0.0.1:1338 '
'--worker-class sanic.worker.GunicornWorker '
'--log-level info '
'examples.simple_server:app'
)
worker = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
time.sleep(2)
return worker
@pytest.fixture(scope='module')
def gunicorn_worker_log_level_warning():
command = (
'gunicorn '
'--bind 127.0.0.1:1339 '
'--worker-class sanic.worker.GunicornWorker '
'--log-level warning '
'examples.simple_server:app'
)
worker = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
time.sleep(2)
return worker
@pytest.fixture(scope='module')
def gunicorn_worker_log_level_warning2():
command = (
'gunicorn '
'--bind 127.0.0.1:1340 '
'--worker-class sanic.worker.GunicornWorker '
'--log-level warning '
'examples.exception_monitoring:app'
)
worker = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
time.sleep(2)
return worker
def test_gunicorn_worker(gunicorn_worker):
with urllib.request.urlopen("http://localhost:1337/") as f:
res = json.loads(f.read(100).decode())
assert res["test"]
def test_gunicorn_worker_logs_info(gunicorn_worker_log_level_info):
"""
on base of our log-level we get an access message
"""
with urllib.request.urlopen('http://localhost:1338/') as _:
gunicorn_worker_log_level_info.kill()
assert b"(sanic.access)[INFO][127.0.0.1" in gunicorn_worker_log_level_info.stdout.read()
def test_gunicorn_worker_logs_warning(gunicorn_worker_log_level_warning):
"""
with log-level warning we are not getting an access messages anymore
"""
with urllib.request.urlopen('http://localhost:1339/') as _:
gunicorn_worker_log_level_warning.kill()
assert not gunicorn_worker_log_level_warning.stdout.read()
def test_gunicorn_worker_logs_warning_on_error(gunicorn_worker_log_level_warning2):
"""
with log-level warning we get an error log but don't get an access log
"""
try:
url = urllib.request.urlopen('http://localhost:1340/')
except HTTPError:
pass
else:
url.close()
gunicorn_worker_log_level_warning2.kill()
log_message = gunicorn_worker_log_level_warning2.stdout.read()
assert b"(sanic.access)[INFO][127.0.0.1" not in log_message
assert b"[ERROR] Exception occurred while handling uri" in log_message
class GunicornTestWorker(GunicornWorker):
def __init__(self):
self.app = mock.Mock()