[IMP] Add a syslog handler

[IMP] Add an atexit callback to tell "Goodbye"
[IMP] Group the option for the logging
[IMP] Capability to disable the output to console with --log-level=notset

bzr revid: stephane@tinyerp.com-20081222230418-3ll0mqno8yz9z3jw
This commit is contained in:
Stephane Wirtel 2008-12-23 00:04:18 +01:00
parent 0a392bce47
commit cfc56e0b38
3 changed files with 66 additions and 16 deletions

View File

@ -36,6 +36,7 @@ import sys
import threading
import time
import xmlrpclib
import release
_service = {}
_group = {}
@ -139,6 +140,7 @@ class LocalService(Service):
def service_exist(name):
return (name in _service) and bool(_service[name])
LOG_NOTSET = 'notset'
LOG_DEBUG_RPC = 'debug_rpc'
LOG_DEBUG = 'debug'
LOG_INFO = 'info'
@ -153,7 +155,24 @@ def init_logger():
from tools import config
import os
logger = logging.getLogger()
if config['syslog']:
# SysLog Handler
if os.name == 'nt':
sysloghandler = logging.handlers.NTEventLogHandler("%s %s" %
(release.description,
release.version))
else:
sysloghandler = logging.handlers.SysLogHandler('/dev/log')
formatter = logging.Formatter('%(application)s:%(uncoloredlevelname)s:%(name)s:%(message)s')
sysloghandler.setFormatter(formatter)
logger.addHandler(sysloghandler)
# create a format for log messages and dates
formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s', '%a %b %d %Y %H:%M:%S')
if config['logfile']:
# LogFile Handler
logf = config['logfile']
try:
dirname = os.path.dirname(logf)
@ -164,19 +183,17 @@ def init_logger():
sys.stderr.write("ERROR: couldn't create the logfile directory\n")
handler = logging.StreamHandler(sys.stdout)
else:
# Normal Handler on standard output
handler = logging.StreamHandler(sys.stdout)
# create a format for log messages and dates
formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s', '%a %b %d %H:%M:%S %Y')
# tell the handler to use this format
handler.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger().addHandler(handler)
logging.getLogger().setLevel(config['log_level'])
logger.addHandler(handler)
logger.setLevel(config['log_level'])
if isinstance(handler, logging.StreamHandler) and os.name != 'nt':
# change color of level names
# uses of ANSI color codes
@ -201,21 +218,37 @@ def init_logger():
class Logger(object):
def uncoloredlevelname(self, level):
# The level'names are globals to all loggers, so we must strip-off the
# color formatting for some specific logger (i.e: syslog)
levelname = logging.getLevelName(getattr(logging, level.upper(), 0))
if levelname.startswith("\x1b["):
return levelname[10:-4]
return levelname
def notifyChannel(self, name, level, msg):
log = logging.getLogger(name)
if level == LOG_NOTSET:
return
if level == LOG_DEBUG_RPC and not hasattr(log, level):
fct = lambda msg, *args, **kwargs: log.log(logging.DEBUG_RPC, msg, *args, **kwargs)
setattr(log, LOG_DEBUG_RPC, fct)
extra = {
'uncoloredlevelname': self.uncoloredlevelname(level),
'application' : "%s %s" % (release.description, release.version),
}
level_method = getattr(log, level)
result = str(msg).strip().split('\n')
if len(result)>1:
for idx, s in enumerate(result):
level_method('[%02d]: %s' % (idx+1, s,))
level_method('[%02d]: %s' % (idx+1, s,), extra=extra)
elif result:
level_method(result[0])
level_method(result[0], extra=extra)
init_logger()

View File

@ -55,6 +55,14 @@ __version__ = release.version
import netsvc
logger = netsvc.Logger()
def atexit_callback():
logger.notifyChannel('shutdown', netsvc.LOG_INFO, "Shutdown Server!")
#logger.notifyChannel('pan! pan!', netsvc.LOG_INFO, "Killed Server ;-)")
import atexit
atexit.register(atexit_callback)
#-----------------------------------------------------------------------
# import the tools module so that the commandline parameters are parsed
#-----------------------------------------------------------------------

View File

@ -41,7 +41,6 @@ class configmanager(object):
def __init__(self, fname=None):
self.options = {
'email_from':False,
'verbose': False,
'interface': '', # this will bind the server to all interfaces
'port': '8069',
'netinterface': '',
@ -74,22 +73,22 @@ class configmanager(object):
'stop_after_init': False, # this will stop the server after initialization
'price_accuracy': 2,
'secure' : False,
'syslog' : False,
'log_level': logging.INFO,
'assert_exit_level': logging.WARNING, # level above which a failed assert will be raise
}
hasSSL = check_ssl()
loglevels = dict([(getattr(netsvc, 'LOG_%s' % x), getattr(logging, x)) for x in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'DEBUG_RPC')])
loglevels = dict([(getattr(netsvc, 'LOG_%s' % x), getattr(logging, x))
for x in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'DEBUG_RPC', 'NOTSET')])
version = "%s %s" % (release.description, release.version)
parser = optparse.OptionParser(version=version)
parser.add_option("-c", "--config", dest="config", help="specify alternate config file")
parser.add_option("-s", "--save", action="store_true", dest="save", default=False, help="save configuration to ~/.openerp_serverrc")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="enable debugging")
parser.add_option("--pidfile", dest="pidfile", help="file where the server pid will be stored")
parser.add_option("--logfile", dest="logfile", help="file where the server log will be stored")
parser.add_option("-n", "--interface", dest="interface", help="specify the TCP IP address")
parser.add_option("-p", "--port", dest="port", help="specify the TCP port")
@ -104,16 +103,26 @@ class configmanager(object):
# stops the server from launching after initialization
parser.add_option("--stop-after-init", action="store_true", dest="stop_after_init", default=False, help="stop the server after it initializes")
parser.add_option('--debug', dest='debug_mode', action='store_true', default=False, help='enable debug mode')
parser.add_option('--log-level', dest='log_level', type='choice', choices=loglevels.keys(), help='specify the level of the logging. Accepted values: ' + str(loglevels.keys()))
parser.add_option("--assert-exit-level", dest='assert_exit_level', type="choice", choices=loglevels.keys(), help="specify the level at which a failed assertion will stop the server. Accepted values: " + str(loglevels.keys()))
if hasSSL:
parser.add_option("-S", "--secure", dest="secure", action="store_true", help="launch server over https instead of http", default=False)
# Logging Group
group = optparse.OptionGroup(parser, "Logging Configuration")
group.add_option("--logfile", dest="logfile", help="file where the server log will be stored")
group.add_option("--syslog", action="store_true", dest="syslog",
default=False, help="Send the log to the syslog server")
group.add_option('--log-level', dest='log_level', type='choice', choices=loglevels.keys(),
help='specify the level of the logging. Accepted values: ' + str(loglevels.keys()))
parser.add_option_group(group)
# SMTP Group
group = optparse.OptionGroup(parser, "SMTP Configuration")
group.add_option('--email-from', dest='email_from', default='', help='specify the SMTP email address for sending email')
group.add_option('--smtp', dest='smtp_server', default='', help='specify the SMTP server for sending email')
group.add_option('--smtp-port', dest='smtp_port', default='25', help='specify the SMTP port')
group.add_option('--smtp-ssl', dest='smtp_ssl', default='', help='specify the SMTP server support SSL or not')
if hasSSL:
group.add_option('--smtp-ssl', dest='smtp_ssl', default='', help='specify the SMTP server support SSL or not')
group.add_option('--smtp-user', dest='smtp_user', default='', help='specify the SMTP username for sending email')
group.add_option('--smtp-password', dest='smtp_password', default='', help='specify the SMTP password for sending email')
group.add_option('--price_accuracy', dest='price_accuracy', default='2', help='specify the price accuracy')
@ -183,13 +192,13 @@ class configmanager(object):
if getattr(opt, arg):
self.options[arg] = getattr(opt, arg)
for arg in ('language', 'translate_out', 'translate_in',
'upgrade', 'verbose', 'debug_mode',
'stop_after_init', 'without_demo', 'netrpc', 'xmlrpc'):
for arg in ('language', 'translate_out', 'translate_in', 'upgrade', 'debug_mode',
'stop_after_init', 'without_demo', 'netrpc', 'xmlrpc', 'syslog'):
self.options[arg] = getattr(opt, arg)
if opt.assert_exit_level:
self.options['assert_exit_level'] = loglevels[opt.assert_exit_level]
if opt.log_level:
self.options['log_level'] = loglevels[opt.log_level]