add unit tests/refactoring

This commit is contained in:
Yun Xu 2017-09-12 23:42:42 -07:00
parent a46e004f07
commit 24bdb1ce98
5 changed files with 61 additions and 15 deletions

View File

@ -14,7 +14,7 @@ from sanic.config import Config
from sanic.constants import HTTP_METHODS from sanic.constants import HTTP_METHODS
from sanic.exceptions import ServerError, URLBuildError, SanicException from sanic.exceptions import ServerError, URLBuildError, SanicException
from sanic.handlers import ErrorHandler from sanic.handlers import ErrorHandler
from sanic.log import logger, error_logger from sanic.log import logger, error_logger, LOGGING_CONFIG_DEFAULTS
from sanic.response import HTTPResponse, StreamingHTTPResponse from sanic.response import HTTPResponse, StreamingHTTPResponse
from sanic.router import Router from sanic.router import Router
from sanic.server import serve, serve_multiple, HttpProtocol, Signal from sanic.server import serve, serve_multiple, HttpProtocol, Signal
@ -28,13 +28,16 @@ class Sanic:
def __init__(self, name=None, router=None, error_handler=None, def __init__(self, name=None, router=None, error_handler=None,
load_env=True, request_class=None, load_env=True, request_class=None,
strict_slashes=False): strict_slashes=False, log_config=None):
# Get name from previous stack frame # Get name from previous stack frame
if name is None: if name is None:
frame_records = stack()[1] frame_records = stack()[1]
name = getmodulename(frame_records[1]) name = getmodulename(frame_records[1])
# logging
logging.config.dictConfig(log_config or LOGGING_CONFIG_DEFAULTS)
self.name = name self.name = name
self.router = router or Router() self.router = router or Router()
self.request_class = request_class self.request_class = request_class
@ -567,7 +570,7 @@ class Sanic:
def run(self, host=None, port=None, debug=False, ssl=None, def run(self, host=None, port=None, debug=False, ssl=None,
sock=None, workers=1, protocol=None, sock=None, workers=1, protocol=None,
backlog=100, stop_event=None, register_sys_signals=True, backlog=100, stop_event=None, register_sys_signals=True,
access_log=True): access_log=True, log_config=None):
"""Run the HTTP Server and listen until keyboard interrupt or term """Run the HTTP Server and listen until keyboard interrupt or term
signal. On termination, drain connections before closing. signal. On termination, drain connections before closing.
@ -585,6 +588,8 @@ class Sanic:
:param protocol: Subclass of asyncio protocol class :param protocol: Subclass of asyncio protocol class
:return: Nothing :return: Nothing
""" """
logging.config.dictConfig(log_config or LOGGING_CONFIG_DEFAULTS)
if sock is None: if sock is None:
host, port = host or "127.0.0.1", port or 8000 host, port = host or "127.0.0.1", port or 8000
@ -627,12 +632,14 @@ class Sanic:
async def create_server(self, host=None, port=None, debug=False, async def create_server(self, host=None, port=None, debug=False,
ssl=None, sock=None, protocol=None, ssl=None, sock=None, protocol=None,
backlog=100, stop_event=None, backlog=100, stop_event=None,
access_log=True): access_log=True, log_config=None):
"""Asynchronous version of `run`. """Asynchronous version of `run`.
NOTE: This does not support multiprocessing and is not the preferred NOTE: This does not support multiprocessing and is not the preferred
way to run a Sanic application. way to run a Sanic application.
""" """
logging.config.dictConfig(log_config or LOGGING_CONFIG_DEFAULTS)
if sock is None: if sock is None:
host, port = host or "127.0.0.1", port or 8000 host, port = host or "127.0.0.1", port or 8000

View File

@ -4,14 +4,8 @@ import syslog
import platform import platform
import types import types
SANIC_PREFIX = 'SANIC_'
_address_dict = { SANIC_PREFIX = 'SANIC_'
'Windows': ('localhost', 514),
'Darwin': '/var/run/syslog',
'Linux': '/dev/log',
'FreeBSD': '/var/run/log'
}
class Config(dict): class Config(dict):

