1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
31 LOG_CRITICAL = 'critical'
33 logging.TEST = logging.INFO - 5
34 logging.addLevelName(logging.TEST, 'TEST')
36 _logger = logging.getLogger(__name__)
41 "The netsvc.Logger API shouldn't be used anymore, please "
42 "use the standard `logging.getLogger` API instead.")
43 super(Logger, self).__init__()
45 def notifyChannel(self, name, level, msg):
47 "notifyChannel API shouldn't be used anymore, please use "
48 "the standard `logging` module instead.")
49 from service import common
51 log = logging.getLogger(__name__ + '.deprecated.' + ustr(name))
53 if level in [LOG_TEST] and not hasattr(log, level):
54 fct = lambda msg, *args, **kwargs: log.log(getattr(logging, level.upper()), msg, *args, **kwargs)
55 setattr(log, level, fct)
58 level_method = getattr(log, level)
60 if isinstance(msg, Exception):
61 msg = exception_to_unicode(msg)
64 msg = ustr(msg).strip()
65 if level in (LOG_ERROR, LOG_CRITICAL): # and tools.config.get_misc('debug','env_info',False):
66 msg = common.exp_get_server_environment() + "\n" + msg
68 result = msg.split('\n')
69 except UnicodeDecodeError:
70 result = msg.strip().split('\n')
73 for idx, s in enumerate(result):
74 level_method('[%02d]: %s' % (idx+1, s,))
76 level_method(result[0])
78 # TODO: perhaps reset the logger streams?
79 #if logrotate closes our files, we end up here..
82 # better ignore the exception and carry on..
85 def set_loglevel(self, level, logger=None):
86 if logger is not None:
87 log = logging.getLogger(str(logger))
89 log = logging.getLogger()
90 log.setLevel(logging.INFO) # make sure next msg is printed
91 log.info("Log level changed to %s" % logging.getLevelName(level))
97 # TODO get_encodings, ustr and exception_to_unicode were originally from tools.misc.
98 # There are here until we refactor tools so that this module doesn't depends on tools.
100 def get_encodings(hint_encoding='utf-8'):
103 'iso-8859-1': 'iso8859-15',
108 if hint_encoding.lower() in fallbacks:
109 yield fallbacks[hint_encoding.lower()]
111 # some defaults (also taking care of pure ASCII)
112 for charset in ['utf8','latin1']:
113 if not hint_encoding or (charset.lower() != hint_encoding.lower()):
116 from locale import getpreferredencoding
117 prefenc = getpreferredencoding()
118 if prefenc and prefenc.lower() != 'utf-8':
120 prefenc = fallbacks.get(prefenc.lower())
124 def ustr(value, hint_encoding='utf-8', errors='strict'):
125 """This method is similar to the builtin `unicode`, except
126 that it may try multiple encodings to find one that works
127 for decoding `value`, and defaults to 'utf-8' first.
129 :param: value: the value to convert
130 :param: hint_encoding: an optional encoding that was detecte
131 upstream and should be tried first to decode ``value``.
132 :param str errors: optional `errors` flag to pass to the unicode
133 built-in to indicate how illegal character values should be
134 treated when converting a string: 'strict', 'ignore' or 'replace'
135 (see ``unicode()`` constructor).
136 Passing anything other than 'strict' means that the first
137 encoding tried will be used, even if it's not the correct
138 one to use, so be careful! Ignored if value is not a string/unicode.
139 :raise: UnicodeError if value cannot be coerced to unicode
140 :return: unicode string representing the given value
142 if isinstance(value, Exception):
143 return exception_to_unicode(value)
145 if isinstance(value, unicode):
148 if not isinstance(value, basestring):
150 return unicode(value)
152 raise UnicodeError('unable to convert %r' % (value,))
154 for ln in get_encodings(hint_encoding):
156 return unicode(value, ln, errors=errors)
159 raise UnicodeError('unable to convert %r' % (value,))
162 def exception_to_unicode(e):
163 if (sys.version_info[:2] < (2,6)) and hasattr(e, 'message'):
164 return ustr(e.message)
165 if hasattr(e, 'args'):
166 return "\n".join((ustr(a) for a in e.args))
170 return u"Unknown message"
172 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: