X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=bin%2Fnetsvc.py;h=eae53826a74038e5514288b714622478f2bf509c;hb=a21dcd7e1c8623f4aaf3a3659e81247273f652e9;hp=11f7ca5b6955543c1ac781713587a0615542e548;hpb=7cf31b4869e49efa4013ddbcdf837ab94a739cf8;p=odoo%2Fodoo.git diff --git a/bin/netsvc.py b/bin/netsvc.py index 11f7ca5..eae5382 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -24,11 +24,8 @@ # ############################################################################## -import errno import logging import logging.handlers -import os -import socket import sys import threading import time @@ -103,12 +100,10 @@ class ExportService(object): _services = {} _groups = {} - _logger = logging.getLogger('web-services') def __init__(self, name, audience=''): ExportService._services[name] = self self.__name = name - self._logger.debug("Registered an exported service: %s" % name) def joinGroup(self, name): ExportService._groups.setdefault(name, {})[self.__name] = self @@ -130,7 +125,6 @@ class ExportService(object): raise LOG_NOTSET = 'notset' -LOG_DEBUG_SQL = 'debug_sql' LOG_DEBUG_RPC = 'debug_rpc' LOG_DEBUG = 'debug' LOG_TEST = 'test' @@ -141,57 +135,28 @@ LOG_CRITICAL = 'critical' logging.DEBUG_RPC = logging.DEBUG - 2 logging.addLevelName(logging.DEBUG_RPC, 'DEBUG_RPC') -logging.DEBUG_SQL = logging.DEBUG_RPC - 2 -logging.addLevelName(logging.DEBUG_SQL, 'DEBUG_SQL') logging.TEST = logging.INFO - 5 logging.addLevelName(logging.TEST, 'TEST') -BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10) -#The background is set with 40 plus the number of the color, and the foreground with 30 -#These are the sequences need to get colored ouput -RESET_SEQ = "\033[0m" -COLOR_SEQ = "\033[1;%dm" -BOLD_SEQ = "\033[1m" -COLOR_PATTERN = "%s%s%%s%s" % (COLOR_SEQ, COLOR_SEQ, RESET_SEQ) -LEVEL_COLOR_MAPPING = { - logging.DEBUG_SQL: (WHITE, MAGENTA), - logging.DEBUG_RPC: (BLUE, WHITE), - logging.DEBUG: (BLUE, DEFAULT), - logging.INFO: (GREEN, DEFAULT), - logging.TEST: (WHITE, BLUE), - logging.WARNING: (YELLOW, DEFAULT), - logging.ERROR: (RED, DEFAULT), - logging.CRITICAL: (WHITE, RED), -} - -class DBFormatter(logging.Formatter): - def format(self, record): - record.dbname = getattr(threading.current_thread(), 'dbname', '?') - return logging.Formatter.format(self, record) - -class ColoredFormatter(DBFormatter): - def format(self, record): - fg_color, bg_color = LEVEL_COLOR_MAPPING[record.levelno] - record.levelname = COLOR_PATTERN % (30 + fg_color, 40 + bg_color, record.levelname) - return DBFormatter.format(self, record) - def init_logger(): import os from tools.translate import resetlocale resetlocale() + logger = logging.getLogger() # create a format for log messages and dates - format = '[%(asctime)s][%(dbname)s] %(levelname)s:%(name)s:%(message)s' + formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s') if tools.config['syslog']: # SysLog Handler if os.name == 'nt': - handler = logging.handlers.NTEventLogHandler("%s %s" % (release.description, release.version)) + handler = logging.handlers.NTEventLogHandler("%s %s" % + (release.description, + release.version)) else: handler = logging.handlers.SysLogHandler('/dev/log') - format = '%s %s' % (release.description, release.version) \ - + ':%(dbname)s:%(levelname)s:%(name)s:%(message)s' + formatter = logging.Formatter("%s %s" % (release.description, release.version) + ':%(levelname)s:%(name)s:%(message)s') elif tools.config['logfile']: # LogFile Handler @@ -213,17 +178,37 @@ def init_logger(): # Normal Handler on standard output handler = logging.StreamHandler(sys.stdout) - if isinstance(handler, logging.StreamHandler) and os.isatty(handler.stream.fileno()): - formatter = ColoredFormatter(format) - else: - formatter = DBFormatter(format) + + # tell the handler to use this format handler.setFormatter(formatter) # add the handler to the root logger - logger = logging.getLogger() logger.addHandler(handler) logger.setLevel(int(tools.config['log_level'] or '0')) + if (not isinstance(handler, logging.FileHandler)) and os.name != 'nt': + # change color of level names + # uses of ANSI color codes + # see http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html + # maybe use http://code.activestate.com/recipes/574451/ + colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', None, 'default'] + foreground = lambda f: 30 + colors.index(f) + background = lambda f: 40 + colors.index(f) + + mapping = { + 'DEBUG_RPC': ('blue', 'white'), + 'DEBUG': ('blue', 'default'), + 'INFO': ('green', 'default'), + 'TEST': ('white', 'blue'), + 'WARNING': ('yellow', 'default'), + 'ERROR': ('red', 'default'), + 'CRITICAL': ('white', 'red'), + } + + for level, (fg, bg) in mapping.items(): + msg = "\x1b[%dm\x1b[%dm%s\x1b[0m" % (foreground(fg), background(bg), level) + logging.addLevelName(getattr(logging, level), msg) + class Logger(object): def __init__(self): @@ -272,11 +257,8 @@ class Logger(object): # better ignore the exception and carry on.. pass - def set_loglevel(self, level, logger=None): - if logger is not None: - log = logging.getLogger(str(logger)) - else: - log = logging.getLogger() + def set_loglevel(self, level): + log = logging.getLogger() log.setLevel(logging.INFO) # make sure next msg is printed log.info("Log level changed to %s" % logging.getLevelName(level)) log.setLevel(level) @@ -329,39 +311,17 @@ class Server: """ __is_started = False __servers = [] - __starter_threads = [] - - # we don't want blocking server calls (think select()) to - # wait forever and possibly prevent exiting the process, - # but instead we want a form of polling/busy_wait pattern, where - # _server_timeout should be used as the default timeout for - # all I/O blocking operations - _busywait_timeout = 0.5 __logger = logging.getLogger('server') def __init__(self): - Server.__servers.append(self) if Server.__is_started: - # raise Exception('All instances of servers must be inited before the startAll()') - # Since the startAll() won't be called again, allow this server to - # init and then start it after 1sec (hopefully). Register that - # timer thread in a list, so that we can abort the start if quitAll - # is called in the meantime - t = threading.Timer(1.0, self._late_start) - t.name = 'Late start timer for %s' % str(self.__class__) - Server.__starter_threads.append(t) - t.start() + raise Exception('All instances of servers must be inited before the startAll()') + Server.__servers.append(self) def start(self): self.__logger.debug("called stub Server.start") - - def _late_start(self): - self.start() - for thr in Server.__starter_threads: - if thr.finished.is_set(): - Server.__starter_threads.remove(thr) def stop(self): self.__logger.debug("called stub Server.stop") @@ -384,11 +344,6 @@ class Server: if not cls.__is_started: return cls.__logger.info("Stopping %d services" % len(cls.__servers)) - for thr in cls.__starter_threads: - if not thr.finished.is_set(): - thr.cancel() - cls.__starter_threads.remove(thr) - for srv in cls.__servers: srv.stop() cls.__is_started = False @@ -399,21 +354,6 @@ class Server: res.extend(srv.stats() for srv in cls.__servers) return '\n'.join(res) - def _close_socket(self): - if os.name != 'nt': - try: - self.socket.shutdown(getattr(socket, 'SHUT_RDWR', 2)) - except socket.error, e: - if e.errno != errno.ENOTCONN: raise - # OSX, socket shutdowns both sides if any side closes it - # causing an error 57 'Socket is not connected' on shutdown - # of the other side (or something), see - # http://bugs.python.org/issue4397 - self.__logger.debug( - '"%s" when shutting down server socket, ' - 'this is normal under OS X', e) - self.socket.close() - class OpenERPDispatcherException(Exception): def __init__(self, exception, traceback): self.exception = exception @@ -421,10 +361,7 @@ class OpenERPDispatcherException(Exception): class OpenERPDispatcher: def log(self, title, msg): - logger = logging.getLogger(title) - if logger.isEnabledFor(logging.DEBUG_RPC): - for line in pformat(msg).split('\n'): - logger.log(logging.DEBUG_RPC, line) + Logger().notifyChannel('%s' % title, LOG_DEBUG_RPC, pformat(msg)) def dispatch(self, service_name, method, params): try: