Reviewers: ,
Please review this at http://codereview.tryton.org/831002/
Affected files:
M bin/trytond
M etc/trytond.conf
M trytond/config.py
A trytond/log.py
M trytond/protocols/dispatcher.py
M trytond/protocols/webdav.py
M trytond/server.py
Index: bin/trytond
===================================================================
--- a/bin/trytond
+++ b/bin/trytond
@@ -24,8 +24,6 @@
parser.add_option('--debug', dest='debug_mode', action='store_true',
help='enable debug mode (start post-mortem debugger if exceptions'
' occur)')
- parser.add_option("-v", "--verbose", action="store_true",
- dest="verbose", help="enable verbose mode")
parser.add_option("-d", "--database", dest="db_name",
help="specify the database name")
@@ -38,6 +36,9 @@
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('--log-level', dest='log_level',
+ help='verbosity of the messages recorded in the logs. One of: '
+ 'debug,info,warning,error,critical.')
parser.add_option("--disable-cron", dest="cron",
action="store_false", help="disable cron")
@@ -54,10 +55,10 @@
options['configfile'] = None
for arg in (
- 'verbose',
'debug_mode',
'pidfile',
'logfile',
+ 'log_level',
'cron',
):
if getattr(opt, arg) is not None:
Index: etc/trytond.conf
===================================================================
--- a/etc/trytond.conf
+++ b/etc/trytond.conf
@@ -47,6 +47,8 @@
# Configure the path of the files for the pid and the logs
#pidfile = False
#logfile = False
+# Configure log level (debug, info, warning, error, critical)
+#log_level = info
#privatekey = server.pem
#certificate = server.pem
Index: trytond/config.py
===================================================================
--- a/trytond/config.py
+++ b/trytond/config.py
@@ -57,10 +57,10 @@
'db_maxconn': 64,
'pg_path': None,
'admin_passwd': 'admin',
- 'verbose': False,
'debug_mode': False,
'pidfile': None,
'logfile': None,
+ 'log_level': 'info',
'privatekey': '/etc/ssl/trytond/server.key',
'certificate': '/etc/ssl/trytond/server.pem',
'smtp_server': 'localhost',
Index: trytond/log.py
===================================================================
new file mode 100644
--- /dev/null
+++ b/trytond/log.py
@@ -0,0 +1,55 @@
+#This file is part of Tryton. The COPYRIGHT file at the top level of
+#this repository contains the full copyright notices and license terms.
+
+from logging import Formatter, CRITICAL, ERROR, WARNING, INFO, DEBUG
+from sys import platform, stdout
+
+RESET_SEQ = "\x1b[0m"
+COLOR_SEQ = "%s%%s" + RESET_SEQ
+
+COLORS = {
+ 'DEBUG': COLOR_SEQ % "\x1b[36m", # light blue
+ 'INFO': COLOR_SEQ % "\x1b[1;1m", # bold white
+ 'WARNING': COLOR_SEQ % "\x1b[1;33m", # bold yellow
+ 'ERROR': COLOR_SEQ % "\x1b[1;31m", # bold red
+ 'CRITICAL': COLOR_SEQ % ("\x1b[1;33m\x1b[1;41m"), # bold yellow over
red
+}
+
+LOG_LEVELS = {
+ 'DEBUG': DEBUG,
+ 'INFO': INFO,
+ 'WARNING': WARNING,
+ 'ERROR': ERROR,
+ 'CRITICAL': CRITICAL,
+}
+
+
+def getLogLevel(name):
+ try:
+ return LOG_LEVELS[name.upper()]
+ except KeyError:
+ raise ValueError('Invalid log level: %s' % name)
+
+
+class ColoredFormatter(Formatter):
+ """
+ Class written by airmind:
+ http://stackoverflow.com/questions/384076/
+ """
+ def format(self, record):
+ levelname = record.levelname
+ msg = Formatter.format(self, record)
+ if levelname in COLORS:
+ if stdout.isatty():
+ msg = COLORS[levelname] % msg
+ else:
+ print ("*" * 100, levelname, "(%s)" % type(levelname), "not
in",
+ COLORS.keys())
+ return msg
+
+
+def createColoredFormatter(stream, fmt, datefmt):
+ if (platform != 'win32'):
+ return ColoredFormatter(fmt=fmt, datefmt=datefmt)
+ else:
+ return Formatter('%(message)s')
Index: trytond/protocols/dispatcher.py
===================================================================
--- a/trytond/protocols/dispatcher.py
+++ b/trytond/protocols/dispatcher.py
@@ -172,12 +172,12 @@
continue
raise
except Exception, exception:
- if CONFIG['verbose'] and not isinstance(exception, (
+ if not isinstance(exception, (
NotLogged, ConcurrencyException, UserError,
UserWarning)):
tb_s
= ''.join(traceback.format_exception(*sys.exc_info()))
logger = logging.getLogger('dispatcher')
- logger.error('Exception calling method %s on '
+ logger.debug('Exception calling method %s on '
'%s %s from %s@%s:%d/%s:\n'
% (method, object_type, object_name, user, host,
port,
database_name) + tb_s)
Index: trytond/protocols/webdav.py
===================================================================
--- a/trytond/protocols/webdav.py
+++ b/trytond/protocols/webdav.py
@@ -131,12 +131,12 @@
self.verbose = False
def _log_exception(self, exception):
- if CONFIG['verbose'] and not isinstance(exception, (
+ if not isinstance(exception, (
NotLogged, ConcurrencyException, UserError,
UserWarning,
DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden)):
tb_s = ''.join(traceback.format_exception(*sys.exc_info()))
logger = logging.getLogger('webdav')
- logger.error('Exception:\n' + tb_s)
+ logger.debug('Exception:\n' + tb_s)
@staticmethod
def get_dburi(uri):
Index: trytond/server.py
===================================================================
--- a/trytond/server.py
+++ b/trytond/server.py
@@ -10,6 +10,7 @@
import signal
import time
from trytond.config import CONFIG
+from trytond.log import createColoredFormatter, getLogLevel
from getpass import getpass
import hashlib
import threading
@@ -22,13 +23,13 @@
def __init__(self, options):
format = '[%(asctime)s] %(levelname)s:%(name)s:%(message)s'
datefmt = '%a %b %d %H:%M:%S %Y'
- logging.basicConfig(level=logging.INFO, format=format,
- datefmt=datefmt)
CONFIG.update_etc(options['configfile'])
CONFIG.update_cmdline(options)
CONFIG.set_timezone()
+ logging.getLogger().setLevel(getLogLevel(CONFIG['log_level']))
+
if CONFIG['logfile']:
logf = CONFIG['logfile']
# test if the directories exist, else create them
@@ -41,8 +42,8 @@
handler.rolloverAt -= diff
except Exception, exception:
sys.stderr.write(
- "ERROR: couldn't create the logfile directory:"
- + str(exception))
+ "ERROR: couldn't create the logfile directory:%s\n"
+ % exception)
else:
formatter = logging.Formatter(format, datefmt)
# tell the handler to use this format
@@ -50,14 +51,11 @@
# add the handler to the root logger
logging.getLogger().addHandler(handler)
- logging.getLogger().setLevel(logging.INFO)
- elif os.name != 'nt':
- reverse = '\x1b[7m'
- reset = '\x1b[0m'
- # reverse color for error and critical messages
- for level in logging.ERROR, logging.CRITICAL:
- msg = reverse + logging.getLevelName(level) + reset
- logging.addLevelName(level, msg)
+
+ default_handler = logging.StreamHandler(sys.stdout)
+ formatter = createColoredFormatter(sys.stdout, format, datefmt)
+ default_handler.setFormatter(formatter)
+ logging.getLogger().addHandler(default_handler)
self.logger = logging.getLogger("server")