Skip to content
Permalink
Browse files

Shift default configuration to production-friendly values

The out-of-the-box configuration for the server is now geared toward
production rather than development so that there is less need for
supplemental configuration. This makes the deployment process slightly
easier.

Part of this change involves removing file-based application and
access logs, which were redundant with the logging that is already
happening through systemd and nginx. Additional configuration logic
was added to get CherryPy not to write access logs to stdout.
  • Loading branch information...
lovett committed Apr 13, 2019
1 parent 18c2377 commit f17ac209ca3aa93bce169bcc4c9955971245323b
Showing with 39 additions and 51 deletions.
  1. +7 −7 README.md
  2. +0 −1 ansible/roles/system/tasks/main.yml
  3. +32 −43 medley.py
@@ -67,7 +67,7 @@ Sqlite databases. Default: `./db`

**engine.autoreload.on**: Whether the CherryPy webserver should watch
for changes to application files and restart itself. Only useful in
development. Default: `True`
development. Default: `False`

**local_maintenance**: Whether the server should allow requests
from localhost that perform cleanup and maintenance operations. These
@@ -77,22 +77,22 @@ when the application is otherwise dormant. Default: `True`
**log.screen**: Whether requests should be written to the stdout of the
tty running the server process. Default: `True`

**log_dir**: The path to the directory that should be used for access
logs. Default: `./logs`
**log.screen_access**: Whether access logs should be written to stdout
when screen logging is enabled. Default: `False`

**memorize_checksums**: Whether the server should keep static asset file
hashes in memory for use with HTTP cache control. Useful in production
but counterproductive in development. Default: `False`
but counterproductive in development. Default: `True`

**request.show_tracebacks**: Whether CherryPy should display Python
trackebacks when errors occur. Default: `True`
trackebacks when errors occur. Default: `False`

**server.daemonize**: Whether the CherryPy server should run as a
daemon. Not meaningful in production unless systemd is not being
used. Default: `False`

**server.socket_host**: The IP the server should listen on. Default:
`0.0.0.0`
`127.0.0.1`

**server.socket_port**: The port the server should listen on. Default:
`8085`
@@ -101,7 +101,7 @@ used. Default: `False`
authorization. Default: `False`

**users**: If using conditional auth, a Python dictionary of usernames
and passwords for Basic Auth. Default: `None`
and passwords for Basic Auth. Default: `{}`

**tools.conditional_auth.whitelist**: If using conditional auth, a
space-separated string of IP addresses or fragments that are allowed
@@ -31,7 +31,6 @@
group="{{ project_group }}"
mode=0775
with_items:
- /var/log/{{ project_name }}
- /var/cache/{{ project_name }}
- /var/cache/{{ project_name }}/speak

@@ -11,7 +11,6 @@

import importlib
import logging
import logging.config
import os
import os.path
import cherrypy
@@ -31,21 +30,27 @@ def main():
server_root = os.path.dirname(os.path.abspath(__file__))
app_root = os.path.join(server_root, "apps")

# Configuration - default values
# Configuration defaults
#
# These are reasonable values for a production environment.
cherrypy.config.update({
"cache_dir": "./cache",
"database_dir": "./db",
"engine.autoreload.on": True,
"engine.autoreload.on": False,
"local_maintenance": True,
"log.screen": True,
"log_dir": "./logs",
"memorize_checksums": False,
"request.show_tracebacks": True,
"log.screen_access": False,
"log.access_file": "",
"log.error_file": "",
"memorize_checksums": True,
"request.show_tracebacks": False,
"server.daemonize": False,
"server.socket_host": "0.0.0.0",
"server.socket_host": "127.0.0.1",
"server.socket_port": 8085,
"server_root": server_root,
"tools.conditional_auth.on": False,
"users": {},
"tools.conditional_auth.whitelist": "",

# Jinja templating won't work unless tools.encode is off
"tools.encode.on": False,
@@ -69,6 +74,11 @@ def main():
if os.path.isfile(candidate)),
)
cherrypy.config.update(config)

cherrypy.log("Configuration overrides loaded from {}".format(
config
))

except StopIteration:
pass

@@ -79,8 +89,9 @@ def main():

# Directory creation
#
# Filesystem paths declared by the config are expected to exist.
for key in ("database_dir", "cache_dir", "log_dir"):
# Filesystem paths specified in the configuration are expected to
# already exist. Try to create them if they don't.
for key in ("database_dir", "cache_dir"):
value = cherrypy.config.get(key)

try:
@@ -184,40 +195,18 @@ def main():
cherrypy.tools.negotiable = tools.negotiable.Tool()
cherrypy.tools.capture = tools.capture.Tool()

# Logging
error_log_handler = logging.handlers.TimedRotatingFileHandler(
os.path.join(
cherrypy.config.get("log_dir"),
"error.log"
),
when="D",
interval=1,
backupCount=14,
encoding="utf8"
)
error_log_handler.setLevel(logging.INFO)

# pylint: disable=protected-access
error_log_handler.setFormatter(cherrypy._cplogging.logfmt)

cherrypy.log.error_log.addHandler(error_log_handler)

access_log_handler = logging.handlers.TimedRotatingFileHandler(
os.path.join(
cherrypy.config.get("log_dir"),
"access.log"
),
when="D",
interval=1,
backupCount=14,
encoding="utf8"
)
access_log_handler.setLevel(logging.INFO)

# pylint: disable=protected-access
access_log_handler.setFormatter(cherrypy._cplogging.logfmt)

cherrypy.log.access_log.addHandler(access_log_handler)
# Disable access logging to the console
#
# This changes CherryPy's default behavior, which is to send
# access and error logs to the screen when screen logging is
# enabled. Turning off one but not the other only works when
# logging to files.
#
# The log.screen_access config key is unique to this project.
if not cherrypy.config.get("log.screen_access"):
for handler in cherrypy.log.access_log.handlers:
if isinstance(handler, logging.StreamHandler):
cherrypy.log.access_log.handlers.remove(handler)

cherrypy.engine.start()
cherrypy.engine.publish("scheduler:revive")

0 comments on commit f17ac20

Please sign in to comment.
You can’t perform that action at this time.