##// END OF EJS Templates
blackbox: fix a case of name capture
Bryan O'Sullivan -
r19052:63a783d1 default
parent child Browse files
Show More
@@ -1,119 +1,119 b''
1 # blackbox.py - log repository events to a file for post-mortem debugging
1 # blackbox.py - log repository events to a file for post-mortem debugging
2 #
2 #
3 # Copyright 2010 Nicolas Dumazet
3 # Copyright 2010 Nicolas Dumazet
4 # Copyright 2013 Facebook, Inc.
4 # Copyright 2013 Facebook, Inc.
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 """log repository events to a blackbox for debugging
9 """log repository events to a blackbox for debugging
10
10
11 Logs event information to .hg/blackbox.log to help debug and diagnose problems.
11 Logs event information to .hg/blackbox.log to help debug and diagnose problems.
12 The events that get logged can be configured via the blackbox.track config key.
12 The events that get logged can be configured via the blackbox.track config key.
13 Examples:
13 Examples:
14
14
15 [blackbox]
15 [blackbox]
16 track = *
16 track = *
17
17
18 [blackbox]
18 [blackbox]
19 track = command, commandfinish, commandexception, exthook, pythonhook
19 track = command, commandfinish, commandexception, exthook, pythonhook
20
20
21 [blackbox]
21 [blackbox]
22 track = incoming
22 track = incoming
23
23
24 """
24 """
25
25
26 from mercurial import util, cmdutil
26 from mercurial import util, cmdutil
27 from mercurial.i18n import _
27 from mercurial.i18n import _
28 import os, re
28 import os, re
29
29
30 cmdtable = {}
30 cmdtable = {}
31 command = cmdutil.command(cmdtable)
31 command = cmdutil.command(cmdtable)
32 testedwith = 'internal'
32 testedwith = 'internal'
33 lastblackbox = None
33 lastblackbox = None
34
34
35 def wrapui(ui):
35 def wrapui(ui):
36 class blackboxui(ui.__class__):
36 class blackboxui(ui.__class__):
37 @util.propertycache
37 @util.propertycache
38 def track(self):
38 def track(self):
39 return ui.configlist('blackbox', 'track', ['*'])
39 return self.configlist('blackbox', 'track', ['*'])
40
40
41 def log(self, event, *msg, **opts):
41 def log(self, event, *msg, **opts):
42 global lastblackbox
42 global lastblackbox
43 super(blackboxui, self).log(event, *msg, **opts)
43 super(blackboxui, self).log(event, *msg, **opts)
44
44
45 if not '*' in self.track and not event in self.track:
45 if not '*' in self.track and not event in self.track:
46 return
46 return
47
47
48 if util.safehasattr(self, '_blackbox'):
48 if util.safehasattr(self, '_blackbox'):
49 blackbox = self._blackbox
49 blackbox = self._blackbox
50 elif util.safehasattr(self, '_bbopener'):
50 elif util.safehasattr(self, '_bbopener'):
51 try:
51 try:
52 self._blackbox = self._bbopener('blackbox.log', 'a')
52 self._blackbox = self._bbopener('blackbox.log', 'a')
53 except (IOError, OSError), err:
53 except (IOError, OSError), err:
54 self.debug('warning: cannot write to blackbox.log: %s\n' %
54 self.debug('warning: cannot write to blackbox.log: %s\n' %
55 err.strerror)
55 err.strerror)
56 del self._bbopener
56 del self._bbopener
57 self._blackbox = None
57 self._blackbox = None
58 blackbox = self._blackbox
58 blackbox = self._blackbox
59 else:
59 else:
60 # certain ui instances exist outside the context of
60 # certain ui instances exist outside the context of
61 # a repo, so just default to the last blackbox that
61 # a repo, so just default to the last blackbox that
62 # was seen.
62 # was seen.
63 blackbox = lastblackbox
63 blackbox = lastblackbox
64
64
65 if blackbox:
65 if blackbox:
66 date = util.datestr(None, '%Y/%m/%d %H:%M:%S')
66 date = util.datestr(None, '%Y/%m/%d %H:%M:%S')
67 user = util.getuser()
67 user = util.getuser()
68 formattedmsg = msg[0] % msg[1:]
68 formattedmsg = msg[0] % msg[1:]
69 try:
69 try:
70 blackbox.write('%s %s> %s' % (date, user, formattedmsg))
70 blackbox.write('%s %s> %s' % (date, user, formattedmsg))
71 except IOError, err:
71 except IOError, err:
72 self.debug('warning: cannot write to blackbox.log: %s\n' %
72 self.debug('warning: cannot write to blackbox.log: %s\n' %
73 err.strerror)
73 err.strerror)
74 lastblackbox = blackbox
74 lastblackbox = blackbox
75
75
76 def setrepo(self, repo):
76 def setrepo(self, repo):
77 self._bbopener = repo.opener
77 self._bbopener = repo.opener
78
78
79 ui.__class__ = blackboxui
79 ui.__class__ = blackboxui
80
80
81 def uisetup(ui):
81 def uisetup(ui):
82 wrapui(ui)
82 wrapui(ui)
83
83
84 def reposetup(ui, repo):
84 def reposetup(ui, repo):
85 # During 'hg pull' a httppeer repo is created to represent the remote repo.
85 # During 'hg pull' a httppeer repo is created to represent the remote repo.
86 # It doesn't have a .hg directory to put a blackbox in, so we don't do
86 # It doesn't have a .hg directory to put a blackbox in, so we don't do
87 # the blackbox setup for it.
87 # the blackbox setup for it.
88 if not repo.local():
88 if not repo.local():
89 return
89 return
90
90
91 ui.setrepo(repo)
91 ui.setrepo(repo)
92
92
93 @command('^blackbox',
93 @command('^blackbox',
94 [('l', 'limit', 10, _('the number of events to show')),
94 [('l', 'limit', 10, _('the number of events to show')),
95 ],
95 ],
96 _('hg blackbox [OPTION]...'))
96 _('hg blackbox [OPTION]...'))
97 def blackbox(ui, repo, *revs, **opts):
97 def blackbox(ui, repo, *revs, **opts):
98 '''view the recent repository events
98 '''view the recent repository events
99 '''
99 '''
100
100
101 if not os.path.exists(repo.join('blackbox.log')):
101 if not os.path.exists(repo.join('blackbox.log')):
102 return
102 return
103
103
104 limit = opts.get('limit')
104 limit = opts.get('limit')
105 blackbox = repo.opener('blackbox.log', 'r')
105 blackbox = repo.opener('blackbox.log', 'r')
106 lines = blackbox.read().split('\n')
106 lines = blackbox.read().split('\n')
107
107
108 count = 0
108 count = 0
109 output = []
109 output = []
110 for line in reversed(lines):
110 for line in reversed(lines):
111 if count >= limit:
111 if count >= limit:
112 break
112 break
113
113
114 # count the commands by matching lines like: 2013/01/23 19:13:36 root>
114 # count the commands by matching lines like: 2013/01/23 19:13:36 root>
115 if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line):
115 if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line):
116 count += 1
116 count += 1
117 output.append(line)
117 output.append(line)
118
118
119 ui.status('\n'.join(reversed(output)))
119 ui.status('\n'.join(reversed(output)))
General Comments 0
You need to be logged in to leave comments. Login now