diff --git a/.travis.yml b/.travis.yml index a8bad24..a6afdec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,15 @@ language: python python: - "2.7" - - "3.3" - "3.4" - "3.5" - - "3.6-dev" # 3.6 development branch + - "3.6" + - "3.7" + - "3.8" + - "3.8-dev" -install: "pip install ." +install: + - pip install . -script: py.test +script: + - pytest diff --git a/glog.py b/glog.py index 1aa0f75..693a80a 100644 --- a/glog.py +++ b/glog.py @@ -1,10 +1,11 @@ """A simple Google-style logging wrapper.""" import logging +import colorlog import time import traceback import os - +import time import gflags as flags FLAGS = flags.FLAGS @@ -18,7 +19,7 @@ def format_message(record): return record_message -class GlogFormatter(logging.Formatter): +class GlogFormatter(colorlog.ColoredFormatter): LEVEL_MAP = { logging.FATAL: 'F', # FATAL is alias of CRITICAL logging.ERROR: 'E', @@ -28,7 +29,7 @@ class GlogFormatter(logging.Formatter): } def __init__(self): - logging.Formatter.__init__(self) + colorlog.ColoredFormatter.__init__(self, '%(log_color)s%(message)s%(reset)s') def format(self, record): try: @@ -45,7 +46,8 @@ def format(self, record): record.lineno, format_message(record)) record.getMessage = lambda: record_message - return logging.Formatter.format(self, record) + return colorlog.ColoredFormatter.format(self, record) + logger = logging.getLogger() handler = logging.StreamHandler() @@ -56,8 +58,22 @@ def setLevel(newlevel): logger.debug('Log level set to %s', newlevel) +def setDirectory(directory): + if not os.path.exists(directory): + os.makedirs(directory) + + localtime = time.localtime() + filepath = directory + "/%04d%02d%02d-%02d%02d%02d.log" % ( + localtime.tm_year, localtime.tm_mon, localtime.tm_mday, localtime.tm_hour, localtime.tm_min, localtime.tm_sec) + fhandler = logging.FileHandler(filepath) + logger.addHandler(fhandler) + logger.debug('Log path set to %s' % filepath) + + def init(): setLevel(FLAGS.verbosity) + setDirectory(FLAGS.directory) + debug = logging.debug info = logging.info @@ -86,16 +102,16 @@ def init(): _level_letters = [name[0] for name in _level_names.values()] GLOG_PREFIX_REGEX = ( - r""" - (?x) ^ - (?P[%s]) - (?P\d\d)(?P\d\d)\s - (?P\d\d):(?P\d\d):(?P\d\d) - \.(?P\d{6})\s+ - (?P-?\d+)\s - (?P[a-zA-Z<_][\w._<>-]+):(?P\d+) - \]\s - """) % ''.join(_level_letters) + r""" + (?x) ^ + (?P[%s]) + (?P\d\d)(?P\d\d)\s + (?P\d\d):(?P\d\d):(?P\d\d) + \.(?P\d{6})\s+ + (?P-?\d+)\s + (?P[a-zA-Z<_][\w._<>-]+):(?P\d+) + \]\s + """) % ''.join(_level_letters) """Regex you can use to parse glog line prefixes.""" handler.setFormatter(GlogFormatter()) @@ -111,6 +127,7 @@ def Parse(self, arg): flags.BooleanFlag.Parse(self, arg) logging.captureWarnings(self.value) + flags.DEFINE_flag(CaptureWarningsFlag()) @@ -123,13 +140,14 @@ def Parse(self, arg): # Look up the name for this level (DEBUG, INFO, etc) if it exists try: level = logging._levelNames.get(intarg, intarg) - except AttributeError: # This was renamed somewhere b/w 2.7 and 3.4 + except AttributeError: # This was renamed somewhere b/w 2.7 and 3.4 level = logging._levelToName.get(intarg, intarg) except ValueError: level = arg setLevel(level) return level + flags.DEFINE( parser=VerbosityParser(), serializer=flags.ArgumentSerializer(), @@ -138,6 +156,20 @@ def Parse(self, arg): help='Logging verbosity') +class DirectoryParser(flags.ArgumentParser): + def Parse(self, arg): + setDirectory(arg) + return arg + + +flags.DEFINE( + parser=DirectoryParser(), + serializer=flags.ArgumentSerializer(), + name='logdir', + default=None, + help='The directory of log output.') + + # Define functions emulating C++ glog check-macros # https://htmlpreview.github.io/?https://github.com/google/glog/master/doc/glog.html#check diff --git a/setup.py b/setup.py index e03f13e..5c54d2d 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import os import setuptools -VERSION = '0.3.1' +VERSION = '0.3.2' README = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read() @@ -14,6 +14,7 @@ url='https://github.com/benley/python-glog', install_requires=[ 'python-gflags>=3.1', + 'colorlog', 'six', # glog doesn't need six, but gflags 3.1 does and its distutils # "requires" line apparently accomplishes nothing, so ... ],