1
# Copyright (C) 2005, 2006 Canonical Ltd
1
# Copyright (C) 2005, 2006 by Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
50
50
# is quite expensive, even when the message is not printed by any handlers.
51
51
# We should perhaps change back to just simply doing it here.
57
from bzrlib.lazy_import import lazy_import
58
lazy_import(globals(), """
60
from bzrlib.errors import BzrError, BzrNewError
64
61
from bzrlib.symbol_versioning import (deprecated_function,
68
lazy_import(globals(), """
69
from bzrlib import debug
72
65
_file_handler = None
73
66
_stderr_handler = None
74
67
_stderr_quiet = False
77
70
_bzr_log_file = None
78
_bzr_log_filename = None
81
73
# configure convenient aliases for output routines
101
93
def mutter(fmt, *args):
102
94
if _trace_file is None:
104
if (getattr(_trace_file, 'closed', None) is not None) and _trace_file.closed:
96
if hasattr(_trace_file, 'closed') and _trace_file.closed:
107
if isinstance(fmt, unicode):
108
fmt = fmt.encode('utf8')
111
99
# It seems that if we do ascii % (unicode, ascii) we can
112
100
# get a unicode cannot encode ascii error, so make sure that "fmt"
113
101
# is a unicode string
116
if isinstance(arg, unicode):
117
arg = arg.encode('utf8')
118
real_args.append(arg)
119
out = fmt % tuple(real_args)
102
out = unicode(fmt) % args
123
_trace_file.write(out)
107
_trace_file.write(out)
108
except UnicodeError, e:
109
warning('UnicodeError: %s', e)
110
_trace_file.write(repr(out))
124
111
# TODO: jam 20051227 Consider flushing the trace file to help debugging
125
112
#_trace_file.flush()
128
116
def _rollover_trace_maybe(trace_fname):
141
def open_tracefile(tracefilename=None):
129
def open_tracefile(tracefilename='~/.bzr.log'):
142
130
# Messages are always written to here, so that we have some
143
131
# information if something goes wrong. In a future version this
144
132
# file will be removed on successful completion.
145
global _file_handler, _bzr_log_file, _bzr_log_filename
133
global _file_handler, _bzr_log_file
148
if tracefilename is None:
149
if sys.platform == 'win32':
150
from bzrlib import win32utils
151
home = win32utils.get_home_location()
153
home = os.path.expanduser('~')
154
_bzr_log_filename = os.path.join(home, '.bzr.log')
156
_bzr_log_filename = os.path.expanduser(_bzr_log_filename)
157
_rollover_trace_maybe(_bzr_log_filename)
136
trace_fname = os.path.join(os.path.expanduser(tracefilename))
137
_rollover_trace_maybe(trace_fname)
159
139
LINE_BUFFERED = 1
160
#tf = codecs.open(trace_fname, 'at', 'utf8', buffering=LINE_BUFFERED)
161
tf = open(_bzr_log_filename, 'at', LINE_BUFFERED)
140
tf = codecs.open(trace_fname, 'at', 'utf8', buffering=LINE_BUFFERED)
162
141
_bzr_log_file = tf
163
# tf.tell() on windows always return 0 until some writing done
166
tf.write("this is a debug log for diagnosing/reporting problems in bzr\n")
143
tf.write("\nthis is a debug log for diagnosing/reporting problems in bzr\n")
167
144
tf.write("you can delete or truncate this file, or include sections in\n")
168
tf.write("bug reports to bazaar@lists.canonical.com\n\n")
145
tf.write("bug reports to bazaar-ng@lists.canonical.com\n\n")
169
146
_file_handler = logging.StreamHandler(tf)
170
147
fmt = r'[%(process)5d] %(asctime)s.%(msecs)03d %(levelname)s: %(message)s'
171
148
datefmt = r'%a %H:%M:%S'
183
160
The exception string representation is used as the error
184
161
summary, unless msg is given.
186
Please see log_exception_quietly() for the replacement API.
166
exc_str = format_exception_short(sys.exc_info())
190
168
log_exception_quietly()
285
263
print >>err_file, "bzr: broken pipe"
286
264
elif isinstance(exc_object, KeyboardInterrupt):
287
265
print >>err_file, "bzr: interrupted"
288
elif not getattr(exc_object, 'internal_error', True):
266
elif getattr(exc_object, 'is_user_error', False):
289
267
report_user_error(exc_info, err_file)
290
268
elif isinstance(exc_object, (OSError, IOError)):
291
269
# Might be nice to catch all of these and show them as something more
298
276
# TODO: Should these be specially encoding the output?
299
277
def report_user_error(exc_info, err_file):
300
"""Report to err_file an error that's not an internal error.
302
These don't get a traceback unless -Derror was given.
304
if 'error' in debug.debug_flags:
305
report_bug(exc_info, err_file)
307
278
print >>err_file, "bzr: ERROR:", str(exc_info[1])
311
282
"""Report an exception that probably indicates a bug in bzr"""
313
284
exc_type, exc_object, exc_tb = exc_info
314
print >>err_file, "bzr: ERROR: %s.%s: %s" % (
315
exc_type.__module__, exc_type.__name__, exc_object)
285
print >>err_file, "bzr: ERROR: %s: %s" % (exc_type, exc_object)
317
287
traceback.print_exception(exc_type, exc_object, exc_tb, file=err_file)
323
293
print >>err_file, 'arguments: %r' % sys.argv
325
print >>err_file, "** please send this report to bazaar@lists.ubuntu.com"
295
print >>err_file, "** please send this report to bazaar-ng@lists.ubuntu.com"