Mercurial > hg
view mercurial/loggingutil.py @ 43685:da925257a39e
typing: add pseudo localstr.__init__() to help pytype
Apparently, pytype failed to parse localstr.__new__()? This fixes the
following errors:
line 126, in __hash__: No attribute '_utf8' on localstr [attribute-error]
line 188, in tolocal: Function localstr.__init__ was called with the wrong
arguments [wrong-arg-types]
Expected: (self, string: str, ...)
Actually passed: (self, string: bytes, ...)
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 16 Nov 2019 16:25:28 +0900 |
parents | 687b865b95ad |
children | 4a6024b87dfc |
line wrap: on
line source
# loggingutil.py - utility for logging events # # Copyright 2010 Nicolas Dumazet # Copyright 2013 Facebook, Inc. # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import import errno from . import pycompat from .utils import ( dateutil, procutil, stringutil, ) def openlogfile(ui, vfs, name, maxfiles=0, maxsize=0): """Open log file in append mode, with optional rotation If maxsize > 0, the log file will be rotated up to maxfiles. """ def rotate(oldpath, newpath): try: vfs.unlink(newpath) except OSError as err: if err.errno != errno.ENOENT: ui.debug( b"warning: cannot remove '%s': %s\n" % (newpath, err.strerror) ) try: if newpath: vfs.rename(oldpath, newpath) except OSError as err: if err.errno != errno.ENOENT: ui.debug( b"warning: cannot rename '%s' to '%s': %s\n" % (newpath, oldpath, err.strerror) ) if maxsize > 0: try: st = vfs.stat(name) except OSError: pass else: if st.st_size >= maxsize: path = vfs.join(name) for i in pycompat.xrange(maxfiles - 1, 1, -1): rotate( oldpath=b'%s.%d' % (path, i - 1), newpath=b'%s.%d' % (path, i), ) rotate(oldpath=path, newpath=maxfiles > 0 and path + b'.1') return vfs(name, b'a', makeparentdirs=False) def _formatlogline(msg): date = dateutil.datestr(format=b'%Y/%m/%d %H:%M:%S') pid = procutil.getpid() return b'%s (%d)> %s' % (date, pid, msg) def _matchevent(event, tracked): return b'*' in tracked or event in tracked class filelogger(object): """Basic logger backed by physical file with optional rotation""" def __init__(self, vfs, name, tracked, maxfiles=0, maxsize=0): self._vfs = vfs self._name = name self._trackedevents = set(tracked) self._maxfiles = maxfiles self._maxsize = maxsize def tracked(self, event): return _matchevent(event, self._trackedevents) def log(self, ui, event, msg, opts): line = _formatlogline(msg) try: with openlogfile( ui, self._vfs, self._name, maxfiles=self._maxfiles, maxsize=self._maxsize, ) as fp: fp.write(line) except IOError as err: ui.debug( b'cannot write to %s: %s\n' % (self._name, stringutil.forcebytestr(err)) ) class fileobjectlogger(object): """Basic logger backed by file-like object""" def __init__(self, fp, tracked): self._fp = fp self._trackedevents = set(tracked) def tracked(self, event): return _matchevent(event, self._trackedevents) def log(self, ui, event, msg, opts): line = _formatlogline(msg) try: self._fp.write(line) self._fp.flush() except IOError as err: ui.debug( b'cannot write to %s: %s\n' % ( stringutil.forcebytestr(self._fp.name), stringutil.forcebytestr(err), ) ) class proxylogger(object): """Forward log events to another logger to be set later""" def __init__(self): self.logger = None def tracked(self, event): return self.logger is not None and self.logger.tracked(event) def log(self, ui, event, msg, opts): assert self.logger is not None self.logger.log(ui, event, msg, opts)