Patchwork [4,of,8] commandserver: install logger to record server events through canonical API

login
register
mail settings
Submitter Yuya Nishihara
Date Dec. 4, 2018, 1:24 p.m.
Message ID <16b28e741caae5151277.1543929858@mimosa>
Download mbox | patch
Permalink /patch/36951/
State Accepted
Headers show

Comments

Yuya Nishihara - Dec. 4, 2018, 1:24 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1541844017 -32400
#      Sat Nov 10 19:00:17 2018 +0900
# Node ID 16b28e741caae51512774eb665071c58c50620b8
# Parent  a784cb45d89bdf7f995a918cd75c3bb3f9e56ded
commandserver: install logger to record server events through canonical API

The global commandserver.log() will be replaced with this.

Patch

diff --git a/mercurial/chgserver.py b/mercurial/chgserver.py
--- a/mercurial/chgserver.py
+++ b/mercurial/chgserver.py
@@ -219,7 +219,7 @@  def _newchgui(srcui, csystem, attachio):
 
     return chgui(srcui)
 
-def _loadnewui(srcui, args):
+def _loadnewui(srcui, args, cdebug):
     from . import dispatch  # avoid cycle
 
     newui = srcui.__class__.load()
@@ -247,8 +247,10 @@  def _loadnewui(srcui, args):
     path, newlui = dispatch._getlocal(newui, rpath, wd=cwd)
 
     extensions.populateui(newui)
+    commandserver.setuplogging(newui, fp=cdebug)
     if newui is not newlui:
         extensions.populateui(newlui)
+        commandserver.setuplogging(newlui, fp=cdebug)
 
     return (newui, newlui)
 
@@ -423,7 +425,7 @@  class chgcmdserver(commandserver.server)
 
         args = self._readlist()
         try:
-            self.ui, lui = _loadnewui(self.ui, args)
+            self.ui, lui = _loadnewui(self.ui, args, self.cdebug)
         except error.ParseError as inst:
             dispatch._formatparse(self.ui.warn, inst)
             self.ui.flush()
diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -26,8 +26,10 @@  from .i18n import _
 from . import (
     encoding,
     error,
+    loggingutil,
     pycompat,
     util,
+    vfs as vfsmod,
 )
 from .utils import (
     cborutil,
@@ -223,11 +225,18 @@  class server(object):
             self.ui = ui
             self.repo = self.repoui = None
 
+        self.cdebug = logfile
         self.cerr = channeledoutput(fout, 'e')
         self.cout = channeledoutput(fout, 'o')
         self.cin = channeledinput(fin, fout, 'I')
         self.cresult = channeledoutput(fout, 'r')
 
+        if self.ui.config(b'cmdserver', b'log') == b'-':
+            # switch log stream of server's ui to the 'd' (debug) channel
+            # (don't touch repo.ui as its lifetime is longer than the server)
+            self.ui = self.ui.copy()
+            setuplogging(self.ui, repo=None, fp=self.cdebug)
+
         # TODO: add this to help/config.txt when stabilized
         # ``channel``
         #   Use separate channel for structured output. (Command-server only)
@@ -356,17 +365,18 @@  class server(object):
 
         return 0
 
-def setuplogging(ui):
+def setuplogging(ui, repo=None, fp=None):
     """Set up server logging facility
 
-    If cmdserver.log is '-', log messages will be sent to the 'd' channel
-    while a client is connected. Otherwise, messages will be written to
-    the stderr of the server process.
+    If cmdserver.log is '-', log messages will be sent to the given fp.
+    It should be the 'd' channel while a client is connected, and otherwise
+    is the stderr of the server process.
     """
     # developer config: cmdserver.log
     logpath = ui.config(b'cmdserver', b'log')
     if not logpath:
         return
+    tracked = {b'cmdserver'}
 
     global logfile
     if logpath == b'-':
@@ -374,6 +384,22 @@  def setuplogging(ui):
     else:
         logfile = open(logpath, 'ab')
 
+    if logpath == b'-' and fp:
+        logger = loggingutil.fileobjectlogger(fp, tracked)
+    elif logpath == b'-':
+        logger = loggingutil.fileobjectlogger(ui.ferr, tracked)
+    else:
+        logpath = os.path.abspath(logpath)
+        vfs = vfsmod.vfs(os.path.dirname(logpath))
+        logger = loggingutil.filelogger(vfs, os.path.basename(logpath), tracked)
+
+    targetuis = {ui}
+    if repo:
+        targetuis.add(repo.baseui)
+        targetuis.add(repo.ui)
+    for u in targetuis:
+        u.setlogger(b'cmdserver', logger)
+
 class pipeservice(object):
     def __init__(self, ui, repo, opts):
         self.ui = ui
diff --git a/mercurial/server.py b/mercurial/server.py
--- a/mercurial/server.py
+++ b/mercurial/server.py
@@ -158,7 +158,7 @@  def _createcmdservice(ui, repo, opts):
         servicefn = _cmdservicemap[mode]
     except KeyError:
         raise error.Abort(_('unknown mode %s') % mode)
-    commandserver.setuplogging(ui)
+    commandserver.setuplogging(ui, repo)
     return servicefn(ui, repo, opts)
 
 def _createhgwebservice(ui, repo, opts):