Skip to content
Snippets Groups Projects
Commit 2cad301a7f06 authored by Bryan O'Sullivan's avatar Bryan O'Sullivan
Browse files

blackbox: automatically rotate log files

If enabled, log rotation prevents the amount of space used by the
blackbox log from growing without bound. This becomes important in
cases where there are a lot of busy repositories managed by humans
and automation on many machines.

In large deployments, we cannot reasonably track all the repos where
blackbox logs need to be managed, so it is safer to have blackbox
manage its own logs than to move responsibility to an external tool
such as logrotate.

This change adds two configuration keys:

* blackbox.maxsize is the maximum allowable size of the current log

* blackbox.maxfiles is the number of log files to maintain
parent 2c4cd1c42365
No related branches found
No related tags found
No related merge requests found
......@@ -21,7 +21,13 @@
[blackbox]
track = incoming
[blackbox]
# limit the size of a log file
maxsize = 1.5 MB
# rotate up to N log files when the current one gets too big
maxfiles = 3
"""
from mercurial import util, cmdutil
from mercurial.i18n import _
......@@ -24,8 +30,8 @@
"""
from mercurial import util, cmdutil
from mercurial.i18n import _
import os, re
import errno, os, re
cmdtable = {}
command = cmdutil.command(cmdtable)
......@@ -38,6 +44,38 @@
def track(self):
return self.configlist('blackbox', 'track', ['*'])
def _openlogfile(self):
def rotate(oldpath, newpath):
try:
os.unlink(newpath)
except OSError, err:
if err.errno != errno.ENOENT:
self.debug("warning: cannot remove '%s': %s\n" %
(newpath, err.strerror))
try:
if newpath:
os.rename(oldpath, newpath)
except OSError, err:
if err.errno != errno.ENOENT:
self.debug("warning: cannot rename '%s' to '%s': %s\n" %
(newpath, oldpath, err.strerror))
fp = self._bbopener('blackbox.log', 'a')
maxsize = self.configbytes('blackbox', 'maxsize', 1048576)
if maxsize > 0:
st = os.fstat(fp.fileno())
if st.st_size >= maxsize:
path = fp.name
fp.close()
maxfiles = self.configint('blackbox', 'maxfiles', 7)
for i in xrange(maxfiles - 1, 1, -1):
rotate(oldpath='%s.%d' % (path, i - 1),
newpath='%s.%d' % (path, i))
rotate(oldpath=path,
newpath=maxfiles > 0 and path + '.1')
fp = self._bbopener('blackbox.log', 'a')
return fp
def log(self, event, *msg, **opts):
global lastblackbox
super(blackboxui, self).log(event, *msg, **opts)
......@@ -49,7 +87,7 @@
blackbox = self._blackbox
elif util.safehasattr(self, '_bbopener'):
try:
self._blackbox = self._bbopener('blackbox.log', 'a')
self._blackbox = self._openlogfile()
except (IOError, OSError), err:
self.debug('warning: cannot write to blackbox.log: %s\n' %
err.strerror)
......
......@@ -131,5 +131,20 @@
1970/01/01 00:00:00 bob> exthook-update: echo hooked finished in * seconds (glob)
1970/01/01 00:00:00 bob> update exited False after * seconds (glob)
log rotation
$ echo '[blackbox]' >> .hg/hgrc
$ echo 'maxsize = 20 b' >> .hg/hgrc
$ echo 'maxfiles = 3' >> .hg/hgrc
$ hg status
$ hg status
$ hg status
$ hg tip -q
2:d02f48003e62
$ ls .hg/blackbox.log*
.hg/blackbox.log
.hg/blackbox.log.1
.hg/blackbox.log.2
cleanup
$ cd ..
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment