# HG changeset patch # User Boris Feld # Date 2018-10-22 13:51:01 # Node ID 106adc2614922a24adc1e662ea78c83ec19aa4bf # Parent 6bd477ee729473160d1cd99554f4f1f5d6a87f58 logtoprocess: sends the canonical command name to the subprocess One of the use-case of logtoprocess is to monitor command duration. With the current code, we only get whatever command name the user typed (either abbreviated or aliased). This makes analytics on the collected data more difficult. Stores the canonical command name in the request object. Pass the stored canonical name in the `req.ui.log("commandfinish", ...)` call as keyword argument to not break potential string formatting. Pass the value as the environment variable named `LTP_COMMAND` to the called script. Differential Revision: https://phab.mercurial-scm.org/D4820 diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -66,6 +66,9 @@ class request(object): # low-level repo state (for example, changelog) before extensions. self.prereposetups = prereposetups or [] + # store the parsed and canonical command + self.canonical_command = None + def _runexithandlers(self): exc = None handlers = self.ui._exithandlers @@ -243,7 +246,8 @@ def dispatch(req): req.ui.log('uiblocked', 'ui blocked ms', **pycompat.strkwargs(req.ui._blockedtimes)) req.ui.log("commandfinish", "%s exited %d after %0.2f seconds\n", - msg, ret & 255, duration) + msg, ret & 255, duration, + canonical_command=req.canonical_command) try: req._runexithandlers() except: # exiting, so no re-raises @@ -853,6 +857,9 @@ def _dispatch(req): fullargs = args cmd, func, args, options, cmdoptions = _parse(lui, args) + # store the canonical command name in request object for later access + req.canonical_command = cmd + if options["config"] != req.earlyoptions["config"]: raise error.Abort(_("option --config may not be abbreviated!")) if options["cwd"] != req.earlyoptions["cwd"]: diff --git a/tests/test-logtoprocess.t b/tests/test-logtoprocess.t --- a/tests/test-logtoprocess.t +++ b/tests/test-logtoprocess.t @@ -17,7 +17,7 @@ Test if logtoprocess correctly captures > configitem('logtoprocess', 'foo', > default=None, > ) - > @command(b'foo', []) + > @command(b'foobar', []) > def foo(ui, repo): > ui.log('foo', 'a message: %s\n', 'spam') > EOF @@ -35,7 +35,8 @@ Test if logtoprocess correctly captures > echo "\$EVENT"; > echo "\$MSG1"; > echo "\$MSG2"; - > echo "\$MSG3") > $TESTTMP/commandfinish.log + > echo "\$MSG3"; + > echo "canonical: \$OPT_CANONICAL_COMMAND") > $TESTTMP/commandfinish.log > foo=(echo 'logtoprocess foo output:'; > echo "\$EVENT"; > echo "\$MSG1"; @@ -46,22 +47,23 @@ Running a command triggers both a ui.log ui.log('commandfinish') call. The foo command also uses ui.log. Use sort to avoid ordering issues between the various processes we spawn: - $ hg foo + $ hg fooba $ sleep 1 $ cat $TESTTMP/command.log | sort command - foo - foo + fooba + fooba logtoprocess command output: #if no-chg $ cat $TESTTMP/commandfinish.log | sort 0 + canonical: foobar commandfinish - foo - foo exited 0 after * seconds (glob) + fooba + fooba exited 0 after * seconds (glob) logtoprocess commandfinish output: $ cat $TESTTMP/foo.log | sort