[PATCH 2 of 8 v3] ui: provide a mechanism to track and log blocked time
Simon Farnsworth
simonfar at fb.com
Fri Feb 10 21:06:16 UTC 2017
# HG changeset patch
# User Simon Farnsworth <simonfar at fb.com>
# Date 1486757727 28800
# Fri Feb 10 12:15:27 2017 -0800
# Node ID 25b4512a095b2f3788b255274a15d68dbc10f7b4
# Parent bd40abfb4e5dbaf6e373636c8e7bab7a6bf34e17
ui: provide a mechanism to track and log blocked time
We want to log the time Mercurial spends trapped in things outside
programmatic control. Provide a mechanism to give us both command runtime
and as many different sources of blocking as we deem useful
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -138,6 +138,9 @@
finally:
duration = timeit.default_timer() - starttime
req.ui.flush()
+ if req.ui.logblockedtimes:
+ req.ui._blockedtimes['command_duration'] = duration * 1000
+ req.ui.log('uiblocked', 'ui blocked ms', **req.ui._blockedtimes)
req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n",
msg, ret or 0, duration)
return ret
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -7,6 +7,7 @@
from __future__ import absolute_import
+import collections
import contextlib
import errno
import getpass
@@ -16,6 +17,7 @@
import socket
import sys
import tempfile
+import timeit
import traceback
from .i18n import _
@@ -120,6 +122,8 @@
self.callhooks = True
# Insecure server connections requested.
self.insecureconnections = False
+ # Blocked time
+ self.logblockedtimes = False
if src:
self.fout = src.fout
@@ -137,6 +141,7 @@
self.fixconfig()
self.httppasswordmgrdb = src.httppasswordmgrdb
+ self._blockedtimes = src._blockedtimes
else:
self.fout = util.stdout
self.ferr = util.stderr
@@ -146,6 +151,7 @@
self.environ = encoding.environ
self.httppasswordmgrdb = urlreq.httppasswordmgrwithdefaultrealm()
+ self._blockedtimes = collections.defaultdict(lambda: 0)
allowed = self.configlist('experimental', 'exportableenviron')
if '*' in allowed:
@@ -174,6 +180,14 @@
self._progbar.resetstate() # reset last-print time of progress bar
self.httppasswordmgrdb = urlreq.httppasswordmgrwithdefaultrealm()
+ @contextlib.contextmanager
+ def timeblockedsection(self, key):
+ starttime = timeit.default_timer()
+ yield
+ duration = (timeit.default_timer() - starttime) * 1000
+ key += '_blocked'
+ self._blockedtimes[key] += duration
+
def formatter(self, topic, opts):
return formatter.formatter(self, topic, opts)
@@ -277,6 +291,7 @@
self._reportuntrusted = self.debugflag or self.configbool("ui",
"report_untrusted", True)
self.tracebackflag = self.configbool('ui', 'traceback', False)
+ self.logblockedtimes = self.configbool('ui', 'logblockedtimes')
if section in (None, 'trusted'):
# update trust information
diff --git a/tests/test-logtoprocess.t b/tests/test-logtoprocess.t
--- a/tests/test-logtoprocess.t
+++ b/tests/test-logtoprocess.t
@@ -10,6 +10,7 @@
> def foo(ui, repo):
> ui.log('foo', 'a message: %(bar)s\n', bar='spam')
> EOF
+ $ cp $HGRCPATH $HGRCPATH.bak
$ cat >> $HGRCPATH << EOF
> [extensions]
> logtoprocess=
@@ -52,3 +53,18 @@
logtoprocess commandfinish output:
logtoprocess foo output:
spam
+
+Confirm that logging blocked time catches stdio properly:
+ $ cp $HGRCPATH.bak $HGRCPATH
+ $ cat >> $HGRCPATH << EOF
+ > [extensions]
+ > logtoprocess=
+ > pager=
+ > [logtoprocess]
+ > uiblocked=echo "\$EVENT stdio \$OPT_STDIO_BLOCKED ms command \$OPT_COMMAND_DURATION ms"
+ > [ui]
+ > logblockedtimes=True
+ > EOF
+
+ $ hg log
+ uiblocked stdio * ms command * ms (glob)
More information about the Mercurial-devel
mailing list