View File

@ -19,7 +19,7 @@ LOGGING_CONFIG_DEFAULTS = dict(
"sanic.access": { "sanic.access": {
"level": "INFO", "level": "INFO",
"handlers": ["console"], "handlers": ["access_console"],
"propagate": True, "propagate": True,
"qualname": "sanic.access" "qualname": "sanic.access"
} }
@ -35,13 +35,24 @@ LOGGING_CONFIG_DEFAULTS = dict(
"formatter": "generic", "formatter": "generic",
"stream": "sys.stderr" "stream": "sys.stderr"
}, },
"access_console": {
"class": "logging.StreamHandler",
"formatter": "access",
"stream": "sys.stdout"
},
}, },
formatters={ formatters={
"generic": { "generic": {
"format": "%(asctime)s [%(process)d] [%(levelname)s] %(message)s", "format": "%(asctime)s [%(process)d] [%(levelname)s] %(message)s",
"datefmt": "[%Y-%m-%d %H:%M:%S %z]", "datefmt": "[%Y-%m-%d %H:%M:%S %z]",
"class": "logging.Formatter" "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"
},
} }
) )

View File

@ -17,7 +17,7 @@ except ImportError:
json_loads = json.loads json_loads = json.loads
from sanic.exceptions import InvalidUsage from sanic.exceptions import InvalidUsage
from sanic.log import logger from sanic.log import error_logger
DEFAULT_HTTP_CONTENT_TYPE = "application/octet-stream" DEFAULT_HTTP_CONTENT_TYPE = "application/octet-stream"
@ -114,7 +114,7 @@ class Request(dict):
self.parsed_form, self.parsed_files = ( self.parsed_form, self.parsed_files = (
parse_multipart_form(self.body, boundary)) parse_multipart_form(self.body, boundary))
except Exception: except Exception:
logger.exception("Failed when parsing form") error_logger.exception("Failed when parsing form")
return self.parsed_form return self.parsed_form

View File

@ -2,6 +2,7 @@ import uuid
from importlib import reload from importlib import reload
from sanic.response import text from sanic.response import text
from sanic.log import LOGGING_CONFIG_DEFAULTS
from sanic import Sanic from sanic import Sanic
from io import StringIO from io import StringIO
import logging import logging
@ -37,3 +38,36 @@ def test_log():
request, response = app.test_client.get('/') request, response = app.test_client.get('/')
log_text = log_stream.getvalue() log_text = log_stream.getvalue()
assert rand_string in log_text assert rand_string in log_text
def test_logging_defaults():
reset_logging()
app = Sanic("test_logging")
for fmt in [h.formatter for h in logging.getLogger('root').handlers]:
assert fmt._fmt == LOGGING_CONFIG_DEFAULTS['formatters']['generic']['format']
for fmt in [h.formatter for h in logging.getLogger('sanic.error').handlers]:
assert fmt._fmt == LOGGING_CONFIG_DEFAULTS['formatters']['generic']['format']
for fmt in [h.formatter for h in logging.getLogger('sanic.access').handlers]:
assert fmt._fmt == LOGGING_CONFIG_DEFAULTS['formatters']['access']['format']
def test_logging_pass_customer_logconfig():
reset_logging()
modified_config = LOGGING_CONFIG_DEFAULTS
modified_config['formatters']['generic']['format'] = '%(asctime)s - (%(name)s)[%(levelname)s]: %(message)s'
modified_config['formatters']['access']['format'] = '%(asctime)s - (%(name)s)[%(levelname)s]: %(message)s'
app = Sanic("test_logging", log_config=modified_config)
for fmt in [h.formatter for h in logging.getLogger('root').handlers]:
assert fmt._fmt == modified_config['formatters']['generic']['format']
for fmt in [h.formatter for h in logging.getLogger('sanic.error').handlers]:
assert fmt._fmt == modified_config['formatters']['generic']['format']
for fmt in [h.formatter for h in logging.getLogger('sanic.access').handlers]:
assert fmt._fmt == modified_config['formatters']['access']['format']