Commit 8ca0f349 authored by Christof Schulze's avatar Christof Schulze 😎
Browse files

added logging to file, some clean ups

parent 3d64adf0
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -5,3 +5,6 @@

*/raw/
.idea/

*.cfg
*.log
 No newline at end of file
+12 −12
Original line number Diff line number Diff line
@@ -21,26 +21,26 @@ import re

from ammsml.config import constants as C

IS_COLOR: bool = True

if not hasattr(sys.stdout, 'isatty') or not sys.stdout.isatty():
    IS_COLOR = False
AMMSML_COLOR: bool = True
if C.AMMSML_NOCOLOR:
    AMMSML_COLOR = False
elif not hasattr(sys.stdout, 'isatty') or not sys.stdout.isatty():
    AMMSML_COLOR = False
else:
    try:
        import curses
        curses.setupterm()
        if curses.tigetnum('colors') < 0:
            IS_COLOR = False
            AMMSML_COLOR = False
    except ImportError:
        # curses library was not found
        pass
    except curses.error:
        # curses returns an error (e.g. could not find terminal)
        IS_COLOR = False
        AMMSML_COLOR = False

# TODO implement some Config entry for Color
# if C.IS_FORCE_COLOR:
#     IS_COLOR = True
if C.AMMSML_FORCE_COLOR:
    AMMSML_COLOR = True

# --- begin "pretty"
#
@@ -88,7 +88,7 @@ def parsecolor(color):
def stringc(text: str, color) -> str:
    """String in color."""

    if IS_COLOR:
    if AMMSML_COLOR:
        color_code = parsecolor(color)
        return "\n".join(["\033[%sm%s\033[0m" % (color_code, t) for t in text.split('\n')])
    else:
@@ -98,13 +98,13 @@ def stringc(text: str, color) -> str:
def colorize(lead, num, color):
    """ Print 'lead' = 'num' in 'color' """
    s = "%s=%-4s" % (lead, str(num))
    if num != 0 and IS_COLOR and color is not None:
    if num != 0 and AMMSML_COLOR and color is not None:
        s = stringc(s, color)
    return s


def hostcolor(host: str, stats: list, color: bool = True) -> str:
    if IS_COLOR and color:
    if AMMSML_COLOR and color:
        if stats['failures'] != 0 or stats['unreachable'] != 0:
            return "%-37s" % stringc(host, C.COLOR_ERROR)
        elif stats['changed'] != 0:
+32 −11
Original line number Diff line number Diff line
@@ -25,13 +25,14 @@ import time
import textwrap
import subprocess
import logging
import getpass

from struct import unpack, pack
from termios import TIOCGWINSZ

from ammsml.utils.color import stringc
from ammsml.utils.parsing import to_text, boolean
from ammsml.utils.errors import AMMSMLError
from ammsml.utils.errors import AMMSMLError, AMMSMLAssertionError
from ammsml.utils.singleton import Singleton, with_metaclass
from ammsml.config import constants as C
from ammsml.utils.wrap import wrap_var
@@ -47,15 +48,16 @@ class FilterBlackList(logging.Filter):

logger = None
# TODO: make this a callback event instead
# if getattr(C, 'DEFAULT_LOG_PATH'):
#     path = C.DEFAULT_LOG_PATH
#     if path and (os.path.exists(path) and os.access(path, os.W_OK)) or os.access(os.path.dirname(path), os.W_OK):
#         logging.basicConfig(filename=path, level=logging.INFO, format='%(asctime)s p=%(user)s u=%(process)d | %(message)s')
#         logger = logging.LoggerAdapter(logging.getLogger('ammsml'), {'user': getpass.getuser()})
#         for handler in logging.root.handlers:
#             handler.addFilter(FilterBlackList(getattr(C, 'DEFAULT_LOG_FILTER', [])))
#     else:
#         print("[WARNING]: log file at %s is not writeable and we cannot create it, aborting\n" % path, file=sys.stderr)
if getattr(C, 'DEFAULT_LOG_PATH'):
    path = C.DEFAULT_LOG_PATH
    if path and (os.path.exists(path) and os.access(path, os.W_OK)) or os.access(os.path.dirname(path), os.W_OK):
        logging.basicConfig(filename=path, level=logging.INFO,
                            format='%(asctime)s p=%(user)s u=%(process)d | %(message)s')
        logger = logging.LoggerAdapter(logging.getLogger('ammsml'), {'user': getpass.getuser()})
        for handler in logging.root.handlers:
            handler.addFilter(FilterBlackList(getattr(C, 'DEFAULT_LOG_FILTER', [])))
    else:
        print("[WARNING]: log file at %s is not writeable and we cannot create it, aborting\n" % path, file=sys.stderr)


# map color to log levels
@@ -150,6 +152,26 @@ class Display(with_metaclass(Singleton, object)):
                if e.errno != errno.EPIPE:
                    raise

        if logger and not screen_only:
            # We first convert to a byte string so that we get rid of
            # color and characters that are invalid in the user's locale
            msg2 = to_text(nocolor.lstrip(u'\n'))

            if sys.version_info >= (3,):
                # Convert back to text string on python3
                msg2 = to_text(msg2, self._output_encoding(stderr=stderr))

            lvl = logging.INFO
            if color:
                # set logger level based on color (not great)
                try:
                    lvl = color_to_log_level[color]
                except KeyError:
                    # this should not happen, but JIC
                    raise AMMSMLAssertionError('Invalid color supplied to display: %s' % color)
            # actually log
            logger.log(lvl, msg2)

    def v(self, msg, host=None):
        return self.verbose(msg, host=host, caplevel=0)

@@ -169,7 +191,6 @@ class Display(with_metaclass(Singleton, object)):
        return self.verbose(msg, host=host, caplevel=5)

    def debug(self, msg, host=None):
        # TODO boolean() neccesary?
        if boolean(C.DEFAULT_DEBUG):
            if host is None:
                self.display("%6d %0.5f: %s" % (os.getpid(), time.time(), msg), color=C.COLOR_DEBUG)
+5 −0
Original line number Diff line number Diff line
@@ -195,3 +195,8 @@ class TemplateParsingError(AMMSMLError):
class AMMSMLOptionsError(AMMSMLError):

    pass


class AMMSMLAssertionError(AMMSMLError, AssertionError):
    """Invalid assertion"""
    pass
+2 −2
Original line number Diff line number Diff line
@@ -38,9 +38,9 @@ def unfrackpath(path, follow=True, basedir=None):
    """
    Returns a path that is free of symlinks (if follow=True), environment variables,
    relative path traversals and symbols (~)
    :param path: A byte or text string representing a path to be canonicalized
    :param path: A byte or text string representing a path to be canonised
    :param follow: A boolean to indicate of symlinks should be resolved or not
    :raises UnicodeDecodeError: If the canonicalized version of the path
    :raises UnicodeDecodeError: If the canonised version of the path
        contains non-utf8 byte sequences.
    :rtype: A text string
    :returns: An absolute path with symlinks, environment variables, and tilde