MrDraw/src/octoprint/cli/server.py
Gina Häußge 1de307e15d Log version, safe mode & plugins to log on log roll over
We want to make sure that information is ALWAYS in each and every log.
2017-02-24 10:53:16 +01:00

222 lines
8 KiB
Python

# coding=utf-8
from __future__ import absolute_import, division, print_function
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
__copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms of the AGPLv3 License"
import click
import logging
import sys
from octoprint.cli import bulk_options, standard_options, set_ctx_obj_option, get_ctx_obj_option
def run_server(basedir, configfile, host, port, debug, allow_root, logging_config, verbosity, safe_mode, octoprint_daemon=None):
"""Initializes the environment and starts up the server."""
from octoprint import init_platform, __display_version__, FatalStartupError
def log_startup(recorder=None, safe_mode=None, **kwargs):
from octoprint.logging import get_divider_line
logger = logging.getLogger("octoprint.server")
logger.info(get_divider_line("*"))
logger.info("Starting OctoPrint {}".format(__display_version__))
if safe_mode:
logger.info("Starting in SAFE MODE. Third party plugins will be disabled!")
if recorder and len(recorder):
logger.info(get_divider_line("-", "Logged during platform initialization:"))
from octoprint.logging.handlers import CombinedLogHandler
handler = CombinedLogHandler(*logging.getLogger().handlers)
recorder.setTarget(handler)
recorder.flush()
logger.info(get_divider_line("-"))
from octoprint import urllib3_ssl
if not urllib3_ssl:
logging.getLogger("octoprint.server")\
.warn("requests/urllib3 will run in an insecure SSL environment. "
"You might see corresponding warnings logged later "
"(\"InsecurePlatformWarning\"). It is recommended to either "
"update to a Python version >= 2.7.9 or alternatively "
"install PyOpenSSL plus its dependencies. For details see "
"https://urllib3.readthedocs.org/en/latest/security.html#openssl-pyopenssl")
logger.info(get_divider_line("*"))
def log_register_rollover(safe_mode=None, plugin_manager=None, **kwargs):
from octoprint.logging import get_handler, log_to_handler, get_divider_line
from octoprint.logging.handlers import OctoPrintLogHandler
def rollover_callback():
handler = get_handler("file")
if handler is None:
return
logger = logging.getLogger("octoprint.server")
def _log(message, level=logging.INFO):
log_to_handler(logger, handler, level, message)
_log(get_divider_line("-", "Log roll over detected"))
_log("OctoPrint {}".format(__display_version__))
if safe_mode:
_log("SAFE MODE is active. Third party plugins are disabled!")
plugin_manager.log_all_plugins(only_to_handler=handler)
_log(get_divider_line("-"))
OctoPrintLogHandler.registerRolloverCallback(rollover_callback)
try:
settings, _, safe_mode, plugin_manager = init_platform(basedir,
configfile,
logging_file=logging_config,
debug=debug,
verbosity=verbosity,
uncaught_logger=__name__,
safe_mode=safe_mode,
after_safe_mode=log_startup,
after_plugin_manager=log_register_rollover)
except FatalStartupError as e:
click.echo(e.message, err=True)
click.echo("There was a fatal error starting up OctoPrint.", err=True)
else:
from octoprint.server import Server
octoprint_server = Server(settings=settings,
plugin_manager=plugin_manager,
host=host,
port=port,
debug=debug,
safe_mode=safe_mode,
allow_root=allow_root,
octoprint_daemon=octoprint_daemon)
octoprint_server.run()
#~~ server options
server_options = bulk_options([
click.option("--host", type=click.STRING, callback=set_ctx_obj_option,
help="Specify the host on which to bind the server."),
click.option("--port", type=click.INT, callback=set_ctx_obj_option,
help="Specify the port on which to bind the server."),
click.option("--logging", type=click.Path(), callback=set_ctx_obj_option,
help="Specify the config file to use for configuring logging."),
click.option("--iknowwhatimdoing", "allow_root", is_flag=True, callback=set_ctx_obj_option,
help="Allow OctoPrint to run as user root."),
click.option("--debug", is_flag=True, callback=set_ctx_obj_option,
help="Enable debug mode.")
])
"""Decorator to add the options shared among the server commands: ``--host``, ``--port``,
``--logging``, ``--iknowwhatimdoing`` and ``--debug``."""
daemon_options = bulk_options([
click.option("--pid", type=click.Path(), default="/tmp/octoprint.pid", callback=set_ctx_obj_option,
help="Pidfile to use for daemonizing.")
])
"""Decorator to add the options for the daemon subcommand: ``--pid``."""
#~~ "octoprint serve" and "octoprint daemon" commands
@click.group()
def server_commands():
pass
@server_commands.command(name="serve")
@server_options
@standard_options(hidden=True)
@click.pass_context
def serve_command(ctx, **kwargs):
"""Starts the OctoPrint server."""
def get_value(key):
return get_ctx_obj_option(ctx, key, kwargs.get(key))
host = get_value("host")
port = get_value("port")
logging = get_value("logging")
allow_root = get_value("allow_root")
debug = get_value("debug")
basedir = get_value("basedir")
configfile = get_value("configfile")
verbosity = get_value("verbosity")
safe_mode = get_value("safe_mode")
run_server(basedir, configfile, host, port, debug,
allow_root, logging, verbosity, safe_mode)
if sys.platform == "linux2":
# we only support daemon mode under Linux
@server_commands.command(name="daemon")
@server_options
@daemon_options
@standard_options(hidden=True)
@click.argument("command", type=click.Choice(["start", "stop", "restart", "status"]),
metavar="start|stop|restart|status")
@click.pass_context
def daemon_command(ctx, command, **kwargs):
"""
Starts, stops or restarts in daemon mode.
Please note that daemon mode is only supported under Linux right now.
"""
def get_value(key):
return get_ctx_obj_option(ctx, key, kwargs.get(key))
host = get_value("host")
port = get_value("port")
logging = get_value("logging")
allow_root = get_value("allow_root")
debug = get_value("debug")
pid = get_value("pid")
basedir = get_value("basedir")
configfile = get_value("configfile")
verbosity = get_value("verbosity")
safe_mode = get_value("safe_mode")
if pid is None:
click.echo("No path to a pidfile set",
file=sys.stderr)
sys.exit(1)
from octoprint.daemon import Daemon
class OctoPrintDaemon(Daemon):
def __init__(self, pidfile, basedir, configfile, host, port, debug, allow_root, logging_config, verbosity, safe_mode):
Daemon.__init__(self, pidfile)
self._basedir = basedir
self._configfile = configfile
self._host = host
self._port = port
self._debug = debug
self._allow_root = allow_root
self._logging_config = logging_config
self._verbosity = verbosity
self._safe_mode = safe_mode
def run(self):
run_server(self._basedir, self._configfile, self._host, self._port, self._debug,
self._allow_root, self._logging_config, self._verbosity, self._safe_mode,
octoprint_daemon=self)
octoprint_daemon = OctoPrintDaemon(pid, basedir, configfile, host, port, debug, allow_root, logging, verbosity,
safe_mode)
if command == "start":
octoprint_daemon.start()
elif command == "stop":
octoprint_daemon.stop()
elif command == "restart":
octoprint_daemon.restart()
elif command == "status":
octoprint_daemon.status()