Source code for x2gobroker.loggers
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
# Copyright (C) 2012-2020 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#
# X2Go Session Broker is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# X2Go Session Broker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
"""\
The :mod:`x2gobroker.loggers` module provides three different logger objects for different purposes:
* ``logger_broker``: Logging of all sort of things happening in X2Go Session Broker
* ``logger_access``: Logging of http/https access of the broker's httpd daemon
* ``logger_error``: Logging of errors encountered at runtime
All ``logger_*`` objects are instantiated via the function :func:`logging.getLogger()` from the :mod:`logging` module..
Depending on the execution context (as a service, in foreground for debugging, as SSH broker), these logging objects are set up slighly different.
"""
import os
import sys
import pwd
import getpass
import logging
import logging.config
import configparser
[docs]
def init_console_loggers():
"""\
Initialize loggers that log to stderr.
:returns: a 3-tuple of (logger_broker, logger_access, logger_error)
:rtype: ``tuple``
"""
logger_root = logging.getLogger()
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setFormatter(logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt=''))
# all loggers stream to stderr...
logger_root.addHandler(stderr_handler)
logger_broker = logging.getLogger('broker')
logger_broker.addHandler(stderr_handler)
logger_broker.propagate = 0
logger_access = logging.getLogger('access')
logger_access.addHandler(stderr_handler)
logger_access.propagate = 0
logger_error = logging.getLogger('error')
logger_error.addHandler(stderr_handler)
logger_error.propagate = 0
return (logger_broker, logger_access, logger_error)
PROG_NAME = os.path.basename(sys.argv[0])
# load the defaults.conf file, if present
iniconfig_loaded = None
iniconfig_section = '-'.join(PROG_NAME.split('-')[1:])
X2GOBROKER_DEFAULTS = "/etc/x2go/broker/defaults.conf"
if os.path.isfile(X2GOBROKER_DEFAULTS) and os.access(X2GOBROKER_DEFAULTS, os.R_OK):
iniconfig = configparser.RawConfigParser()
iniconfig.optionxform = str
iniconfig_loaded = iniconfig.read(X2GOBROKER_DEFAULTS)
# normally this would go into defaults.py, however, we do not want to create a dependency loop between loggers.py and defaults.py...
if 'X2GOBROKER_DAEMON_USER' in os.environ:
X2GOBROKER_DAEMON_USER=os.environ['X2GOBROKER_DAEMON_USER']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_DAEMON_USER'):
X2GOBROKER_DAEMON_USER=iniconfig.get(iniconfig_section, 'X2GOBROKER_DAEMON_USER')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_DAEMON_USER'):
X2GOBROKER_DAEMON_USER=iniconfig.get('common', 'X2GOBROKER_DAEMON_USER')
else:
X2GOBROKER_DAEMON_USER="x2gobroker"
if 'X2GOBROKER_LOGCONFIG' in os.environ:
X2GOBROKER_LOGCONFIG=os.environ['X2GOBROKER_LOGCONFIG']
elif iniconfig_loaded and iniconfig.has_option(iniconfig_section, 'X2GOBROKER_LOGCONFIG'):
X2GOBROKER_LOGCONFIG=iniconfig.get(iniconfig_section, 'X2GOBROKER_LOGCONFIG')
elif iniconfig_loaded and iniconfig.has_option('common', 'X2GOBROKER_LOGCONFIG'):
X2GOBROKER_LOGCONFIG=iniconfig.get('common', 'X2GOBROKER_LOGCONFIG')
else:
X2GOBROKER_LOGCONFIG="/etc/x2go/broker/x2gobroker-loggers.conf"
# standalone daemon mode (x2gobroker-daemon)? or x2gobroker-ssh command invocation?
if (
(getpass.getuser() in (X2GOBROKER_DAEMON_USER, 'root')) or
(pwd.getpwuid(os.geteuid()).pw_name in (X2GOBROKER_DAEMON_USER, 'root'))
) and os.path.exists(X2GOBROKER_LOGCONFIG):
# we run in standalone daemon mode or broker via SSH (with correct setup),
# so let's use the system configuration for logging
logging.config.fileConfig(X2GOBROKER_LOGCONFIG)
# create loggers
logger_broker = logging.getLogger('broker')
logger_access = logging.getLogger('access')
logger_error = logging.getLogger('error')
else:
# or interactive mode (called from the cmdline)?
logger_broker, logger_access, logger_error = init_console_loggers()
[docs]
def tornado_log_request(handler):
"""\
Function for overriding the :func:`log_request() <tornado.web.RequestHandler>` method in
:class:`tornado.web.RequestHandler`.
:param handler: handler
:type handler: ``obj``
"""
if handler.get_status() < 400:
log_method = logger_access.info
elif handler.get_status() < 500:
log_method = logger_access.warning
else:
log_method = logger_error.error
request_time = 1000.0 * handler.request.request_time()
log_method("%d %s %.2fms", handler.get_status(),
handler._request_summary(), request_time)