/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1 by mbp at sourcefrog
import from baz patch-364
1
# This program is free software; you can redistribute it and/or modify
2
# it under the terms of the GNU General Public License as published by
3
# the Free Software Foundation; either version 2 of the License, or
4
# (at your option) any later version.
5
6
# This program is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
# GNU General Public License for more details.
10
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
15
1185.33.6 by Martin Pool
Code and tests for shorter formatting of error messages
16
"""Messages and logging for bazaar-ng.
17
18
Messages are supplied by callers as a string-formatting template, plus values
19
to be inserted into it.  The actual %-formatting is deferred to the log
20
library so that it doesn't need to be done for messages that won't be emitted.
21
22
Messages are classified by severity levels: critical, error, warning, info,
23
and debug.
24
25
They can be sent to two places: to stderr, and to ~/.bzr.log.  For purposes
26
such as running the test suite, they can also be redirected away from both of
27
those two places to another location.
28
29
~/.bzr.log gets all messages, and full tracebacks for uncaught exceptions.
30
31
Output to stderr depends on the mode chosen by the user.  By default, messages
32
of info and above are sent out, which results in progress messages such as the
33
list of files processed by add and commit.  In quiet mode, only warnings and
34
above are shown.  In debug mode, stderr gets debug messages too.
35
36
Errors that terminate an operation are generally passed back as exceptions;
37
others may be just emitted as messages.
38
39
Exceptions are reported in a brief form to stderr so as not to look scary.
40
BzrErrors are required to be able to format themselves into a properly
41
explanatory message.  This is not true for builtin excexceptions such as
42
KeyError, which typically just str to "0".  They're printed in a different
43
form.
344 by Martin Pool
- It's not an error to use the library without
44
"""
45
46
1097 by Martin Pool
- send trace messages out through python logging module
47
# TODO: in debug mode, stderr should get full tracebacks and also
48
# debug messages.  (Is this really needed?)
49
50
# TODO: When running the test suites, we should add an additional
51
# logger that sends messages into the test log file.
52
1185.16.74 by Martin Pool
doc
53
# FIXME: Unfortunately it turns out that python's logging module
54
# is quite expensive, even when the message is not printed by any handlers.
55
# We should perhaps change back to just simply doing it here.
56
1097 by Martin Pool
- send trace messages out through python logging module
57
58
import sys
59
import os
60
import logging
61
1185.33.8 by Martin Pool
Cleanup exception formatting stuff
62
import bzrlib
1185.33.7 by Martin Pool
Better formatting of builtin errors
63
from bzrlib.errors import BzrNewError
64
1097 by Martin Pool
- send trace messages out through python logging module
65
1101 by Martin Pool
- add global definition to quieten pychecker
66
_file_handler = None
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
67
_stderr_handler = None
1101 by Martin Pool
- add global definition to quieten pychecker
68
69
1097 by Martin Pool
- send trace messages out through python logging module
70
class QuietFormatter(logging.Formatter):
71
    """Formatter that supresses the details of errors.
72
73
    This is used by default on stderr so as not to scare the user.
74
    """
75
    # At first I tried overriding formatException to suppress the
76
    # exception details, but that has global effect: no loggers
77
    # can get the exception details is we suppress them here.
78
79
    def format(self, record):
80
        if record.levelno >= logging.WARNING:
1393.1.57 by Martin Pool
- no 'bzr' prefix on info messages
81
            s = 'bzr: ' + record.levelname + ': '
82
        else:
83
            s = ''
1289 by Martin Pool
- wrap wide strings when showing exceptions
84
        s += record.getMessage()
1097 by Martin Pool
- send trace messages out through python logging module
85
        if record.exc_info:
1185.33.8 by Martin Pool
Cleanup exception formatting stuff
86
            s += '\n' + format_exception_short(record.exc_info)
1097 by Martin Pool
- send trace messages out through python logging module
87
        return s
88
        
89
90
91
92
################
93
# configure convenient aliases for output routines
94
95
_bzr_logger = logging.getLogger('bzr')
96
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
97
info = note = _bzr_logger.info
1097 by Martin Pool
- send trace messages out through python logging module
98
warning =   _bzr_logger.warning
99
log_error = _bzr_logger.error
100
error =     _bzr_logger.error
101
mutter =    _bzr_logger.debug
102
debug =     _bzr_logger.debug
103
104
261 by Martin Pool
- auto-rollover of .bzr.log
105
def _rollover_trace_maybe(trace_fname):
359 by Martin Pool
- pychecker fixups
106
    import stat
