comparison hgext/blackbox.py @ 18669:18242716a014

blackbox: adds a blackbox extension Adds a blackbox extension that listens to ui.log() and writes the messages to .hg/blackbox.log. Future commits will use ui.log() to log commands, unhandled exceptions, incoming changes, and hooks. The extension defaults to logging everything, but can be configured via blackbox.track to only log certain events. Log lines are of the format: "date time user> message" Example log line: 2013/02/09 08:35:19 durham> 1 incoming changes - new heads: d84ced58aaa
author Durham Goode <durham@fb.com>
date Tue, 12 Feb 2013 14:08:33 -0800
parents
children f27598902007
comparison
equal deleted inserted replaced
18668:4034b8d551b1 18669:18242716a014
1 # worker.py - master-slave parallelism support
2 #
3 # Copyright 2013 Facebook, Inc.
4 #
5 # 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
8 """log repository events to a blackbox for debugging
9
10 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 Examples:
13
14 [blackbox]
15 track = *
16
17 [blackbox]
18 track = command, commandfinish, commandexception, exthook, pythonhook
19
20 [blackbox]
21 track = incoming
22
23 """
24
25 from mercurial import util, cmdutil
26 from mercurial.i18n import _
27 import os, getpass, re, string
28
29 cmdtable = {}
30 command = cmdutil.command(cmdtable)
31 testedwith = 'internal'
32 lastblackbox = None
33
34 def wrapui(ui):
35 class blackboxui(ui.__class__):
36 @util.propertycache
37 def track(self):
38 return ui.configlist('blackbox', 'track', ['*'])
39
40 def log(self, event, *msg, **opts):
41 global lastblackbox
42 super(blackboxui, self).log(event, *msg, **opts)
43
44 if not '*' in self.track and not event in self.track:
45 return
46
47 if util.safehasattr(self, '_blackbox'):
48 blackbox = self._blackbox
49 else:
50 # certain ui instances exist outside the context of
51 # a repo, so just default to the last blackbox that
52 # was seen.
53 blackbox = lastblackbox
54
55 if blackbox:
56 date = util.datestr(None, '%Y/%m/%d %H:%M:%S')
57 user = getpass.getuser()
58 formattedmsg = msg[0] % msg[1:]
59 blackbox.write('%s %s> %s' % (date, user, formattedmsg))
60 lastblackbox = blackbox
61
62 def setrepo(self, repo):
63 self._blackbox = repo.opener('blackbox.log', 'a')
64
65 ui.__class__ = blackboxui
66
67 def uisetup(ui):
68 wrapui(ui)
69
70 def reposetup(ui, repo):
71 # 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 # the blackbox setup for it.
74 if not repo.local():
75 return
76
77 ui.setrepo(repo)