119
# FIXME note always emits utf-8, regardless of the terminal encoding
113
121
# FIXME: clearing the ui and then going through the abstract logging
114
122
# framework is whack; we should probably have a logging Handler that
115
123
# deals with terminal output if needed.
122
130
_bzr_logger.warning(*args, **kwargs)
133
@deprecated_function(deprecated_in((2, 1, 0)))
134
def info(*args, **kwargs):
135
"""Deprecated: use trace.note instead."""
136
note(*args, **kwargs)
139
@deprecated_function(deprecated_in((2, 1, 0)))
140
def log_error(*args, **kwargs):
141
"""Deprecated: use bzrlib.trace.show_error instead"""
142
_bzr_logger.error(*args, **kwargs)
145
@deprecated_function(deprecated_in((2, 1, 0)))
146
def error(*args, **kwargs):
147
"""Deprecated: use bzrlib.trace.show_error instead"""
148
_bzr_logger.error(*args, **kwargs)
125
151
def show_error(*args, **kwargs):
126
152
"""Show an error message to the user.
283
309
start_time = osutils.format_local_date(_bzr_log_start_time,
284
310
timezone='local')
311
# create encoded wrapper around stderr
285
312
bzr_log_file = _open_bzr_log()
286
313
if bzr_log_file is not None:
287
314
bzr_log_file.write(start_time.encode('utf-8') + '\n')
290
317
r'%Y-%m-%d %H:%M:%S')
291
318
# after hooking output into bzr_log, we also need to attach a stderr
292
319
# handler, writing only at level info and with encoding
293
stderr_handler = EncodedStreamHandler(sys.stderr,
294
osutils.get_terminal_encoding(), 'replace', level=logging.INFO)
320
term_encoding = osutils.get_terminal_encoding()
321
writer_factory = codecs.getwriter(term_encoding)
322
encoded_stderr = writer_factory(sys.stderr, errors='replace')
323
stderr_handler = logging.StreamHandler(encoded_stderr)
324
stderr_handler.setLevel(logging.INFO)
295
325
logging.getLogger('bzr').addHandler(stderr_handler)
307
337
global _trace_file
308
338
# make a new handler
309
new_handler = EncodedStreamHandler(to_file, "utf-8", level=logging.DEBUG)
339
new_handler = logging.StreamHandler(to_file)
340
new_handler.setLevel(logging.DEBUG)
310
341
if log_format is None:
311
342
log_format = '%(levelname)8s %(message)s'
312
343
new_handler.setFormatter(logging.Formatter(log_format, date_format))
483
514
print_exception(exc_info, err_file)
484
515
return errors.EXIT_ERROR
485
516
exc_type, exc_object, exc_tb = exc_info
486
if isinstance(exc_object, KeyboardInterrupt):
517
if (isinstance(exc_object, IOError)
518
and getattr(exc_object, 'errno', None) == errno.EPIPE):
519
err_file.write("bzr: broken pipe\n")
520
return errors.EXIT_ERROR
521
elif isinstance(exc_object, KeyboardInterrupt):
487
522
err_file.write("bzr: interrupted\n")
488
523
return errors.EXIT_ERROR
489
524
elif isinstance(exc_object, MemoryError):
501
536
elif not getattr(exc_object, 'internal_error', True):
502
537
report_user_error(exc_info, err_file)
503
538
return errors.EXIT_ERROR
504
elif osutils.is_environment_error(exc_object):
505
if getattr(exc_object, 'errno', None) == errno.EPIPE:
506
err_file.write("bzr: broken pipe\n")
507
return errors.EXIT_ERROR
539
elif isinstance(exc_object, (OSError, IOError)) or (
540
# GZ 2010-05-20: Like (exc_type is pywintypes.error) but avoid import
541
exc_type.__name__ == "error" and exc_type.__module__ == "pywintypes"):
508
542
# Might be nice to catch all of these and show them as something more
509
543
# specific, but there are too many cases at the moment.
510
544
report_user_error(exc_info, err_file)
567
597
_trace_file.flush()
570
class EncodedStreamHandler(logging.Handler):
571
"""Robustly write logging events to a stream using the specified encoding
573
Messages are expected to be formatted to unicode, but UTF-8 byte strings
574
are also accepted. An error during formatting or a str message in another
575
encoding will be quitely noted as an error in the Bazaar log file.
577
The stream is not closed so sys.stdout or sys.stderr may be passed.
580
def __init__(self, stream, encoding=None, errors='strict', level=0):
581
logging.Handler.__init__(self, level)
584
encoding = getattr(stream, "encoding", "ascii")
585
self.encoding = encoding
589
flush = getattr(self.stream, "flush", None)
590
if flush is not None:
593
def emit(self, record):
595
line = self.format(record)
596
if not isinstance(line, unicode):
597
line = line.decode("utf-8")
598
self.stream.write(line.encode(self.encoding, self.errors) + "\n")
600
log_exception_quietly()
601
# Try saving the details that would have been logged in some form
602
msg = args = "<Unformattable>"
604
msg = repr(record.msg).encode("ascii")
605
args = repr(record.args).encode("ascii")
608
# Using mutter() bypasses the logging module and writes directly
609
# to the file so there's no danger of getting into a loop here.
610
mutter("Logging record unformattable: %s %% %s", msg, args)
613
600
class Config(object):
614
601
"""Configuration of message tracing in bzrlib.