261 by Martin Pool
- auto-rollover of .bzr.log
107
    try:
108
        size = os.stat(trace_fname)[stat.ST_SIZE]
333 by Martin Pool
- allow trace file to grow up to 4MB
109
        if size <= 4 << 20:
261 by Martin Pool
- auto-rollover of .bzr.log
110
            return
111
        old_fname = trace_fname + '.old'
1185.1.40 by Robert Collins
Merge what applied of Alexander Belchenko's win32 patch.
112
        from osutils import rename
113
        rename(trace_fname, old_fname)
261 by Martin Pool
- auto-rollover of .bzr.log
114
    except OSError:
115
        return
116
117
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
118
def open_tracefile(tracefilename='~/.bzr.log'):
59 by mbp at sourcefrog
lift out tracefile creation code
119
    # Messages are always written to here, so that we have some
120
    # information if something goes wrong.  In a future version this
121
    # file will be removed on successful completion.
1097 by Martin Pool
- send trace messages out through python logging module
122
    global _file_handler
359 by Martin Pool
- pychecker fixups
123
    import stat, codecs
59 by mbp at sourcefrog
lift out tracefile creation code
124
397 by Martin Pool
- open_tracefile takes a tracefilename parameter
125
    trace_fname = os.path.join(os.path.expanduser(tracefilename))
261 by Martin Pool
- auto-rollover of .bzr.log
126
    _rollover_trace_maybe(trace_fname)
403 by Martin Pool
- Don't give an error if the trace file can't be opened
127
    try:
1185.33.11 by Martin Pool
Code format cleanups
128
        LINE_BUFFERED = 1
129
        tf = codecs.open(trace_fname, 'at', 'utf8', buffering=LINE_BUFFERED)
403 by Martin Pool
- Don't give an error if the trace file can't be opened
130
1097 by Martin Pool
- send trace messages out through python logging module
131
        if os.fstat(tf.fileno())[stat.ST_SIZE] == 0:
1100 by Martin Pool
- fix name error reported by Andrew Bennetts
132
            tf.write("\nthis is a debug log for diagnosing/reporting problems in bzr\n")
133
            tf.write("you can delete or truncate this file, or include sections in\n")
134
            tf.write("bug reports to bazaar-ng@lists.canonical.com\n\n")
1097 by Martin Pool
- send trace messages out through python logging module
135
        
136
        _file_handler = logging.StreamHandler(tf)
137
        fmt = r'[%(process)5d] %(asctime)s.%(msecs)03d %(levelname)s: %(message)s'
138
        datefmt = r'%a %H:%M:%S'
139
        _file_handler.setFormatter(logging.Formatter(fmt, datefmt))
140
        _file_handler.setLevel(logging.DEBUG)
141
        logging.getLogger('').addHandler(_file_handler)
403 by Martin Pool
- Don't give an error if the trace file can't be opened
142
    except IOError, e:
143
        warning("failed to open trace file: %s" % (e))
260 by Martin Pool
- remove atexit() dependency for writing out execution times
144
1097 by Martin Pool
- send trace messages out through python logging module
145
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
146
def log_startup(argv):
147
    debug('bzr %s invoked on python %s (%s)',
148
          bzrlib.__version__,
149
          '.'.join(map(str, sys.version_info)),
150
          sys.platform)
151
    debug('  arguments: %r', argv)
1185.16.73 by Martin Pool
- in error messages, show cwd as repr in case it's in unicode
152
    debug('  working dir: %r', os.getcwdu())
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
153
1097 by Martin Pool
- send trace messages out through python logging module
154
155
def log_exception(msg=None):
1185.16.82 by mbp at sourcefrog
- give a quieter warning if a plugin can't be loaded
156
    """Log the last exception to stderr and the trace file.
1097 by Martin Pool
- send trace messages out through python logging module
157
158
    The exception string representation is used as the error
159
    summary, unless msg is given.
160
    """
1185.33.8 by Martin Pool
Cleanup exception formatting stuff
161
    exc_str = format_exception_short(sys.exc_info())
162
    if msg:
163
        _bzr_logger.exception(msg)
164
    _bzr_logger.error(exc_str)
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
165
166
1185.16.82 by mbp at sourcefrog
- give a quieter warning if a plugin can't be loaded
167
def log_exception_quietly():
168
    """Log the last exception to the trace file only.
169
170
    Used for exceptions that occur internally and that may be 
171
    interesting to developers but not to users.  For example, 
172
    errors loading plugins.
173
    """
