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