544 Stimmen

Wie kann ich die Python-Logging-Ausgabe einfärben?

Vor einiger Zeit sah ich eine Mono-Anwendung mit farbiger Ausgabe, vermutlich aufgrund des Protokollsystems (da alle Meldungen standardisiert waren).

Jetzt hat Python die logging Modul, mit dem Sie eine Vielzahl von Optionen zur Anpassung der Ausgabe angeben können. Ich stelle mir vor, dass etwas Ähnliches auch mit Python möglich wäre, aber ich kann nirgendwo herausfinden, wie man das macht.

Gibt es eine Möglichkeit, die Python logging Modulausgabe in Farbe?

Ich möchte z. B. Fehler in rot, Fehlermeldungen in blau oder gelb usw.

Natürlich würde dies wahrscheinlich ein kompatibles Terminal erfordern (die meisten modernen Terminals sind kompatibel); aber ich könnte auf die ursprüngliche logging Ausgabe, wenn Farbe nicht unterstützt wird.

Haben Sie eine Idee, wie ich mit dem Logging-Modul eine farbige Ausgabe erhalten kann?

2voto

SebiSebi Punkte 285

FriendlyLog ist eine weitere Alternative. Es funktioniert mit Python 2 und 3 unter Linux, Windows und MacOS.

2voto

lesnik Punkte 2179

Die folgende Lösung funktioniert nur mit Python 3, aber für mich sieht sie am klarsten aus.

Die Idee ist, mit Hilfe der Log Record Factory "farbige" Attribute zu den Log Record Objekten hinzuzufügen und diese "farbigen" Attribute dann im Log Format zu verwenden.

import logging
logger = logging.getLogger(__name__)

def configure_logging(level):

    # add 'levelname_c' attribute to log resords
    orig_record_factory = logging.getLogRecordFactory()
    log_colors = {
        logging.DEBUG:     "\033[1;34m",  # blue
        logging.INFO:      "\033[1;32m",  # green
        logging.WARNING:   "\033[1;35m",  # magenta
        logging.ERROR:     "\033[1;31m",  # red
        logging.CRITICAL:  "\033[1;41m",  # red reverted
    }
    def record_factory(*args, **kwargs):
        record = orig_record_factory(*args, **kwargs)
        record.levelname_c = "{}{}{}".format(
            log_colors[record.levelno], record.levelname, "\033[0m")
        return record

    logging.setLogRecordFactory(record_factory)

    # now each log record object would contain 'levelname_c' attribute
    # and you can use this attribute when configuring logging using your favorite
    # method.
    # for demo purposes I configure stderr log right here

    formatter_c = logging.Formatter("[%(asctime)s] %(levelname_c)s:%(name)s:%(message)s")

    stderr_handler = logging.StreamHandler()
    stderr_handler.setLevel(level)
    stderr_handler.setFormatter(formatter_c)

    root_logger = logging.getLogger('')
    root_logger.setLevel(logging.DEBUG)
    root_logger.addHandler(stderr_handler)

def main():
    configure_logging(logging.DEBUG)

    logger.debug("debug message")
    logger.info("info message")
    logger.critical("something unusual happened")

if __name__ == '__main__':
    main()

Sie können dieses Beispiel leicht abändern, um andere farbige Attribute zu erstellen (z. B. message_c) und dann diese Attribute verwenden, um farbigen Text (nur) dort zu erhalten, wo Sie es wünschen.

(Ein praktischer Trick, den ich kürzlich entdeckt habe: Ich habe eine Datei mit farbigen Debug-Protokollen, und wann immer ich die Protokollstufe meiner Anwendung vorübergehend erhöhen möchte, muss ich nur tail -f die Protokolldatei in einem anderen Terminal und sehen Sie die Debug-Protokolle auf dem Bildschirm, ohne die Konfiguration zu ändern und die Anwendung neu zu starten)

1voto

saner99 Punkte 11

Jedem, der das gleiche Bedürfnis verspürt, empfehle ich mein eigenes Paket TCPrint . Es basiert auf Colorama (das plattformübergreifende Kompatibilität bietet), aber im Gegensatz dazu verwendet es vertraute <tags> zur Kennzeichnung von Textfarben und enthält Tags für die Protokollierung

Installation:

pip install ctprint

Färbung:

from ctprint inport ctp, ctdecode, cterr, ctlog

# print colored text
ctp('<bw> black text on white background /> default formating')

Fehlerbehandlung:

# print error message
try:
    1/0  # any broken line
except Exception as _ex:
    cterr(_ex)

Variablen protokollieren:

var0 = var1 = 0

# print varName-varValue pairs
def example_ctlog():

    var2 = 'string val'
    var3 = {'ctp_string': '<bg_red><red>red text on red background (NO) >'}

    # out of the function, var0=var2 - nothing problems.
    ctlog(var0=var0, var1=var1, var2=var2, var3=var3)

Und mehr:

ctp.help() # print help dialog with all supported tags and functions

Zusätzlich zu den Protokollierungsfunktionen und Farbmarkierungen gibt es <error> y <log> Quick-Tags für die Kennzeichnung von Benutzerausgaben

wenn Sie die Protokollierung beschleunigen und die Lesbarkeit im Terminal (vscode/pycharm/cmd/bash usw.) verbessern wollen, ohne die Befehlszeilenschnittstelle im Stil von , oder , anzupassen, wissen Sie, was zu tun ist. CTPrint wurde für das erste

Glück!

1voto

Akhil Punkte 773

Ein praktisches Bash-Skript mit tput-Farben

# Simple using tput
bold=$(tput bold)
reset=$(tput sgr0)

fblack=$(tput setaf 0)
fred=$(tput setaf 1)
fgreen=$(tput setaf 2)
fyellow=$(tput setaf 3)
fblue=$(tput setaf 4)
fmagenta=$(tput setaf 5)
fcyan=$(tput setaf 6)
fwhite=$(tput setaf 7)
fnotused=$(tput setaf 8)
freset=$(tput setaf 9)

bblack=$(tput setab 0)
bred=$(tput setab 1)
bgreen=$(tput setab 2)
byellow=$(tput setab 3)
bblue=$(tput setab 4)
bmagenta=$(tput setab 5)
bcyan=$(tput setab 6)
bwhite=$(tput setab 7)
bnotused=$(tput setab 8)
breset=$(tput setab 9)

# 0 - Emergency (emerg)       $fred       # something is wrong... go red
# 1 - Alerts (alert)          $fred       # something is wrong... go red
# 2 - Critical (crit)         $fred       # something is wrong... go red
# 3 - Errors (err)            $fred       # something is wrong... go red
# 4 - Warnings (warn)         $fyellow    # yellow yellow dirty logs
# 5 - Notification (notice)   $fwhite     # common stuff
# 6 - Information (info)      $fblue      # sky is blue
# 7 - Debug (debug)           $fgreen     # lot of stuff to read... go green

1voto

Joe Heffer Punkte 515

Dies ist eine Aufzählung, die die Farbcodes enthält:

class TerminalColour:
    """
    Terminal colour formatting codes
    """
    # https://stackoverflow.com/questions/287871/print-in-terminal-with-colors
    MAGENTA = '\033[95m'
    BLUE = '\033[94m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    GREY = '\033[0m'  # normal
    WHITE = '\033[1m'  # bright white
    UNDERLINE = '\033[4m'

Dies kann angewandt werden auf die Namen jeder Protokollstufe. Seien Sie sich darüber im Klaren, dass es sich um einen ungeheuerlichen Hack handelt.

logging.addLevelName(logging.INFO, "{}{}{}".format(TerminalColour.WHITE, logging.getLevelName(logging.INFO), TerminalColour.GREY))
logging.addLevelName(logging.WARNING, "{}{}{}".format(TerminalColour.YELLOW, logging.getLevelName(logging.WARNING), TerminalColour.GREY))
logging.addLevelName(logging.ERROR, "{}{}{}".format(TerminalColour.RED, logging.getLevelName(logging.ERROR), TerminalColour.GREY))
logging.addLevelName(logging.CRITICAL, "{}{}{}".format(TerminalColour.MAGENTA, logging.getLevelName(logging.CRITICAL), .GREY))

Beachten Sie, dass Ihr Protokollformatierer den Namen der Protokollebene enthalten muss

%(levelname)

zum Beispiel:

    LOGGING = {
...
        'verbose': {
            'format': '%(asctime)s %(levelname)s %(name)s:%(lineno)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '[%(asctime)s] %(levelname)s %(name)s %(message)s'
        },

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X