You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by mc...@apache.org on 2014/05/29 19:08:47 UTC

git commit: Fix client logging.

Repository: incubator-aurora
Updated Branches:
  refs/heads/master d92f86c8c -> ab286ac19


Fix client logging.

- Make client print logs at levels INFO and greater to stderr instead
  of discarding.
- Add a clean log printer.
- Add a log level to differentiate between log messages that should be
  shown to user, and logs that should be sent to a distributed log
  transcript.

Bugs closed: aurora-473

Reviewed at https://reviews.apache.org/r/21980/


Project: http://git-wip-us.apache.org/repos/asf/incubator-aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-aurora/commit/ab286ac1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-aurora/tree/ab286ac1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-aurora/diff/ab286ac1

Branch: refs/heads/master
Commit: ab286ac197b42b0529737a274a6529549eb3e621
Parents: d92f86c
Author: Mark Chu-Carroll <mc...@twopensource.com>
Authored: Thu May 29 13:06:08 2014 -0400
Committer: Mark Chu-Carroll <mc...@twitter.com>
Committed: Thu May 29 13:06:08 2014 -0400

----------------------------------------------------------------------
 src/main/python/apache/aurora/client/cli/BUILD  |  1 +
 .../python/apache/aurora/client/cli/__init__.py |  3 +-
 .../python/apache/aurora/client/cli/client.py   |  4 +-
 .../python/apache/aurora/client/cli/logsetup.py | 63 ++++++++++++++++++++
 .../apache/aurora/client/cli/test_logging.py    | 10 ++--
 5 files changed, 74 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/ab286ac1/src/main/python/apache/aurora/client/cli/BUILD
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/cli/BUILD b/src/main/python/apache/aurora/client/cli/BUILD
index b3b8661..5392ed9 100644
--- a/src/main/python/apache/aurora/client/cli/BUILD
+++ b/src/main/python/apache/aurora/client/cli/BUILD
@@ -45,6 +45,7 @@ python_library(
     'command_hooks.py',
     'cron.py',
     'jobs.py',
+    'logsetup.py',
     'options.py',
     'quota.py',
     'sla.py',

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/ab286ac1/src/main/python/apache/aurora/client/cli/__init__.py
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/cli/__init__.py b/src/main/python/apache/aurora/client/cli/__init__.py
index bd9ea67..fd6f96e 100644
--- a/src/main/python/apache/aurora/client/cli/__init__.py
+++ b/src/main/python/apache/aurora/client/cli/__init__.py
@@ -40,6 +40,7 @@ from uuid import uuid1
 from twitter.common.python.pex import PexInfo
 
 from .command_hooks import GlobalCommandHookRegistry
+from .logsetup import TRANSCRIPT
 
 # Constants for standard return codes.
 EXIT_OK = 0
@@ -374,7 +375,7 @@ class CommandLine(object):
     if args[0] == "help":
       return self.help_cmd(args[1:])
     noun, context = self._parse_args(args)
-    print_aurora_log(logging.INFO, "Command=(%s)", args)
+    print_aurora_log(TRANSCRIPT, "Command=(%s)", args)
     pre_result = self._run_pre_hooks_and_plugins(context, args)
     if pre_result is not EXIT_OK:
       return pre_result

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/ab286ac1/src/main/python/apache/aurora/client/cli/client.py
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/cli/client.py b/src/main/python/apache/aurora/client/cli/client.py
index ab0a7ef..1fb5364 100644
--- a/src/main/python/apache/aurora/client/cli/client.py
+++ b/src/main/python/apache/aurora/client/cli/client.py
@@ -15,6 +15,8 @@ import sys
 
 from apache.aurora.client.cli import CommandLine
 from apache.aurora.client.cli.bridge import Bridge, CommandProcessor
+from apache.aurora.client.cli.logsetup import setup_default_log_handlers
+import logging
 
 
 class AuroraCommandLine(CommandLine):
@@ -52,6 +54,7 @@ class AuroraClientV2CommandProcessor(CommandProcessor):
     return self.commandline.registered_nouns
 
   def execute(self, args):
+    setup_default_log_handlers(logging.INFO)
     return self.commandline.execute(args[1:])
 
 
@@ -70,7 +73,6 @@ class AuroraClientV1CommandProcessor(CommandProcessor):
     from apache.aurora.client.bin.aurora_client import proxy_main as clientone_proxy_main
     return clientone_proxy_main()
 
-
 def proxy_main():
   v2 = AuroraClientV2CommandProcessor()
   v1 = AuroraClientV1CommandProcessor()

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/ab286ac1/src/main/python/apache/aurora/client/cli/logsetup.py
----------------------------------------------------------------------
diff --git a/src/main/python/apache/aurora/client/cli/logsetup.py b/src/main/python/apache/aurora/client/cli/logsetup.py
new file mode 100644
index 0000000..15fb306
--- /dev/null
+++ b/src/main/python/apache/aurora/client/cli/logsetup.py
@@ -0,0 +1,63 @@
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import logging
+import sys
+
+# A new log level, for information that's slightly more important than debugging.
+# This is the level of log information that will be sent to a distibuted
+# log to gather information about user behavior.
+TRANSCRIPT = logging.DEBUG + 1
+logging.addLevelName(TRANSCRIPT, "TRANSCRIPT")
+
+class PlainFormatter(logging.Formatter):
+  """
+    Format a log in a simple style:
+    type] msg
+  """
+  SCHEME = "plain"
+
+  LEVEL_MAP = {
+    logging.FATAL: "FATAL",
+    logging.ERROR: "ERROR",
+    logging.WARN:  "WARN",
+    logging.INFO:  "info",
+    TRANSCRIPT: "transcript",
+    logging.DEBUG: "debug"
+  }
+
+  def __init__(self):
+    logging.Formatter.__init__(self)
+
+  def format(self, record):
+    try:
+      record_message = "%s" % (record.msg % record.args)
+    except TypeError:
+      record_message = record.msg
+    try:
+      level = PlainFormatter.LEVEL_MAP[record.levelno]
+    except:
+      level = "?????"
+    record_message = "log(%s): %s" % (level, record_message)
+    record.getMessage = lambda: record_message
+    return logging.Formatter.format(self, record)
+
+
+def setup_default_log_handlers(level):
+  stderr_handler = logging.StreamHandler(sys.stderr)
+  stderr_handler.setLevel(level)
+  stderr_handler.setFormatter(PlainFormatter())
+  root_logger = logging.getLogger()
+  root_logger.addHandler(stderr_handler)
+  root_logger.setLevel(logging.INFO)

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/ab286ac1/src/test/python/apache/aurora/client/cli/test_logging.py
----------------------------------------------------------------------
diff --git a/src/test/python/apache/aurora/client/cli/test_logging.py b/src/test/python/apache/aurora/client/cli/test_logging.py
index 7db0241..b3c3b8d 100644
--- a/src/test/python/apache/aurora/client/cli/test_logging.py
+++ b/src/test/python/apache/aurora/client/cli/test_logging.py
@@ -100,7 +100,7 @@ class TestLogging(AuroraClientCommandTest):
     """
     mock_log_handler = MockHandler()
     logger = logging.getLogger('aurora_client')
-    logger.setLevel(logging.INFO)
+    logger.setLevel(logging.DEBUG)
     logger.addHandler(mock_log_handler)
     # We'll patch out create_context, which will give us a fake context
     # object, and everything can be stubbed through that.
@@ -124,9 +124,9 @@ class TestLogging(AuroraClientCommandTest):
             fp.name])
 
       # Check that things were logged correctly:
-      # there should be two entries, with the clientid and username;
-      # the first entry should log the command being invoked.
-      assert ("'job', 'create', '--wait-until=RUNNING', 'west/bozo/test/hello'" in
-          mock_log_handler.logs[0].getMessage())
+      # there should be at least two entries, with the clientid and username;
+      # and one entry should log the command being invoked.
+      assert any(("'job', 'create', '--wait-until=RUNNING', 'west/bozo/test/hello'" in
+          r.getMessage()) for r in mock_log_handler.logs)
       assert mock_log_handler.logs[0].clientid == mock_log_handler.logs[1].clientid
       assert mock_log_handler.logs[0].user == mock_log_handler.logs[1].user