diff --git a/bin/trytond b/bin/trytond index 1146379635..a244d6714a 100755 --- a/bin/trytond +++ b/bin/trytond @@ -1,6 +1,5 @@ #!/usr/bin/env python #This file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. - import sys, os DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..', '..', 'trytond'))) diff --git a/trytond/ir/ui/view.py b/trytond/ir/ui/view.py index 1e1d7cbb33..0641dbb242 100644 --- a/trytond/ir/ui/view.py +++ b/trytond/ir/ui/view.py @@ -3,7 +3,7 @@ from trytond.osv import fields, OSV from difflib import SequenceMatcher import os -from trytond.netsvc import Logger, LOG_ERROR, LOG_WARNING +import logging from lxml import etree @@ -69,11 +69,11 @@ class View(OSV): if hasattr(etree, 'RelaxNG'): validator = etree.RelaxNG(file=rng_name) if not validator.validate(tree): - logger = Logger() + logger = logging.getLogger('ir') error_log = reduce(lambda x, y: str(x) + '\n' + str(y), validator.error_log.filter_from_errors()) - logger.notify_channel('ir', LOG_ERROR, - 'Invalid xml view:\n%s' % (str(error_log) + '\n' + xml)) + logger.error( + 'Invalid xml view:\n%s' % (str(error_log) + '\n' + xml)) return False root_element = tree.getroottree().getroot() strings = self._translate_view(root_element) diff --git a/trytond/module.py b/trytond/module.py index a027a7e366..085591a6a5 100644 --- a/trytond/module.py +++ b/trytond/module.py @@ -5,10 +5,10 @@ from sets import Set from config import CONFIG import tools import pooler -from netsvc import Logger, LOG_ERROR, LOG_INFO import zipfile import zipimport import traceback +import logging OPJ = os.path.join MODULES_PATH = OPJ(os.path.dirname(__file__), 'modules') @@ -130,14 +130,14 @@ def create_graph(module_list, force=None): try: info = eval(tools.file_open(tryton_file).read()) except: - Logger().notify_channel('init', LOG_ERROR, - 'module:%s:eval file %s' % (module, tryton_file)) + logging.getLogger('init').error( + 'module:%s:eval file %s' % (module, tryton_file)) raise if info.get('installable', True): packages.append((module, info.get('depends', []), info)) elif module != 'all': - Logger().notify_channel('init', LOG_ERROR, - 'module:%s:Module not found!' % (module,)) + logging.getLogger('init').error( + 'module:%s:Module not found!' % (module,)) current, later = Set([x[0] for x in packages]), Set() while packages and current > later: @@ -168,19 +168,19 @@ def create_graph(module_list, force=None): if package not in later: continue missings = [x for x in deps if x not in graph] - Logger().notify_channel('init', LOG_ERROR, - 'module:%s:Unmet dependency %s' % (package, missings)) + logging.getLogger('init').error( + 'module:%s:Unmet dependency %s' % (package, missings)) return graph, packages, later def init_module_objects(cursor, module_name, obj_list): - Logger().notify_channel('init', LOG_INFO, - 'module:%s:creating or updating database tables' % module_name) + logging.getLogger('init').info( + 'module:%s:creating or updating database tables' % module_name) for obj in obj_list: obj.auto_init(cursor, module_name) def init_module_wizards(cursor, module_name, wizard_list): - Logger().notify_channel('init', LOG_INFO, - 'module:%s:creating or updating wizards' % module_name) + logging.getLogger('init').info( + 'module:%s:creating or updating wizards' % module_name) for wizard in wizard_list: wizard.auto_init(cursor, module_name) @@ -192,7 +192,7 @@ def load_module_graph(cursor, graph, lang=None): module = package.name if module not in MODULES: continue - Logger().notify_channel('init', LOG_INFO, 'module:%s' % module) + logging.getLogger('init').info('module:%s' % module) sys.stdout.flush() pool = pooler.get_pool(cursor.dbname) modules = pool.instanciate(module) @@ -221,8 +221,8 @@ def load_module_graph(cursor, graph, lang=None): mode = 'update' if hasattr(package, 'init') or package_state=='to install': mode = 'init' - Logger().notify_channel('init', LOG_INFO, - 'module:%s:loading %s' % (module, filename)) + logging.getLogger('init').info( + 'module:%s:loading %s' % (module, filename)) ext = os.path.splitext(filename)[1] if ext == '.sql': if mode == 'init': @@ -243,8 +243,8 @@ def load_module_graph(cursor, graph, lang=None): lang2 = os.path.splitext(filename)[0] if lang2 not in lang: continue - Logger().notify_channel('init', LOG_INFO, - 'module:%s:loading %s' % (module, filename)) + logging.getLogger('init').info( + 'module:%s:loading %s' % (module, filename)) translation_obj = pool.get('ir.translation') translation_obj.translation_import(cursor, 0, lang2, module, tools.file_open(OPJ(module, filename))) @@ -283,8 +283,8 @@ def register_classes(): import webdav for package in create_graph(get_module_list())[0]: module = package.name - Logger().notify_channel('init', LOG_INFO, - 'module:%s:registering classes' % module) + logging.getLogger('init').info( + 'module:%s:registering classes' % module) if module in ('ir', 'workflow', 'res', 'webdav'): MODULES.append(module) @@ -308,8 +308,8 @@ def register_classes(): import pdb traceb = sys.exc_info()[2] pdb.post_mortem(traceb) - Logger().notify_channel('init', LOG_ERROR, - 'Couldn\'t import module %s:\n%s' % (module, tb_s)) + logging.getLogger('init').error( + 'Couldn\'t import module %s:\n%s' % (module, tb_s)) break else: mod_path = OPJ(MODULES_PATH, module+'.zip') @@ -330,8 +330,8 @@ def register_classes(): import pdb traceb = sys.exc_info()[2] pdb.post_mortem(traceb) - Logger().notify_channel('init', LOG_ERROR, - 'Couldn\'t import module %s:\n%s' % (module, tb_s)) + logging.getLogger('init').error( + 'Couldn\'t import module %s:\n%s' % (module, tb_s)) break MODULES.append(module) diff --git a/trytond/netsvc.py b/trytond/netsvc.py index 7fc4205bd5..0b6e60c9d6 100644 --- a/trytond/netsvc.py +++ b/trytond/netsvc.py @@ -5,7 +5,6 @@ import SimpleXMLRPCServer, signal, sys, xmlrpclib import SocketServer import socket import logging -import logging.handlers import os from pysocket import PySocket import traceback @@ -77,43 +76,9 @@ class ServiceUnavailable(Exception): def service_exist(name): return (name in _SERVICE) and bool(_SERVICE[name]) -def init_logger(): - if CONFIG['logfile']: - logf = CONFIG['logfile'] - # test if the directories exist, else create them - try: - handler = logging.handlers.TimedRotatingFileHandler(logf, 'D', 1, - 30) - except Exception, exception: - sys.stderr.write("ERROR: couldn't create the logfile directory:" \ - + str(exception)) - handler = logging.StreamHandler(sys.stdout) - else: - 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(logging.INFO) - - -class Logger(object): - - def notify_channel(self, name, level, msg): - log = logging.getLogger(name) - getattr(log, level)(msg) - - class Agent(object): _timers = [] - _logger = Logger() + _logger = logging.getLogger('timers') def set_alarm(self, function, time_start, args=None, kwargs=None): if not args: @@ -122,10 +87,10 @@ class Agent(object): kwargs = {} wait = time_start - time.time() if wait > 0: - self._logger.notify_channel('timers', LOG_DEBUG, - "Job scheduled in %s seconds for %s.%s" % \ - (wait, function.im_class.__name__, - function.func_name)) + self._logger.debug( + "Job scheduled in %s seconds for %s.%s" % \ + (wait, function.im_class.__name__, + function.func_name)) timer = threading.Timer(wait, function, args, kwargs) timer.start() self._timers.append(timer) @@ -172,8 +137,8 @@ class GenericXMLRPCRequestHandler: def _dispatch(self, method, params): host, port = self.client_address[:2] - Logger().notify_channel('web-service', LOG_INFO, - 'connection from %s:%d' % (host, port)) + logging.getLogger('web-service').info( + 'connection from %s:%d' % (host, port)) try: name = self.path.split("/")[-1] service = LocalService(name) @@ -327,8 +292,8 @@ class TinySocketClientThread(threading.Thread): return False if first: host, port = self.sock.getpeername()[:2] - Logger().notify_channel('web-service', LOG_INFO, - 'connection from %s:%d' % (host, port)) + logging.getLogger('web-service').info( + 'connection from %s:%d' % (host, port)) first = False try: service = LocalService(msg[0]) diff --git a/trytond/osv/orm.py b/trytond/osv/orm.py index a0fde519fc..fb5816f135 100644 --- a/trytond/osv/orm.py +++ b/trytond/osv/orm.py @@ -1,6 +1,6 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. # -*- coding: utf-8 -*- -from trytond.netsvc import Logger, LOG_ERROR, LOG_WARNING, LocalService +from trytond.netsvc import LocalService import fields from trytond.tools import Cache import md5 @@ -449,7 +449,6 @@ class ORM(object): (self._name, 'en_US', 'error', error, '', module_name)) def _auto_init(self, cursor, module_name): - logger = Logger() self._field_create(cursor, module_name) if not self._auto or self.table_query(): # No db table for this object. @@ -790,7 +789,7 @@ class ORM(object): if context is None: context = {} fields_names = [x.split('/') for x in fields_names] - logger = Logger() + logger = logging.getLogger('import') def process_liness(self, datas, prefix, fields_def, position=0): line = datas[position] @@ -858,10 +857,9 @@ class ORM(object): if str(key) == line[i]: res = key if line[i] and not res: - logger.notify_channel("import", LOG_WARNING, - "key '%s' not found " \ - "in selection field '%s'" % \ - (line[i], field[len(prefix)])) + logger.warning("key '%s' not found " \ + "in selection field '%s'" % \ + (line[i], field[len(prefix)])) elif fields_def[field[len(prefix)]]['type'] == 'many2one': res = False if line[i]: @@ -873,10 +871,9 @@ class ORM(object): if not res: warning += ('Relation not found: ' + line[i] + \ ' on ' + relation + ' !\n') - logger.notify_channel("import", - LOG_WARNING, - 'Relation not found: ' + line[i] + \ - ' on ' + relation + ' !\n') + logger.warning( + 'Relation not found: ' + line[i] + \ + ' on ' + relation + ' !\n') elif fields_def[field[len(prefix)]]['type'] == 'many2many': res = [] if line[i]: @@ -889,9 +886,8 @@ class ORM(object): if not res3: warning += ('Relation not found: ' + \ line[i] + ' on '+relation + ' !\n') - logger.notify_channel("import", - LOG_WARNING, - 'Relation not found: ' + line[i] + \ + logger.warning( + 'Relation not found: ' + line[i] + \ ' on '+relation + ' !\n') else: res.append(res3) @@ -961,7 +957,7 @@ class ORM(object): self.write(cursor, user, new_id, translate[lang], context=context2) except Exception, exp: - logger.notify_channel("import", LOG_ERROR, exp) + logger.error(exp) cursor.rollback() return (-1, res, exp[0], warning) done += 1 diff --git a/trytond/osv/osv.py b/trytond/osv/osv.py index fc19039e8c..6d1e49f285 100644 --- a/trytond/osv/osv.py +++ b/trytond/osv/osv.py @@ -2,7 +2,7 @@ "Objects Services" from orm import ORM -from trytond.netsvc import Service, LocalService, Logger, LOG_ERROR +from trytond.netsvc import Service, LocalService from trytond import pooler import copy import sys @@ -48,9 +48,8 @@ class OSVService(Service): if CONFIG['verbose']: tb_s = reduce(lambda x, y: x+y, traceback.format_exception(*sys.exc_info())) - logger = Logger() - logger.notify_channel("web-service", LOG_ERROR, - 'Exception in call: \n' + tb_s) + logger = logging.getLogger("web-service") + logger.error('Exception in call: \n' + tb_s) if isinstance(exception, IntegrityError): for key in self._sql_errors.keys(): if key in exception[0]: @@ -98,9 +97,8 @@ class OSVService(Service): if CONFIG['verbose']: tb_s = reduce(lambda x, y: x+y, traceback.format_exception(*sys.exc_info())) - logger = Logger() - logger.notify_channel("web-service", LOG_ERROR, - 'Exception in call: \n' + tb_s) + logger = logging.getLogger() + logger.error('Exception in call: \n' + tb_s) if isinstance(exception, IntegrityError): for key in self._sql_errors.keys(): if key in exception[0]: diff --git a/trytond/pooler.py b/trytond/pooler.py index dd9f3b6296..a80075454a 100644 --- a/trytond/pooler.py +++ b/trytond/pooler.py @@ -1,6 +1,6 @@ #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 sql_db import db_connect -from netsvc import Logger, LOG_INFO +import logging _DB = {} _POOL = {} @@ -12,8 +12,8 @@ def get_db_and_pool(db_name, update_module=False, wizard=False, report=False, if db_name in _DB: database = _DB[db_name] else: - Logger().notify_channel('pooler', LOG_INFO, - 'Connecting to %s' % (db_name)) + logging.getLogger('pooler').info( + 'Connecting to %s' % (db_name)) database = db_connect(db_name) cursor = database.cursor() cursor.close() @@ -24,8 +24,8 @@ def get_db_and_pool(db_name, update_module=False, wizard=False, report=False, pool_wizard = _POOL_WIZARD[db_name] pool_report = _POOL_REPORT[db_name] else: - Logger().notify_channel('pooler', LOG_INFO, - 'Instanciate pooler for %s' % (db_name)) + logging.getLogger('pooler').info( + 'Instanciate pooler for %s' % (db_name)) from osv.osv import OSVService pool = OSVService() _POOL[db_name] = pool @@ -64,8 +64,8 @@ def get_db_only(db_name): if db_name in _DB: database = _DB[db_name] else: - Logger().notify_channel('pooler', LOG_INFO, - 'Connecting to %s' % (db_name)) + logging.getLogger('pooler').info( + 'Connecting to %s' % (db_name)) database = db_connect(db_name) _DB[db_name] = database return database diff --git a/trytond/report/report.py b/trytond/report/report.py index b656c84278..e80128c8cb 100644 --- a/trytond/report/report.py +++ b/trytond/report/report.py @@ -1,6 +1,6 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. "Report" -from trytond.netsvc import Service, service_exist, Logger, LOG_WARNING, LOG_ERROR +from trytond.netsvc import Service from trytond import pooler import copy import xml @@ -26,6 +26,7 @@ from trytond.config import CONFIG from trytond.sql_db import IntegrityError import inspect import mx.DateTime +import logging MODULE_LIST = [] MODULE_CLASS_LIST = {} @@ -54,8 +55,8 @@ class ReportService(Service): if CONFIG['verbose']: tb_s = reduce(lambda x, y: x+y, traceback.format_exception(*sys.exc_info())) - Logger().notify_channel("web-service", LOG_ERROR, - 'Exception in call: ' + tb_s) + logging.getLogger("web-service").error( + 'Exception in call: ' + tb_s) if isinstance(exception, IntegrityError): pool = pooler.get_pool(cursor.dbname) for key in pool._sql_errors.keys(): diff --git a/trytond/server.py b/trytond/server.py index 2ca02580f4..40876ec363 100644 --- a/trytond/server.py +++ b/trytond/server.py @@ -2,7 +2,10 @@ """ %prog [options] """ - +import logging +format='[%(asctime)s] %(levelname)s:%(name)s:%(message)s' +datefmt='%a %b %d %H:%M:%S %Y' +logging.basicConfig(level=logging.DEBUG, format=format, datefmt=datefmt) import sys, os, signal import netsvc import time @@ -17,22 +20,46 @@ from module import register_classes import mx.DateTime from getpass import getpass import sha - +import logging +import logging.handlers class TrytonServer(object): def __init__(self): - netsvc.init_logger() - self.logger = netsvc.Logger() + + if CONFIG['logfile']: + logf = CONFIG['logfile'] + # test if the directories exist, else create them + try: + handler = logging.handlers.TimedRotatingFileHandler( + logf, 'D', 1, 30) + except Exception, exception: + sys.stderr.write("ERROR: couldn't create the logfile directory:" \ + + str(exception)) + else: + formatter = logging.Formatter(format, datefmt) + # tell the handler to use this format + handler.setFormatter(formatter) + + # 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) + + self.logger = logging.getLogger("init") if not hasattr(mx.DateTime, 'strptime'): mx.DateTime.strptime = lambda x, y: mx.DateTime.mktime( time.strptime(x, y)) - self.logger.notify_channel("init", netsvc.LOG_INFO, - 'using %s as configuration file' % CONFIG.configfile) - self.logger.notify_channel("init", netsvc.LOG_INFO, - 'initialising distributed objects services') + self.logger.info('using %s as configuration file' % CONFIG.configfile) + self.logger.info('initialising distributed objects services') self.dispatcher = netsvc.Dispatcher() self.dispatcher.monitor(signal.SIGINT) @@ -57,8 +84,7 @@ class TrytonServer(object): if db_name: cursor = pooler.get_db_only(db_name).cursor() except psycopg2.OperationalError: - self.logger.notify_channel("init", netsvc.LOG_INFO, - "could not connect to database '%s'!" % db_name,) + self.logger.info("could not connect to database '%s'!" % db_name,) init[db_name] = False if cursor and CONFIG['init']: @@ -86,7 +112,7 @@ class TrytonServer(object): "'ir_lang'" ")") if len(cursor.fetchall()) == 0: - self.logger.notify_channel("init", netsvc.LOG_INFO, "init db") + self.logger.info("init db") sql_db.init_db(cursor) init[db_name] = True cursor.commit() @@ -132,8 +158,7 @@ class TrytonServer(object): cursor.close() if update_module: - self.logger.notify_channel('init', netsvc.LOG_INFO, - 'Update/Init succeed!') + self.logger.info('Update/Init succeed!') sys.exit(0) # Launch Server @@ -143,44 +168,40 @@ class TrytonServer(object): try: port = int(CONFIG["xmlport"]) except: - self.logger.notify_channel("init", netsvc.LOG_ERROR, - "invalid port '%s'!" % (CONFIG["xmlport"],)) + self.logger.error("invalid port '%s'!" % (CONFIG["xmlport"],)) sys.exit(1) httpd = netsvc.HttpDaemon(interface, port, secure) xml_gw = netsvc.XmlRpc.RpcGateway('web-service') httpd.attach("/xmlrpc", xml_gw ) - self.logger.notify_channel("web-service", netsvc.LOG_INFO, - "starting XML-RPC" + \ - (CONFIG['secure'] and ' Secure' or '') + \ - " services, port " + str(port)) + logging.getLogger("web-service").info( + "starting XML-RPC" + (CONFIG['secure'] and ' Secure' or '') + \ + " services, port " + str(port)) if CONFIG['netrpc']: interface = CONFIG["interface"] try: port = int(CONFIG["netport"]) except: - self.logger.notify_channel("init", netsvc.LOG_ERROR, - "invalid port '%s'!" % (CONFIG["netport"],)) + self.logger.error("invalid port '%s'!" % (CONFIG["netport"],)) sys.exit(1) tinysocket = netsvc.TinySocketServerThread(interface, port, secure) - self.logger.notify_channel("web-service", netsvc.LOG_INFO, - "starting netrpc service, port " + str(port)) + logging.getLogger("web-service").info( + "starting netrpc service, port " + str(port)) if CONFIG['webdav']: interface = CONFIG['interface'] try: port = int(CONFIG['webdavport']) except: - self.logger.notify_channel('init', netsvc.LOG_ERROR, - "invalid port '%s'!" % (CONFIG['webdavport'],)) + self.logger.error("invalid port '%s'!" % (CONFIG['webdavport'],)) sys.exit(1) webdavd = netsvc.WebDAVServerThread(interface, port, secure) - self.logger.notify_channel('web-service', netsvc.LOG_INFO, + logging.getLogger("web-service").info( 'starting webdav service, port ' + str(port)) def handler(signum, frame): @@ -204,8 +225,7 @@ class TrytonServer(object): signal.signal(signal.SIGINT, handler) signal.signal(signal.SIGTERM, handler) - self.logger.notify_channel("init", netsvc.LOG_INFO, - 'the server is running, waiting for connections...') + self.logger.info('the server is running, waiting for connections...') if CONFIG['netrpc']: tinysocket.start() if CONFIG['xmlrpc']: diff --git a/trytond/sql_db.py b/trytond/sql_db.py index 753a1da859..361d50f2c5 100644 --- a/trytond/sql_db.py +++ b/trytond/sql_db.py @@ -9,7 +9,7 @@ from mx import DateTime as mdt import zipfile import version from config import CONFIG -from netsvc import Logger, LOG_ERROR, LOG_WARNING +import logging RE_FROM = re.compile('.* from "?([a-zA-Z_0-9]+)"?.*$') RE_INTO = re.compile('.* into "?([a-zA-Z_0-9]+)"?.*$') @@ -350,9 +350,7 @@ class table_handler: return base_type = column_type[0].lower() if not base_type == self.table[column_name]['typname']: - logger = Logger() - logger.notify_channel( - 'init', LOG_WARNING, + logging.getLogger('init').warning( 'Unable to migrate column % s on table %s from %s to %s.' % \ (column_name, self.table_name, self.table[column_name]['typname'], base_type)) @@ -368,9 +366,7 @@ class table_handler: self.table[column_name]['size'] < field_size: self.migrate_column(column_name, column_type[1]) else: - logger = Logger() - logger.notify_channel( - 'init', LOG_WARNING, + logging.getLogger('init').warning( 'Unable to migrate column %s on table %s ' \ 'from varchar(%s) to varchar(%s).' % \ (column_name, self.table_name, @@ -478,10 +474,7 @@ class table_handler: "SET NOT NULL") self.update_definitions() else: - logger = Logger() - logger.notify_channel( - 'init', - LOG_WARNING, + logging.getLogger('init').warning( 'Unable to set column %s ' \ 'of table %s not null !\n'\ 'Try to re-run: ' \ @@ -509,10 +502,7 @@ class table_handler: 'ADD CONSTRAINT "%s" %s' % \ (self.table_name, ident, constraint,)) except: - raise - logger = Logger() - logger.notify_channel( - 'init', LOG_WARNING, + logging.getLogger('init').warning( 'unable to add \'%s\' constraint on table %s !\n' \ 'If you want to have it, you should update the records ' \ 'and execute manually:\n'\ diff --git a/trytond/tools/convert.py b/trytond/tools/convert.py index 77332754a3..4101b62ade 100644 --- a/trytond/tools/convert.py +++ b/trytond/tools/convert.py @@ -9,7 +9,7 @@ from trytond import pooler from trytond.osv.fields import Integer import csv import os.path -from trytond.netsvc import Logger, LOG_ERROR, LOG_INFO, LocalService, LOG_WARNING +from trytond.netsvc import LocalService from trytond.config import CONFIG from trytond.version import VERSION import time @@ -17,6 +17,7 @@ from xml import sax from decimal import Decimal import datetime import time +import logging CDATA_START = re.compile('^\s*\<\!\[cdata\[', re.IGNORECASE) CDATA_END = re.compile('\]\]\>\s*$', re.IGNORECASE) @@ -376,8 +377,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): try: self.sax_parser.parse(source) except: - Logger().notify_channel( - "init", LOG_ERROR, + logging.getLogger("init").error( "Error while parsing xml file:\n" +\ self.current_state() ) @@ -402,8 +402,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): pass else: - Logger().notify_channel("init", LOG_INFO, - "Tag "+ name + " not supported") + logging.getLogger("init").info("Tag "+ name + " not supported") return else: self.taghandler.startElement(name, attributes) @@ -552,8 +551,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): try: db_field = self._clean_value(key, db_val, object_ref) except Unhandled_field: - logger = Logger() - logger.notify_channel('init', LOG_INFO, + logging.getLogger("init").info( 'Field %s on %s : integrity not tested.'%(key, model)) to_update[key] = values[key] continue @@ -578,8 +576,7 @@ class TrytondXmlHandler(sax.handler.ContentHandler): # if they are not false in a boolean context (ie None, # False, {} or []) if db_field != expected_value and (db_field or expected_value): - logger = Logger() - logger.notify_channel('init', LOG_WARNING, + logging.getLogger("init").warning( "Field %s of %s@%s not updated (id: %s), because "\ "it has changed since the last update"% \ (key, db_id, model, fs_id)) @@ -711,8 +708,7 @@ def post_import(cursor, module, to_delete): wf_service.trg_write(user, model, db_id, cursor) - logger = Logger() - logger.notify_channel('init', LOG_INFO, + logging.getLogger("init").info( 'Deleting %s@%s' % (db_id, model)) try: # Deletion of the record @@ -722,28 +718,26 @@ def post_import(cursor, module, to_delete): cursor.commit() except Exception, exception: cursor.rollback() - logger.notify_channel('init', LOG_ERROR, - 'Could not delete id: %d of model %s\n' \ - 'There should be some relation ' \ - 'that points to this resource\n' \ - 'You should manually fix this ' \ - 'and restart --update=module' % \ - (db_id, model)) + logging.getLogger("init").error( + 'Could not delete id: %d of model %s\n' \ + 'There should be some relation ' \ + 'that points to this resource\n' \ + 'You should manually fix this ' \ + 'and restart --update=module' % \ + (db_id, model)) transition_obj = pool.get('workflow.transition') for mdata_id, db_id in transition_delete: - logger = Logger() - logger.notify_channel('init', LOG_INFO, - 'Deleting %s@workflow.transition' % (db_id,)) + logging.getLogger("init").info( + 'Deleting %s@workflow.transition' % (db_id,)) try: transition_obj.delete(cursor, user, db_id) mdata_delete.append(mdata_id) cursor.commit() except: cursor.rollback() - logger.notify_channel('init', LOG_ERROR, - 'Could not delete id: %d of model workflow.transition' % \ - (db_id,)) + logging.getLogger("init").error( + 'Could not delete id: %d of model workflow.transition'% (db_id,)) # Clean model_data: if mdata_delete: diff --git a/trytond/tools/misc.py b/trytond/tools/misc.py index c120ddbdd5..acc8bda60f 100644 --- a/trytond/tools/misc.py +++ b/trytond/tools/misc.py @@ -10,6 +10,7 @@ import socket import zipfile from trytond import pooler from threading import Semaphore +import logging try: import cStringIO as StringIO except ImportError: @@ -138,8 +139,7 @@ def email_send(email_from, email_to, subject, body, email_cc=None, msg.as_string()) smtp.quit() except Exception, exp: - from trytond.netsvc import Logger, LOG_ERROR - Logger().notify_channel("web-service", LOG_ERROR, str(exp)) + logging.getLogger("web-service").error(str(exp)) return True def email_send_attach(email_from, email_to, subject, body, email_cc=None, @@ -193,8 +193,8 @@ def email_send_attach(email_from, email_to, subject, body, email_cc=None, msg.as_string()) smtp.quit() except Exception, exp: - from trytond.netsvc import Logger, LOG_ERROR - Logger().notify_channel("web-service", LOG_ERROR, str(exp)) + logging.getLogger("web-service").error(str(exp)) + return True def sms_send(user, password, api_id, text, to): diff --git a/trytond/web_service/common.py b/trytond/web_service/common.py index ceff7dfcba..ac18c194da 100644 --- a/trytond/web_service/common.py +++ b/trytond/web_service/common.py @@ -1,10 +1,10 @@ #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 trytond.netsvc import Service, Logger, LOG_INFO +from trytond.netsvc import Service from trytond import security from trytond.version import VERSION import time from trytond.tools import Cache - +import logging class Common(Service): @@ -19,10 +19,9 @@ class Common(Service): def login(self, database, login, password): res = security.login(database, login, password) Cache.clean(database) - logger = Logger() + logger = logging.getLogger("web-service") msg = res and 'successful login' or 'bad login or password' - logger.notify_channel("web-service", LOG_INFO, - "%s from '%s' using database '%s'" % (msg, login, database)) + logger.info("%s from '%s' using database '%s'" % (msg, login, database)) return res or False def about(self): diff --git a/trytond/web_service/db.py b/trytond/web_service/db.py index 714169e429..fe5bf27f93 100644 --- a/trytond/web_service/db.py +++ b/trytond/web_service/db.py @@ -1,7 +1,8 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. # -*- coding: utf-8 -*- -from trytond.netsvc import Service, Logger, LOG_ERROR, LOG_INFO, LOG_WARNING +import logging import threading +from trytond.netsvc import Service from trytond import security from trytond import sql_db from trytond import pooler @@ -29,8 +30,7 @@ class DB(Service): def create(self, password, db_name, lang, admin_password): security.check_super(password) res = False - - logger = Logger() + logger = logging.getLogger('web-service') database = sql_db.db_connect('template1') cursor = database.cursor() @@ -64,17 +64,14 @@ class DB(Service): cursor.commit() res = True except: - logger.notify_channel("web-service", LOG_ERROR, - 'CREATE DB: %s failed' % (db_name,)) + logger.error('CREATE DB: %s failed' % (db_name,)) import traceback, sys tb_s = reduce(lambda x, y: x+y, traceback.format_exception(*sys.exc_info())) - logger.notify_channel("web-service", LOG_ERROR, - 'Exception in call: \n' + tb_s) + logger.error('Exception in call: \n' + tb_s) raise else: - logger.notify_channel("web-service", LOG_INFO, - 'CREATE DB: %s' % (db_name,)) + logger.error('CREATE DB: %s' % (db_name,)) finally: if cursor: cursor.close() @@ -83,7 +80,7 @@ class DB(Service): def drop(self, password, db_name): security.check_super(password) pooler.close_db(db_name) - logger = Logger() + logger = logging.getLogger('web-service') database = sql_db.db_connect('template1') cursor = database.cursor() @@ -93,28 +90,24 @@ class DB(Service): cursor.execute('DROP DATABASE "' + db_name + '"') cursor.commit() except: - logger.notify_channel("web-service", LOG_ERROR, - 'DROP DB: %s failed' % (db_name,)) + logger.error('DROP DB: %s failed' % (db_name,)) import traceback, sys tb_s = reduce(lambda x, y: x+y, traceback.format_exception(*sys.exc_info())) - logger.notify_channel("web-service", LOG_ERROR, - 'Exception in call: \n' + tb_s) + logger.error('Exception in call: \n' + tb_s) raise else: - logger.notify_channel("web-service", LOG_INFO, - 'DROP DB: %s' % (db_name)) + logger.info('DROP DB: %s' % (db_name)) finally: cursor.close() return True def dump(self, password, db_name): security.check_super(password) - logger = Logger() + logger = logging.getLogger('web-service') if tools.CONFIG['db_password']: - logger.notify_channel("web-service", LOG_ERROR, - 'DUMP DB: %s doesn\'t work with password' % (db_name,)) + logger.error('DUMP DB: %s doesn\'t work with password' % (db_name,)) raise Exception, "Couldn't dump database with password" cmd = ['pg_dump', '--format=c'] @@ -131,25 +124,22 @@ class DB(Service): data = stdout.read() res = stdout.close() if res: - logger.notify_channel("web-service", LOG_ERROR, - 'DUMP DB: %s failed\n%s' % (db_name, data)) + logger.error('DUMP DB: %s failed\n%s' % (db_name, data)) raise Exception, "Couldn't dump database" - logger.notify_channel("web-service", LOG_INFO, - 'DUMP DB: %s' % (db_name)) + logger.info('DUMP DB: %s' % (db_name)) return base64.encodestring(data) def restore(self, password, db_name, data): security.check_super(password) - logger = Logger() + logger = logging.getLogger('web-service') if self.db_exist(db_name): - logger.notify_channel("web-service", LOG_WARNING, - 'RESTORE DB: %s already exists' % (db_name,)) + logger.warning('RESTORE DB: %s already exists' % (db_name,)) raise Exception, "Database already exists" if tools.CONFIG['db_password']: - logger.notify_channel("web-service", LOG_ERROR, - 'RESTORE DB: %s doesn\'t work with password' % (db_name,)) + logger.error( + 'RESTORE DB: %s doesn\'t work with password' % (db_name,)) raise Exception, "Couldn't restore database with password" database = sql_db.db_connect('template1') @@ -183,8 +173,7 @@ class DB(Service): res = stdout.close() if res: raise Exception, "Couldn't restore database" - logger.notify_channel("web-service", LOG_INFO, - 'RESTORE DB: %s' % (db_name)) + logger.info('RESTORE DB: %s' % (db_name)) return True def db_exist(self, db_name): diff --git a/trytond/wizard/wizard.py b/trytond/wizard/wizard.py index 2669419463..bc365c0787 100644 --- a/trytond/wizard/wizard.py +++ b/trytond/wizard/wizard.py @@ -1,6 +1,6 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. "Wizard" -from trytond.netsvc import Service, service_exist, Logger, LOG_ERROR +from trytond.netsvc import Service from trytond import pooler import copy from xml import dom @@ -9,6 +9,7 @@ from trytond.config import CONFIG import sys from trytond.sql_db import IntegrityError import traceback +import logging MODULE_LIST = [] MODULE_CLASS_LIST = {} @@ -37,8 +38,8 @@ class WizardService(Service): if CONFIG['verbose']: tb_s = reduce(lambda x, y: x+y, traceback.format_exception(*sys.exc_info())) - Logger().notify_channel("web-service", LOG_ERROR, - 'Exception in call: ' + tb_s) + logging.getLogger("web-service").error( + 'Exception in call: ' + tb_s) if isinstance(exception, IntegrityError): pool = pooler.get_pool(cursor.dbname) for key in pool._sql_errors.keys():