~openerp-commiter/openobject-server/trunk-ach-server-bugfixes

« back to all changes in this revision

Viewing changes to openerp/loglevels.py

  • Committer: Anup(OpenERP)
  • Date: 2011-02-25 05:20:46 UTC
  • mfrom: (3196.1.163 openobject-server)
  • Revision ID: ach@tinyerp.com-20110225052046-1b1yzvi731uwujto
[MERGE] Merged from the main trunk server

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
 
6
#
 
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.
 
11
#
 
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.
 
16
#
 
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/>.
 
19
#
 
20
##############################################################################
 
21
 
 
22
import sys
 
23
import logging
 
24
import warnings
 
25
 
 
26
LOG_NOTSET = 'notset'
 
27
LOG_DEBUG_SQL = 'debug_sql'
 
28
LOG_DEBUG_RPC_ANSWER = 'debug_rpc_answer'
 
29
LOG_DEBUG_RPC = 'debug_rpc'
 
30
LOG_DEBUG = 'debug'
 
31
LOG_TEST = 'test'
 
32
LOG_INFO = 'info'
 
33
LOG_WARNING = 'warn'
 
34
LOG_ERROR = 'error'
 
35
LOG_CRITICAL = 'critical'
 
36
 
 
37
logging.DEBUG_RPC_ANSWER = logging.DEBUG - 4
 
38
logging.addLevelName(logging.DEBUG_RPC_ANSWER, 'DEBUG_RPC_ANSWER')
 
39
logging.DEBUG_RPC = logging.DEBUG - 2
 
40
logging.addLevelName(logging.DEBUG_RPC, 'DEBUG_RPC')
 
41
logging.DEBUG_SQL = logging.DEBUG_RPC - 3
 
42
logging.addLevelName(logging.DEBUG_SQL, 'DEBUG_SQL')
 
43
 
 
44
logging.TEST = logging.INFO - 5
 
45
logging.addLevelName(logging.TEST, 'TEST')
 
46
 
 
47
class Logger(object):
 
48
    def __init__(self):
 
49
        warnings.warn("The netsvc.Logger API shouldn't be used anymore, please "
 
50
                      "use the standard `logging.getLogger` API instead",
 
51
                      PendingDeprecationWarning, stacklevel=2)
 
52
        super(Logger, self).__init__()
 
53
 
 
54
    def notifyChannel(self, name, level, msg):
 
55
        warnings.warn("notifyChannel API shouldn't be used anymore, please use "
 
56
                      "the standard `logging` module instead",
 
57
                      PendingDeprecationWarning, stacklevel=2)
 
58
        from service.web_services import common
 
59
 
 
60
        log = logging.getLogger(ustr(name))
 
61
 
 
62
        if level in [LOG_DEBUG_RPC, LOG_TEST] and not hasattr(log, level):
 
63
            fct = lambda msg, *args, **kwargs: log.log(getattr(logging, level.upper()), msg, *args, **kwargs)
 
64
            setattr(log, level, fct)
 
65
 
 
66
 
 
67
        level_method = getattr(log, level)
 
68
 
 
69
        if isinstance(msg, Exception):
 
70
            msg = exception_to_unicode(msg)
 
71
 
 
72
        try:
 
73
            msg = ustr(msg).strip()
 
74
            if level in (LOG_ERROR, LOG_CRITICAL): # and tools.config.get_misc('debug','env_info',False):
 
75
                msg = common().exp_get_server_environment() + "\n" + msg
 
76
 
 
77
            result = msg.split('\n')
 
78
        except UnicodeDecodeError:
 
79
            result = msg.strip().split('\n')
 
80
        try:
 
81
            if len(result)>1:
 
82
                for idx, s in enumerate(result):
 
83
                    level_method('[%02d]: %s' % (idx+1, s,))
 
84
            elif result:
 
85
                level_method(result[0])
 
86
        except IOError:
 
87
            # TODO: perhaps reset the logger streams?
 
88
            #if logrotate closes our files, we end up here..
 
89
            pass
 
90
        except Exception:
 
91
            # better ignore the exception and carry on..
 
92
            pass
 
93
 
 
94
    def set_loglevel(self, level, logger=None):
 
95
        if logger is not None:
 
96
            log = logging.getLogger(str(logger))
 
97
        else:
 
98
            log = logging.getLogger()
 
99
        log.setLevel(logging.INFO) # make sure next msg is printed
 
100
        log.info("Log level changed to %s" % logging.getLevelName(level))
 
101
        log.setLevel(level)
 
102
 
 
103
    def shutdown(self):
 
104
        logging.shutdown()
 
105
 
 
106
# TODO get_encodings, ustr and exception_to_unicode were originally from tools.misc.
 
107
# There are here until we refactor tools so that this module doesn't depends on tools.
 
108
 
 
109
def get_encodings(hint_encoding='utf-8'):
 
110
    fallbacks = {
 
111
        'latin1': 'latin9',
 
112
        'iso-8859-1': 'iso8859-15',
 
113
        'cp1252': '1252',
 
114
    }
 
115
    if hint_encoding:
 
116
        yield hint_encoding
 
117
        if hint_encoding.lower() in fallbacks:
 
118
            yield fallbacks[hint_encoding.lower()]
 
119
 
 
120
    # some defaults (also taking care of pure ASCII)
 
121
    for charset in ['utf8','latin1']:
 
122
        if not (hint_encoding) or (charset.lower() != hint_encoding.lower()):
 
123
            yield charset
 
124
 
 
125
    from locale import getpreferredencoding
 
126
    prefenc = getpreferredencoding()
 
127
    if prefenc and prefenc.lower() != 'utf-8':
 
128
        yield prefenc
 
129
        prefenc = fallbacks.get(prefenc.lower())
 
130
        if prefenc:
 
131
            yield prefenc
 
132
 
 
133
def ustr(value, hint_encoding='utf-8'):
 
134
    """This method is similar to the builtin `str` method, except
 
135
       it will return unicode() string.
 
136
 
 
137
    @param value: the value to convert
 
138
    @param hint_encoding: an optional encoding that was detected
 
139
                          upstream and should be tried first to
 
140
                          decode ``value``.
 
141
 
 
142
    @rtype: unicode
 
143
    @return: unicode string
 
144
    """
 
145
    if isinstance(value, Exception):
 
146
        return exception_to_unicode(value)
 
147
 
 
148
    if isinstance(value, unicode):
 
149
        return value
 
150
 
 
151
    if not isinstance(value, basestring):
 
152
        try:
 
153
            return unicode(value)
 
154
        except Exception:
 
155
            raise UnicodeError('unable to convert %r' % (value,))
 
156
 
 
157
    for ln in get_encodings(hint_encoding):
 
158
        try:
 
159
            return unicode(value, ln)
 
160
        except Exception:
 
161
            pass
 
162
    raise UnicodeError('unable to convert %r' % (value,))
 
163
 
 
164
 
 
165
def exception_to_unicode(e):
 
166
    if (sys.version_info[:2] < (2,6)) and hasattr(e, 'message'):
 
167
        return ustr(e.message)
 
168
    if hasattr(e, 'args'):
 
169
        return "\n".join((ustr(a) for a in e.args))
 
170
    try:
 
171
        return ustr(e)
 
172
    except Exception:
 
173
        return u"Unknown message"
 
174
 
 
175
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: