annotate hgext/blackbox.py @ 33649:377e8ddaebef stable

pathauditor: disable cache of audited paths by default (issue5628) The initial attempt was to discard cache when appropriate, but it appears to be error prone. We had to carefully inspect all places where audit() is called e.g. without actually updating filesystem, before removing files and directories, etc. So, this patch disables the cache of audited paths by default, and enables it only for the following cases: - short-lived auditor objects - repo.vfs, repo.svfs, and repo.cachevfs, which are managed directories and considered sort of append-only (a file/directory would never be replaced with a symlink) There would be more cacheable vfs objects (e.g. mq.queue.opener), but I decided not to inspect all of them in this patch. We can make them cached later. Benchmark result: - using old clone of http://selenic.com/repo/linux-2.6/ (38319 files) - on tmpfs - run HGRCPATH=/dev/null hg up -q --time tip && hg up -q null - try 4 times and take the last three results original: real 7.480 secs (user 1.140+22.760 sys 0.150+1.690) real 8.010 secs (user 1.070+22.280 sys 0.170+2.120) real 7.470 secs (user 1.120+22.390 sys 0.120+1.910) clearcache (the other series): real 7.680 secs (user 1.120+23.420 sys 0.140+1.970) real 7.670 secs (user 1.110+23.620 sys 0.130+1.810) real 7.740 secs (user 1.090+23.510 sys 0.160+1.940) enable cache only for vfs and svfs (this series): real 8.730 secs (user 1.500+25.190 sys 0.260+2.260) real 8.750 secs (user 1.490+25.170 sys 0.250+2.340) real 9.010 secs (user 1.680+25.340 sys 0.280+2.540) remove cache function at all (for reference): real 9.620 secs (user 1.440+27.120 sys 0.250+2.980) real 9.420 secs (user 1.400+26.940 sys 0.320+3.130) real 9.760 secs (user 1.530+27.270 sys 0.250+2.970)
author Yuya Nishihara <yuya@tcha.org>
date Wed, 26 Jul 2017 22:10:15 +0900
parents 9bb4decd43b0
children 4f60720cf0df
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
18676
1506eb487ddd blackbox: fix copyright
Bryan O'Sullivan <bryano@fb.com>
parents: 18675
diff changeset
1 # blackbox.py - log repository events to a file for post-mortem debugging
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
2 #
18676
1506eb487ddd blackbox: fix copyright
Bryan O'Sullivan <bryano@fb.com>
parents: 18675
diff changeset
3 # Copyright 2010 Nicolas Dumazet
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
4 # Copyright 2013 Facebook, Inc.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
5 #
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
6 # This software may be used and distributed according to the terms of the
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
7 # GNU General Public License version 2 or any later version.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
8
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
9 """log repository events to a blackbox for debugging
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
10
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
11 Logs event information to .hg/blackbox.log to help debug and diagnose problems.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
12 The events that get logged can be configured via the blackbox.track config key.
28246
b862e793ec10 blackbox: log dirty state
timeless <timeless@mozdev.org>
parents: 28245
diff changeset
13
19162
27013ace80eb blackbox: fix literal block syntax
Takumi IINO <trot.thunder@gmail.com>
parents: 19066
diff changeset
14 Examples::
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
15
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
16 [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
17 track = *
28303
ce24de063aa5 blackbox: rewrite dirty documentation noting it is expensive
timeless <timeless@mozdev.org>
parents: 28248
diff changeset
18 # dirty is *EXPENSIVE* (slow);
ce24de063aa5 blackbox: rewrite dirty documentation noting it is expensive
timeless <timeless@mozdev.org>
parents: 28248
diff changeset
19 # each log entry indicates `+` if the repository is dirty, like :hg:`id`.
28246
b862e793ec10 blackbox: log dirty state
timeless <timeless@mozdev.org>
parents: 28245
diff changeset
20 dirty = True
28305
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
21 # record the source of log messages
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
22 logsource = True
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
23
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
24 [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
25 track = command, commandfinish, commandexception, exthook, pythonhook
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
26
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
27 [blackbox]
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
28 track = incoming
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
29
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
30 [blackbox]
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
31 # limit the size of a log file
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
32 maxsize = 1.5 MB
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
33 # rotate up to N log files when the current one gets too big
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
34 maxfiles = 3
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
35
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
36 """
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
37
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
38 from __future__ import absolute_import
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
39
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
40 import errno
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
41 import re
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
42
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
43 from mercurial.i18n import _
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
44 from mercurial.node import hex
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
45
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
46 from mercurial import (
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32155
diff changeset
47 registrar,
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
48 ui as uimod,
28090
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
49 util,
8113c88b8e6d blackbox: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28027
diff changeset
50 )
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
51
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 28552
diff changeset
52 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
53 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
54 # be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 23877
diff changeset
55 # leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 28552
diff changeset
56 testedwith = 'ships-with-hg-core'
33134
7dc090faa8a4 blackbox: minor code reordering
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32412
diff changeset
57
7dc090faa8a4 blackbox: minor code reordering
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32412
diff changeset
58 cmdtable = {}
7dc090faa8a4 blackbox: minor code reordering
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32412
diff changeset
59 command = registrar.command(cmdtable)
7dc090faa8a4 blackbox: minor code reordering
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32412
diff changeset
60
33135
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
61 configtable = {}
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
62 configitem = registrar.configitem(configtable)
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
63
33189
1df74b71396d configitems: register the 'blackbox.dirty' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33136
diff changeset
64 configitem('blackbox', 'dirty',
1df74b71396d configitems: register the 'blackbox.dirty' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33136
diff changeset
65 default=False,
1df74b71396d configitems: register the 'blackbox.dirty' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33136
diff changeset
66 )
33135
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
67 configitem('blackbox', 'maxsize',
33136
59c135bb31bc blackbox: use a human readable version of the default
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33135
diff changeset
68 default='1 MB',
33135
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
69 )
33190
0ef40bb20264 configitems: register the 'blackbox.logsource' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33189
diff changeset
70 configitem('blackbox', 'logsource',
0ef40bb20264 configitems: register the 'blackbox.logsource' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33189
diff changeset
71 default=False,
0ef40bb20264 configitems: register the 'blackbox.logsource' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33189
diff changeset
72 )
33135
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
73
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
74 lastui = None
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
75
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
76 filehandles = {}
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
77
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
78 def _openlog(vfs):
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
79 path = vfs.join('blackbox.log')
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
80 if path in filehandles:
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
81 return filehandles[path]
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
82 filehandles[path] = fp = vfs('blackbox.log', 'a')
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
83 return fp
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
84
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
85 def _closelog(vfs):
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
86 path = vfs.join('blackbox.log')
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
87 fp = filehandles[path]
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
88 del filehandles[path]
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
89 fp.close()
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
90
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
91 def wrapui(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
92 class blackboxui(ui.__class__):
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
93 def __init__(self, src=None):
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
94 super(blackboxui, self).__init__(src)
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
95 if src is None:
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
96 self._partialinit()
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
97 else:
28552
999e1acc61aa blackbox: do not assume self._bb{vfs,repo,fp} are set in blackboxui.__init__
Jun Wu <quark@fb.com>
parents: 28407
diff changeset
98 self._bbfp = getattr(src, '_bbfp', None)
28407
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
99 self._bbinlog = False
28552
999e1acc61aa blackbox: do not assume self._bb{vfs,repo,fp} are set in blackboxui.__init__
Jun Wu <quark@fb.com>
parents: 28407
diff changeset
100 self._bbrepo = getattr(src, '_bbrepo', None)
999e1acc61aa blackbox: do not assume self._bb{vfs,repo,fp} are set in blackboxui.__init__
Jun Wu <quark@fb.com>
parents: 28407
diff changeset
101 self._bbvfs = getattr(src, '_bbvfs', None)
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
102
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
103 def _partialinit(self):
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
104 if util.safehasattr(self, '_bbvfs'):
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
105 return
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
106 self._bbfp = None
28407
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
107 self._bbinlog = False
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
108 self._bbrepo = None
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
109 self._bbvfs = None
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
110
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
111 def copy(self):
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
112 self._partialinit()
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
113 return self.__class__(self)
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
114
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
115 @util.propertycache
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
116 def track(self):
19052
63a783d1ac85 blackbox: fix a case of name capture
Bryan O'Sullivan <bryano@fb.com>
parents: 18831
diff changeset
117 return self.configlist('blackbox', 'track', ['*'])
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
118
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
119 def _openlogfile(self):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
120 def rotate(oldpath, newpath):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
121 try:
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
122 self._bbvfs.unlink(newpath)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
123 except OSError as err:
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
124 if err.errno != errno.ENOENT:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
125 self.debug("warning: cannot remove '%s': %s\n" %
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
126 (newpath, err.strerror))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
127 try:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
128 if newpath:
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
129 self._bbvfs.rename(oldpath, newpath)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
130 except OSError as err:
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
131 if err.errno != errno.ENOENT:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
132 self.debug("warning: cannot rename '%s' to '%s': %s\n" %
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
133 (newpath, oldpath, err.strerror))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
134
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
135 fp = _openlog(self._bbvfs)
33135
0a638f37f2d2 configitems: register 'blackbox.maxsize' as an example of 'configbytes'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33134
diff changeset
136 maxsize = self.configbytes('blackbox', 'maxsize')
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
137 if maxsize > 0:
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
138 st = self._bbvfs.fstat(fp)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
139 if st.st_size >= maxsize:
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
140 path = fp.name
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
141 _closelog(self._bbvfs)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
142 maxfiles = self.configint('blackbox', 'maxfiles', 7)
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
143 for i in xrange(maxfiles - 1, 1, -1):
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
144 rotate(oldpath='%s.%d' % (path, i - 1),
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
145 newpath='%s.%d' % (path, i))
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
146 rotate(oldpath=path,
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
147 newpath=maxfiles > 0 and path + '.1')
28243
45313f5a3a8c blackbox: avoid creating multiple file handles for a single log
timeless <timeless@mozdev.org>
parents: 28090
diff changeset
148 fp = _openlog(self._bbvfs)
19066
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
149 return fp
2cad301a7f06 blackbox: automatically rotate log files
Bryan O'Sullivan <bryano@fb.com>
parents: 19052
diff changeset
150
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
151 def _bbwrite(self, fmt, *args):
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
152 self._bbfp.write(fmt % args)
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
153 self._bbfp.flush()
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
154
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
155 def log(self, event, *msg, **opts):
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
156 global lastui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
157 super(blackboxui, self).log(event, *msg, **opts)
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
158 self._partialinit()
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
159
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
160 if not '*' in self.track and not event in self.track:
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
161 return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
162
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
163 if self._bbfp:
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
164 ui = self
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
165 elif self._bbvfs:
18831
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
166 try:
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
167 self._bbfp = self._openlogfile()
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
168 except (IOError, OSError) as err:
18831
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
169 self.debug('warning: cannot write to blackbox.log: %s\n' %
17f6644a2fbc blackbox: defer opening a log file until needed (issue3869)
Bryan O'Sullivan <bryano@fb.com>
parents: 18810
diff changeset
170 err.strerror)
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
171 del self._bbvfs
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
172 self._bbfp = None
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
173 ui = self
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
174 else:
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
175 # certain ui instances exist outside the context of
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
176 # a repo, so just default to the last blackbox that
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
177 # was seen.
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
178 ui = lastui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
179
28407
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
180 if not ui or not ui._bbfp:
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
181 return
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
182 if not lastui or ui._bbrepo:
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
183 lastui = ui
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
184 if ui._bbinlog:
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
185 # recursion guard
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
186 return
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
187 try:
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
188 ui._bbinlog = True
32412
043948c84647 devel: update blackbox to use default-date
Boris Feld <boris.feld@octobus.net>
parents: 32337
diff changeset
189 default = self.configdate('devel', 'default-date')
043948c84647 devel: update blackbox to use default-date
Boris Feld <boris.feld@octobus.net>
parents: 32337
diff changeset
190 date = util.datestr(default, '%Y/%m/%d %H:%M:%S')
18787
f56278a0a0c5 blackbox: use util.getuser for portability
Bryan O'Sullivan <bryano@fb.com>
parents: 18786
diff changeset
191 user = util.getuser()
32155
055cca8e167b py3: use %d to format integers into bytestrings
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29841
diff changeset
192 pid = '%d' % util.getpid()
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
193 formattedmsg = msg[0] % msg[1:]
28245
caa2a0c6fbb7 blackbox: log working directory version
timeless <timeless@mozdev.org>
parents: 28244
diff changeset
194 rev = '(unknown)'
28246
b862e793ec10 blackbox: log dirty state
timeless <timeless@mozdev.org>
parents: 28245
diff changeset
195 changed = ''
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
196 if ui._bbrepo:
28247
d2c0527af364 blackbox: store the blackbox ui object instead of the log file
timeless <timeless@mozdev.org>
parents: 28246
diff changeset
197 ctx = ui._bbrepo[None]
28304
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
198 parents = ctx.parents()
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
199 rev = ('+'.join([hex(p.node()) for p in parents]))
33361
66fe60d5f291 blackbox: simplify the dirty check
Matt Harbison <matt_harbison@yahoo.com>
parents: 33190
diff changeset
200 if (ui.configbool('blackbox', 'dirty') and
66fe60d5f291 blackbox: simplify the dirty check
Matt Harbison <matt_harbison@yahoo.com>
parents: 33190
diff changeset
201 ctx.dirty(missing=True, merge=False, branch=False)):
28304
6b38888ab033 blackbox: remove hexfn
timeless <timeless@mozdev.org>
parents: 28303
diff changeset
202 changed = '+'
33190
0ef40bb20264 configitems: register the 'blackbox.logsource' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33189
diff changeset
203 if ui.configbool('blackbox', 'logsource'):
28305
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
204 src = ' [%s]' % event
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
205 else:
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
206 src = ''
18786
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
207 try:
28305
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
208 ui._bbwrite('%s %s @%s%s (%s)%s> %s',
f5ae291dfedf blackbox: optionally log event source
timeless <timeless@mozdev.org>
parents: 28304
diff changeset
209 date, user, rev, changed, pid, src, formattedmsg)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25186
diff changeset
210 except IOError as err:
18786
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
211 self.debug('warning: cannot write to blackbox.log: %s\n' %
ed39a8f94e95 blackbox: prevent failed I/O from causing hg to abort
Bryan O'Sullivan <bryano@fb.com>
parents: 18676
diff changeset
212 err.strerror)
28407
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
213 finally:
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
214 ui._bbinlog = False
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
215
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
216 def setrepo(self, repo):
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
217 self._bbfp = None
28407
63da8bd0c65e blackbox: guard against recursion from dirty check
timeless <timeless@mozdev.org>
parents: 28305
diff changeset
218 self._bbinlog = False
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
219 self._bbrepo = repo
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
220 self._bbvfs = repo.vfs
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
221
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
222 ui.__class__ = blackboxui
28248
851c41a21869 blackbox: properly replace ui class
timeless <timeless@mozdev.org>
parents: 28247
diff changeset
223 uimod.ui = blackboxui
18669
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
224
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
225 def uisetup(ui):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
226 wrapui(ui)
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
227
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
228 def reposetup(ui, repo):
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
229 # During 'hg pull' a httppeer repo is created to represent the remote repo.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
230 # It doesn't have a .hg directory to put a blackbox in, so we don't do
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
231 # the blackbox setup for it.
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
232 if not repo.local():
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
233 return
18242716a014 blackbox: adds a blackbox extension
Durham Goode <durham@fb.com>
parents:
diff changeset
234
19230
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
235 if util.safehasattr(ui, 'setrepo'):
6d6f148cada9 blackbox: fix blackbox causing exceptions in tests
Durham Goode <durham@fb.com>
parents: 19162
diff changeset
236 ui.setrepo(repo)
33436
9bb4decd43b0 repovfs: add a ward to check if locks are properly taken
Boris Feld <boris.feld@octobus.net>
parents: 33361
diff changeset
237 repo._wlockfreeprefix.add('blackbox.log')
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
238
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
239 @command('^blackbox',
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
240 [('l', 'limit', 10, _('the number of events to show')),
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
241 ],
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
242 _('hg blackbox [OPTION]...'))
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
243 def blackbox(ui, repo, *revs, **opts):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
244 '''view the recent repository events
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
245 '''
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
246
28026
a6db1163befa blackbox: refactor use of vfs as _bbvfs
timeless <timeless@mozdev.org>
parents: 28025
diff changeset
247 if not repo.vfs.exists('blackbox.log'):
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
248 return
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
249
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
250 limit = opts.get('limit')
28244
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
251 fp = repo.vfs('blackbox.log', 'r')
c17d7b1c40be blackbox: rename fp variable
timeless <timeless@mozdev.org>
parents: 28243
diff changeset
252 lines = fp.read().split('\n')
18673
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
253
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
254 count = 0
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
255 output = []
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
256 for line in reversed(lines):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
257 if count >= limit:
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
258 break
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
259
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
260 # count the commands by matching lines like: 2013/01/23 19:13:36 root>
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
261 if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line):
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
262 count += 1
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
263 output.append(line)
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
264
f27598902007 blackbox: adds a 'blackbox' command for viewing recent logs
Durham Goode <durham@fb.com>
parents: 18669
diff changeset
265 ui.status('\n'.join(reversed(output)))