##// END OF EJS Templates
blackbox: fix literal block syntax
Takumi IINO -
r19162:27013ace stable
parent child Browse files
Show More
@@ -1,157 +1,157 b''
1 1 # blackbox.py - log repository events to a file for post-mortem debugging
2 2 #
3 3 # Copyright 2010 Nicolas Dumazet
4 4 # Copyright 2013 Facebook, Inc.
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 """log repository events to a blackbox for debugging
10 10
11 11 Logs event information to .hg/blackbox.log to help debug and diagnose problems.
12 12 The events that get logged can be configured via the blackbox.track config key.
13 Examples:
13 Examples::
14 14
15 15 [blackbox]
16 16 track = *
17 17
18 18 [blackbox]
19 19 track = command, commandfinish, commandexception, exthook, pythonhook
20 20
21 21 [blackbox]
22 22 track = incoming
23 23
24 24 [blackbox]
25 25 # limit the size of a log file
26 26 maxsize = 1.5 MB
27 27 # rotate up to N log files when the current one gets too big
28 28 maxfiles = 3
29 29
30 30 """
31 31
32 32 from mercurial import util, cmdutil
33 33 from mercurial.i18n import _
34 34 import errno, os, re
35 35
36 36 cmdtable = {}
37 37 command = cmdutil.command(cmdtable)
38 38 testedwith = 'internal'
39 39 lastblackbox = None
40 40
41 41 def wrapui(ui):
42 42 class blackboxui(ui.__class__):
43 43 @util.propertycache
44 44 def track(self):
45 45 return self.configlist('blackbox', 'track', ['*'])
46 46
47 47 def _openlogfile(self):
48 48 def rotate(oldpath, newpath):
49 49 try:
50 50 os.unlink(newpath)
51 51 except OSError, err:
52 52 if err.errno != errno.ENOENT:
53 53 self.debug("warning: cannot remove '%s': %s\n" %
54 54 (newpath, err.strerror))
55 55 try:
56 56 if newpath:
57 57 os.rename(oldpath, newpath)
58 58 except OSError, err:
59 59 if err.errno != errno.ENOENT:
60 60 self.debug("warning: cannot rename '%s' to '%s': %s\n" %
61 61 (newpath, oldpath, err.strerror))
62 62
63 63 fp = self._bbopener('blackbox.log', 'a')
64 64 maxsize = self.configbytes('blackbox', 'maxsize', 1048576)
65 65 if maxsize > 0:
66 66 st = os.fstat(fp.fileno())
67 67 if st.st_size >= maxsize:
68 68 path = fp.name
69 69 fp.close()
70 70 maxfiles = self.configint('blackbox', 'maxfiles', 7)
71 71 for i in xrange(maxfiles - 1, 1, -1):
72 72 rotate(oldpath='%s.%d' % (path, i - 1),
73 73 newpath='%s.%d' % (path, i))
74 74 rotate(oldpath=path,
75 75 newpath=maxfiles > 0 and path + '.1')
76 76 fp = self._bbopener('blackbox.log', 'a')
77 77 return fp
78 78
79 79 def log(self, event, *msg, **opts):
80 80 global lastblackbox
81 81 super(blackboxui, self).log(event, *msg, **opts)
82 82
83 83 if not '*' in self.track and not event in self.track:
84 84 return
85 85
86 86 if util.safehasattr(self, '_blackbox'):
87 87 blackbox = self._blackbox
88 88 elif util.safehasattr(self, '_bbopener'):
89 89 try:
90 90 self._blackbox = self._openlogfile()
91 91 except (IOError, OSError), err:
92 92 self.debug('warning: cannot write to blackbox.log: %s\n' %
93 93 err.strerror)
94 94 del self._bbopener
95 95 self._blackbox = None
96 96 blackbox = self._blackbox
97 97 else:
98 98 # certain ui instances exist outside the context of
99 99 # a repo, so just default to the last blackbox that
100 100 # was seen.
101 101 blackbox = lastblackbox
102 102
103 103 if blackbox:
104 104 date = util.datestr(None, '%Y/%m/%d %H:%M:%S')
105 105 user = util.getuser()
106 106 formattedmsg = msg[0] % msg[1:]
107 107 try:
108 108 blackbox.write('%s %s> %s' % (date, user, formattedmsg))
109 109 except IOError, err:
110 110 self.debug('warning: cannot write to blackbox.log: %s\n' %
111 111 err.strerror)
112 112 lastblackbox = blackbox
113 113
114 114 def setrepo(self, repo):
115 115 self._bbopener = repo.opener
116 116
117 117 ui.__class__ = blackboxui
118 118
119 119 def uisetup(ui):
120 120 wrapui(ui)
121 121
122 122 def reposetup(ui, repo):
123 123 # During 'hg pull' a httppeer repo is created to represent the remote repo.
124 124 # It doesn't have a .hg directory to put a blackbox in, so we don't do
125 125 # the blackbox setup for it.
126 126 if not repo.local():
127 127 return
128 128
129 129 ui.setrepo(repo)
130 130
131 131 @command('^blackbox',
132 132 [('l', 'limit', 10, _('the number of events to show')),
133 133 ],
134 134 _('hg blackbox [OPTION]...'))
135 135 def blackbox(ui, repo, *revs, **opts):
136 136 '''view the recent repository events
137 137 '''
138 138
139 139 if not os.path.exists(repo.join('blackbox.log')):
140 140 return
141 141
142 142 limit = opts.get('limit')
143 143 blackbox = repo.opener('blackbox.log', 'r')
144 144 lines = blackbox.read().split('\n')
145 145
146 146 count = 0
147 147 output = []
148 148 for line in reversed(lines):
149 149 if count >= limit:
150 150 break
151 151
152 152 # count the commands by matching lines like: 2013/01/23 19:13:36 root>
153 153 if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line):
154 154 count += 1
155 155 output.append(line)
156 156
157 157 ui.status('\n'.join(reversed(output)))
General Comments 0
You need to be logged in to leave comments. Login now