[PATCH 1 of 6 V2] blackbox: adds a blackbox extension

Durham Goode durham at fb.com
Tue Feb 12 17:12:53 CST 2013


# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1360706913 28800
#      Tue Feb 12 14:08:33 2013 -0800
# Node ID 248720a9332a9fac80d5f1ab2e19b106cf44e90b
# Parent  5b73c50e99dd6bdf5a5c59a0b4b09ced76b684ad
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

diff --git a/hgext/blackbox.py b/hgext/blackbox.py
new file mode 100644
--- /dev/null
+++ b/hgext/blackbox.py
@@ -0,0 +1,70 @@
+"""log repository events to a blackbox for debugging
+
+Logs event information to .hg/blackbox.log to help debug and diagnose problems.
+The events that get logged can be configured via the blackbox.track config key.
+Examples:
+
+  [blackbox]
+  track = *
+
+  [blackbox]
+  track = command, commandfinish, commandexception, exthook, pythonhook
+
+  [blackbox]
+  track = incoming
+
+"""
+
+from mercurial import util, cmdutil
+from mercurial.i18n import _
+import os, getpass, re, string
+
+cmdtable = {}
+command = cmdutil.command(cmdtable)
+testedwith = 'internal'
+lastblackbox = None
+
+def wrapui(ui):
+    class blackboxui(ui.__class__):
+        @util.propertycache
+        def track(self):
+            return ui.configlist('blackbox', 'track', ['*'])
+
+        def log(self, event, *msg, **opts):
+            global lastblackbox
+            super(blackboxui, self).log(event, *msg, **opts)
+
+            if not '*' in self.track and not event in self.track:
+                return
+
+            if util.safehasattr(self, '_blackbox'):
+                blackbox = self._blackbox
+            else:
+                # certain ui instances exist outside the context of
+                # a repo, so just default to the last blackbox that
+                # was seen.
+                blackbox = lastblackbox
+
+            if blackbox:
+                date = util.datestr(None, '%Y/%m/%d %H:%M:%S')
+                user = getpass.getuser()
+                formattedmsg = msg[0] % msg[1:]
+                blackbox.write('%s %s> %s' % (date, user, formattedmsg))
+                lastblackbox = blackbox
+
+        def setrepo(self, repo):
+            self._blackbox = repo.opener('blackbox.log', 'a')
+
+    ui.__class__ = blackboxui
+
+def uisetup(ui):
+    wrapui(ui)
+
+def reposetup(ui, repo):
+    # During 'hg pull' a httppeer repo is created to represent the remote repo.
+    # It doesn't have a .hg directory to put a blackbox in, so we don't do
+    # the blackbox setup for it.
+    if not repo.local():
+        return
+
+    ui.setrepo(repo)
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -739,7 +739,7 @@
         else:
             self.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
 
-    def log(self, service, message):
+    def log(self, service, *msg, **opts):
         '''hook for logging facility extensions
 
         service should be a readily-identifiable subsystem, which will


More information about the Mercurial-devel mailing list