/usr/lib/python3/dist-packages/pyutilib/component/config/logging_config.py is in python3-pyutilib 5.3.5-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | # _________________________________________________________________________
#
# PyUtilib: A Python utility library.
# Copyright (c) 2008 Sandia Corporation.
# This software is distributed under the BSD License.
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
# _________________________________________________________________________
"""A plugin that supports global configuration of logging options for pyutilib.component.core."""
import os.path
import logging
import logging.handlers as handlers
from pyutilib.component.config.env_config import *
from pyutilib.component.config.options import *
class LoggingConfig(Plugin):
"""A plugin that supports global configuration of logging options."""
implements(IUpdatedOptionsAction)
def __init__(self, namespace):
"""Initialize logging information for a specified namespace"""
self._hdlr=None
self.namespace=namespace
self.env_plugins = ExtensionPoint(IEnvironmentConfig)
if self.namespace == "":
section = "logging"
section_re = None
else:
section = "logging."+namespace
section_re = "^logging$"
#
declare_option("timestamp", section=section, section_re=section_re,
default=False,
doc="""Add timestamp to logging information.""")
#
declare_option("log_dir", section=section, section_re=section_re,
default=None,
doc="""The logging directory.
The default directory is the application directory plus 'log'.""")
#
declare_option("log_type", section=section, section_re=section_re,
default='none',
doc="""Logging facility to use.
Should be one of (`none`, `file`, `stderr`, `syslog`, `winlog`).""")
#
declare_option("log_file", section=section, section_re=section_re,
default=namespace+'.log',
doc="""If `log_type` is `file`, this should be a path to the log-file.""")
#
declare_option("log_level", section=section, section_re=section_re,
default='WARN',
doc="""Level of verbosity in log.
Should be one of (`CRITICAL`, `ERROR`, `WARN`, `INFO`, `DEBUG`).""")
#
declare_option("log_format", section=section, section_re=section_re,
default=None,
doc="""Custom logging format.
If nothing is set, the following will be used:
$(project)[$(env) $(module)] $(levelname): $(message)
In addition to regular key names supported by the Python logger library
library (see http://docs.python.org/lib/node422.html), one could use:
- $(path)s the path for the current environment
- $(basename)s the last path component of the current environment
- $(app)s the name of the current application
Note the usage of `$(...)s` instead of `%(...)s` as the latter form
would be interpreted by the ConfigParser itself.
""")
def reset_after_updates(self):
"""
Configure the pyutilib.component logging facility. This will
implicitly configure all of the environment-specific logging
objects.
"""
sys.stdout.flush()
logger = logging.getLogger('pyutilib.component.core.'+self.namespace)
if not self._hdlr is None:
logger.removeHandler(self._hdlr)
#
# Set logging level
#
level = self.log_level
level = level.upper()
if level in ('DEBUG', 'ALL'):
logger.setLevel(logging.DEBUG)
elif level == 'INFO':
logger.setLevel(logging.INFO)
elif level == 'ERROR':
logger.setLevel(logging.ERROR)
elif level == 'CRITICAL':
logger.setLevel(logging.CRITICAL)
else:
logger.setLevel(logging.WARNING)
#
# Initialize the current path. Is there a rule to use for whic
# environment will be used??? In practice, there is likely to be
# only one environment.
#
if self.log_dir is None:
path = None
for plugin in self.env_plugins:
(flag,count) = plugin.matches(self.namespace)
tmp = plugin.get_option("path")
if flag and not tmp is None:
path = tmp
break
if path is None:
path = os.getcwd()
else:
path = self.log_dir
#
# Setup the logging file
#
logtype = self.log_type.lower()
if self.log_file is None:
logfile = os.path.join(path, 'log')
else:
logfile = self.log_file
if not os.path.isabs(logfile):
logfile = os.path.join(path, logfile)
#
# Define the format
#
format = self.log_format
if format is None:
format = '[env=%(env)s where=%(module)s] %(levelname)s - %(message)s'
if self.timestamp and logtype in ('file', 'stderr'):
format = '%(asctime)s ' + format
format = format.replace('$(', '%(') \
.replace('%(env)s', PluginGlobals.get_env().name)
datefmt = ''
if self.timestamp and self.log_type == 'stderr':
datefmt = '%X'
formatter = logging.Formatter(format, datefmt)
#
# Define the handler
#
if logtype == 'file':
hdlr = logging.FileHandler(logfile)
elif logtype in ('winlog', 'eventlog', 'nteventlog'):
# Requires win32 extensions
hdlr = handlers.NTEventLogHandler(logid,
logtype='Application')
elif logtype in ('syslog', 'unix'):
hdlr = handlers.SysLogHandler('/dev/log')
elif logtype in ('stderr'):
hdlr = logging.StreamHandler(sys.stderr)
else:
hdlr = handlers.BufferingHandler(0)
# Note: this _really_ throws away log events, as a `MemoryHandler`
# would keep _all_ records in case there's no target handler (a bug?)
self._hdlr = hdlr
self._logtype = logtype
self._logfile = logfile
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
self._log = logger
def flush(self):
"""Flush logging I/O"""
self._hdlr.flush()
def shutdown(self):
#
# Q: should this shutdown _all_ logging?
#
logging.shutdown()
def log(self,message):
self._log.info(message)
|