1. youngking
  2. kahgean

Commits

Can Xue  committed 60e9b28

add test for log kit

  • Participants
  • Parent commits a5f3121
  • Branches default

Comments (0)

Files changed (2)

File kahgean/logkit.py

View file
  • Ignore whitespace
         return s
 
 
-def add_options(options):
+def append_options(options):
     """work with kahgean.options, add arguments to an ``Options`` object"""
     options.add_option('--log-level', help='logging level (default: info)')
     options.add_option('--log-format', help='')
     options.add_option('--log-server', help='')
 
 
-def deal_with_options(options):
-    """work with ``add_options()``, deal with the parsing result of
+def deal_with_options(options, clear_handlers=True):
+    """work with ``append_options()``, deal with the parsing result of
     the ``Options`` object"""
     root_logger = logging.getLogger()
+    # remove all hanlers
+    if clear_handlers:
+        for handler in root_logger.handlers:
+            root_logger.removeHandler(handler)
     # setup log level
-    level_name = options.get('log_level', 'info')
+    level_name = options.get('log-level', 'info')
     root_logger.setLevel(level_name.upper())
     # setup formats
-    format = options.get('log_format', DEFAULT_FORMAT)
-    date_format = options.get('date_format', DEFAULT_DATE_FORMAT)
+    format = options.get('log-format', DEFAULT_FORMAT)
+    date_format = options.get('log-date-format', DEFAULT_DATE_FORMAT)
     # if log_filename is given, use a file-based handler
-    log_filename = options.get('log_filename', None)
+    log_filename = options.get('log-filename', None)
     if log_filename:
         handler = logging.FileHandler(log_filename, encoding='utf8')
         formatter = ColoredFormatter(False, format, date_format)
         handler.setFormatter(formatter)
         root_logger.addHandler(handler)
     # if log_server is given, use a socket-based handler
-    log_server = options.get('log_server', None)
+    log_server = options.get('log-server', None)
     if log_server:
         info = log_server.split(':', 1)
         if len(info) == 2:
             # for ``address:port``
             host, port = info
-            port = int(info)
+            port = int(port)
         else:
             host = info[0]
             port = logging.handlers.DEFAULT_TCP_LOGGING_PORT
-        handler = SocketHandler(host, port)
+        handler = logging.handlers.SocketHandler(host, port)
         root_logger.addHandler(handler)
     # if use stderr to log (either log_to_stderr is True, or no any handlers
     # have been registered to the root logger), try to make log text colorful
-    log_to_stderr = options.get('log_to_stderr', None)
+    log_to_stderr = options.get('log-to-stderr', None)
     if log_to_stderr or (log_to_stderr is None and not root_logger.handlers):
         stderr = sys.stderr
         colored = True

File test/test_logkit.py

View file
  • Ignore whitespace
+# Copyright (C) 2012 Xue Can <xuecan@gmail.com> and contributors.
+# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license
+
+import os
+import sys
+import warnings
+import logging
+from logging.handlers import DEFAULT_TCP_LOGGING_PORT
+from tempfile import NamedTemporaryFile
+import pickle
+import SocketServer
+import struct
+import thread
+import time
+from nose.tools import *
+from kahgean import logkit
+from kahgean.options import Options
+
+
+def setup_module():
+    global options
+    options = Options()
+    logkit.append_options(options)
+
+
+def test_no_options():
+    options.parse_options([])
+    logkit.deal_with_options(options)
+    logging.debug('You should not see this')
+    logging.info('this is an info')
+    logging.warning('this is a warning')
+    logging.error('this is an error')
+    logging.critical('this is a critical error')
+    sys.stderr.write('You should see 4 log lines above with colors, '
+                     'right? (y or N)')
+    answer = raw_input() or 'n'
+    ok_(answer.lower() in ['y', 'yes'])
+
+
+def prepare_logfile():
+    global temp_file
+    temp_file = NamedTemporaryFile(suffix='.log', delete=False)
+    temp_file.close()
+
+
+def cleanup_logfile():
+    if not temp_file.closed:
+        temp_file.close()
+    os.unlink(temp_file.name)
+
+
+@with_setup(prepare_logfile, cleanup_logfile)
+def test_logfile():
+    options.parse_options(['--log-level', 'error',
+                           '--log-filename', temp_file.name])
+    logkit.deal_with_options(options)
+    logging.debug('debug')
+    logging.info('info')
+    logging.error('error')
+    try:
+        raise RuntimeError('exception')
+    except:
+        logging.exception('exception')
+    logging.critical('critical')
+    temp_file.close()
+    fp = open(temp_file.name, 'r')
+    data = fp.read(4096)
+    fp.close()
+    ok_('debug' not in data)
+    ok_('info' not in data)
+    ok_('error' in data)
+    ok_('exception' in data)
+    ok_('critical' in data)
+
+
+def prepare_logserver():
+    global logserver, registry
+    registry = list()
+    logserver = SocketServer.TCPServer(
+        ('localhost', DEFAULT_TCP_LOGGING_PORT + 10000),
+        LogRecordStreamHandler)
+    thread.start_new_thread(logserver.serve_forever, ())
+
+
+@with_setup(prepare_logserver)
+def test_logserver():
+    options.parse_options(['--log-level', 'warning', '--log-server',
+                           'localhost:%d' % (DEFAULT_TCP_LOGGING_PORT + 10000)])
+    logkit.deal_with_options(options)
+    logging.debug('debug')
+    logging.info('info')
+    logging.warning('warning')
+    logging.error('error')
+    try:
+        raise RuntimeError('exception')
+    except:
+        logging.exception('exception')
+    logging.critical('critical')
+    time.sleep(.1)
+    ok_('debug' not in registry)
+    ok_('info' not in registry)
+    ok_('warning' in registry)
+    ok_('error' in registry)
+    ok_('exception' in registry)
+    ok_('critical' in registry)
+
+
+class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
+    """Handler for a streaming logging request.
+
+    For more information about this, please visit:
+    http://docs.python.org/howto/logging-cookbook.html
+    """
+
+    def handle(self):
+        """
+        Handle multiple requests - each expected to be a 4-byte length,
+        followed by the LogRecord in pickle format. Logs the record
+        according to whatever policy is configured locally.
+        """
+        while True:
+            chunk = self.connection.recv(4)
+            if len(chunk) < 4:
+                break
+            slen = struct.unpack('>L', chunk)[0]
+            chunk = self.connection.recv(slen)
+            while len(chunk) < slen:
+                chunk = chunk + self.connection.recv(slen - len(chunk))
+            obj = self.unPickle(chunk)
+            record = logging.makeLogRecord(obj)
+            self.handleLogRecord(record)
+
+
+    def unPickle(self, data):
+        return pickle.loads(data)
+
+    def handleLogRecord(self, record):
+        registry.append(record.msg)