1185.33.11 by Martin Pool
Code format cleanups
174
    import traceback
1185.16.82 by mbp at sourcefrog
- give a quieter warning if a plugin can't be loaded
175
    debug(traceback.format_exc())
176
177
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
178
def enable_default_logging():
179
    """Configure default logging to stderr and .bzr.log"""
180
    global _stderr_handler, _file_handler
181
182
    _stderr_handler = logging.StreamHandler()
1359 by Martin Pool
- merge in new BZR_NOISY vs BZR_DEBUG stuff from main
183
    _stderr_handler.setFormatter(QuietFormatter())
1185.34.2 by Jelmer Vernooij
Don't quite when tracefile can't be opened. Display warning
184
    logging.getLogger('').addHandler(_stderr_handler)
1359 by Martin Pool
- merge in new BZR_NOISY vs BZR_DEBUG stuff from main
185
186
    if os.environ.get('BZR_DEBUG'):
187
        level = logging.DEBUG
188
    else:
189
        level = logging.INFO
190
191
    _stderr_handler.setLevel(logging.INFO)
1185.34.2 by Jelmer Vernooij
Don't quite when tracefile can't be opened. Display warning
192
193
    if not _file_handler:
194
        open_tracefile()
195
196
    if _file_handler:
197
        _file_handler.setLevel(level)
198
1185.16.136 by Martin Pool
Set logger level depending on BZR_DEBUG to reduce work
199
    _bzr_logger.setLevel(level) 
1359 by Martin Pool
- merge in new BZR_NOISY vs BZR_DEBUG stuff from main
200
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
201
def disable_default_logging():
202
    """Turn off default log handlers.
203
204
    This is intended to be used by the test framework, which doesn't
205
    want leakage from the code-under-test into the main logs.
206
    """
1112 by Martin Pool
- disable standard logging to .bzr.log and stderr while running
207
208
    l = logging.getLogger('')
209
    l.removeHandler(_stderr_handler)
210
    if _file_handler:
211
        l.removeHandler(_file_handler)
1185.33.6 by Martin Pool
Code and tests for shorter formatting of error messages
212
213
1185.33.13 by Martin Pool
Hide more stuff in bzrlib.trace
214
def enable_test_log(to_file):
215
    """Redirect logging to a temporary file for a test"""
216
    disable_default_logging()
217
    global _test_log_hdlr
218
    hdlr = logging.StreamHandler(to_file)
219
    hdlr.setLevel(logging.DEBUG)
220
    hdlr.setFormatter(logging.Formatter('%(levelname)8s  %(message)s'))
221
    logging.getLogger('').addHandler(hdlr)
222
    logging.getLogger('').setLevel(logging.DEBUG)
223
    _test_log_hdlr = hdlr
224
225
226
def disable_test_log():
227
    logging.getLogger('').removeHandler(_test_log_hdlr)
228
    enable_default_logging()
229
230
1185.33.8 by Martin Pool
Cleanup exception formatting stuff
231
def format_exception_short(exc_info):
1185.33.6 by Martin Pool
Code and tests for shorter formatting of error messages
232
    """Make a short string form of an exception.
233
234
    This is used for display to stderr.  It specially handles exception
235
    classes without useful string methods.
1185.33.7 by Martin Pool
Better formatting of builtin errors
236
237
    The result has no trailing newline.
1185.33.8 by Martin Pool
Cleanup exception formatting stuff
238
239
    exc_info - typically an exception from sys.exc_info()
1185.33.6 by Martin Pool
Code and tests for shorter formatting of error messages
240
    """
1185.33.8 by Martin Pool
Cleanup exception formatting stuff
241
    exc_type, exc_object, exc_tb = exc_info
1185.33.17 by Martin Pool
[merge] aaron, various fixes
242
    try:
243
        if exc_type is None:
244
            return '(no exception)'
245
        if isinstance(exc_object, BzrNewError):
246
            return str(exc_object)
247
        else:
248
            import traceback
249
            tb = traceback.extract_tb(exc_tb)
250
            msg = '%s: %s' % (exc_type, exc_object)
251
            if msg[-1] == '\n':
252
                msg = msg[:-1]
253
            if tb:
254
                msg += '\n  at %s line %d\n  in %s' % (tb[-1][:3])
255
            return msg
256
    except:
257
        return '(error formatting exception of type %s)' % exc_type