#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright (C) 2015 GNS3 Technologies Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Provide a pretty logging on console""" import logging import sys class ColouredFormatter(logging.Formatter): RESET = '\x1B[0m' RED = '\x1B[31m' YELLOW = '\x1B[33m' GREEN = '\x1B[32m' PINK = '\x1b[35m' def format(self, record, colour=False): message = super().format(record) if not colour: return message.replace("#RESET#", "") level_no = record.levelno if level_no >= logging.CRITICAL: colour = self.RED elif level_no >= logging.ERROR: colour = self.RED elif level_no >= logging.WARNING: colour = self.YELLOW elif level_no >= logging.INFO: colour = self.GREEN elif level_no >= logging.DEBUG: colour = self.PINK else: colour = self.RESET message = message.replace("#RESET#", self.RESET) message = '{colour}{message}{reset}'.format(colour=colour, message=message, reset=self.RESET) return message class ColouredStreamHandler(logging.StreamHandler): def format(self, record, colour=False): if not isinstance(self.formatter, ColouredFormatter): self.formatter = ColouredFormatter() return self.formatter.format(record, colour) def emit(self, record): stream = self.stream try: msg = self.format(record, stream.isatty()) stream.write(msg) stream.write(self.terminator) self.flush() # On OSX when frozen flush raise a BrokenPipeError except BrokenPipeError: pass except Exception: self.handleError(record) class WinStreamHandler(logging.StreamHandler): def emit(self, record): if sys.stdin.encoding != "utf-8": record = record stream = self.stream try: msg = self.formatter.format(record, stream.isatty()) stream.write(msg.encode(stream.encoding, errors="replace").decode(stream.encoding)) stream.write(self.terminator) self.flush() pass except Exception: self.handleError(record) def init_logger(level, logfile=None, quiet=False): if logfile and len(logfile) > 0: stream_handler = logging.FileHandler(logfile) stream_handler.formatter = ColouredFormatter("{asctime} {levelname} {filename}:{lineno} {message}", "%Y-%m-%d %H:%M:%S", "{") elif sys.platform.startswith("win"): stream_handler = WinStreamHandler(sys.stdout) stream_handler.formatter = ColouredFormatter("{asctime} {levelname} {filename}:{lineno} {message}", "%Y-%m-%d %H:%M:%S", "{") else: stream_handler = ColouredStreamHandler(sys.stdout) stream_handler.formatter = ColouredFormatter("{asctime} {levelname} {filename}:{lineno}#RESET# {message}", "%Y-%m-%d %H:%M:%S", "{") if quiet: stream_handler.addFilter(logging.Filter(name="user_facing")) logging.getLogger('user_facing').propagate = False logging.basicConfig(level=level, handlers=[stream_handler]) return logging.getLogger('user_facing')