前段时间,我看到一个带彩色输出的Mono应用程序,可能是因为它的日志系统(因为所有的消息都是标准化的)。
现在,Python有logging
模块,它允许您指定许多选项来自定义输出。所以,我想象Python可能会有类似的东西,但我无法在任何地方找到如何做到这一点。
有没有办法让Python logging
模块输出颜色?
我想要的(例如)红色错误,蓝色或黄色调试消息等等。
当然这可能需要一个兼容的终端(大多数现代终端都是);但如果不支持颜色,我可以回退到原来的logging
输出。
我是如何通过日志记录模块获得彩色输出的?
答案 0 :(得分:167)
我已经知道了颜色逃逸,我刚才在我的bash提示中使用过它们。无论如何,谢谢 我想要的是将它与日志模块集成,我最终在经过几次尝试和错误之后做了这些模块 以下是我最终的结果:
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
#The background is set with 40 plus the number of the color, and the foreground with 30
#These are the sequences need to get colored ouput
RESET_SEQ = "\033[0m"
COLOR_SEQ = "\033[1;%dm"
BOLD_SEQ = "\033[1m"
def formatter_message(message, use_color = True):
if use_color:
message = message.replace("$RESET", RESET_SEQ).replace("$BOLD", BOLD_SEQ)
else:
message = message.replace("$RESET", "").replace("$BOLD", "")
return message
COLORS = {
'WARNING': YELLOW,
'INFO': WHITE,
'DEBUG': BLUE,
'CRITICAL': YELLOW,
'ERROR': RED
}
class ColoredFormatter(logging.Formatter):
def __init__(self, msg, use_color = True):
logging.Formatter.__init__(self, msg)
self.use_color = use_color
def format(self, record):
levelname = record.levelname
if self.use_color and levelname in COLORS:
levelname_color = COLOR_SEQ % (30 + COLORS[levelname]) + levelname + RESET_SEQ
record.levelname = levelname_color
return logging.Formatter.format(self, record)
要使用它,请创建自己的Logger:
# Custom logger class with multiple destinations
class ColoredLogger(logging.Logger):
FORMAT = "[$BOLD%(name)-20s$RESET][%(levelname)-18s] %(message)s ($BOLD%(filename)s$RESET:%(lineno)d)"
COLOR_FORMAT = formatter_message(FORMAT, True)
def __init__(self, name):
logging.Logger.__init__(self, name, logging.DEBUG)
color_formatter = ColoredFormatter(self.COLOR_FORMAT)
console = logging.StreamHandler()
console.setFormatter(color_formatter)
self.addHandler(console)
return
logging.setLoggerClass(ColoredLogger)
以防万一其他人需要它。
如果您使用多个记录器或处理程序,请小心:ColoredFormatter
正在更改记录对象,该记录对象将进一步传递给其他处理程序或传播到其他记录程序。如果您已配置文件记录器等,则可能不希望在日志文件中包含颜色。为避免这种情况,最好在操作levelname属性之前简单地创建record
copy.copy()
的副本,或者在返回格式化字符串之前将levelname重置为之前的值(信用额度为{{ 3}}在评论中。)
答案 1 :(得分:114)
多年前我写了一个彩色的流处理程序供我自己使用。然后我遇到了这个页面,发现了一些人们正在复制/粘贴的代码片段:-(。我的流处理程序目前只适用于UNIX(Linux,Mac OS X),但优点是它是available on PyPI(和GitHub)并且它很简单易用。它还有一个Vim语法模式:-)。将来我可以将它扩展到Windows上。
要安装软件包:
$ pip install coloredlogs
确认其有效:
$ coloredlogs --demo
开始使用自己的代码:
$ python
> import coloredlogs, logging
> coloredlogs.install()
> logging.info("It works!")
2014-07-30 21:21:26 peter-macbook root[7471] INFO It works!
上例中显示的默认日志格式包含日期,时间,主机名,记录器名称,PID,日志级别和日志消息。这就是它在实践中的样子:
答案 2 :(得分:68)
这是一个适用于任何平台的解决方案。如果它不只是告诉我,我会更新它。
工作原理:在支持ANSI转义的平台上使用它们(非Windows),在Windows上它确实使用API调用来更改控制台颜色。
该脚本会破坏标准库中的logging.StreamHandler.emit方法,为其添加包装器。
<强> TestColorer.py 强>
# Usage: add Colorer.py near you script and import it.
import logging
import Colorer
logging.warn("a warning")
logging.error("some error")
logging.info("some info")
<强> Colorer.py 强>
#!/usr/bin/env python
# encoding: utf-8
import logging
# now we patch Python code to add color support to logging.StreamHandler
def add_coloring_to_emit_windows(fn):
# add methods we need to the class
def _out_handle(self):
import ctypes
return ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
out_handle = property(_out_handle)
def _set_color(self, code):
import ctypes
# Constants from the Windows API
self.STD_OUTPUT_HANDLE = -11
hdl = ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
ctypes.windll.kernel32.SetConsoleTextAttribute(hdl, code)
setattr(logging.StreamHandler, '_set_color', _set_color)
def new(*args):
FOREGROUND_BLUE = 0x0001 # text color contains blue.
FOREGROUND_GREEN = 0x0002 # text color contains green.
FOREGROUND_RED = 0x0004 # text color contains red.
FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
FOREGROUND_WHITE = FOREGROUND_BLUE|FOREGROUND_GREEN |FOREGROUND_RED
# winbase.h
STD_INPUT_HANDLE = -10
STD_OUTPUT_HANDLE = -11
STD_ERROR_HANDLE = -12
# wincon.h
FOREGROUND_BLACK = 0x0000
FOREGROUND_BLUE = 0x0001
FOREGROUND_GREEN = 0x0002
FOREGROUND_CYAN = 0x0003
FOREGROUND_RED = 0x0004
FOREGROUND_MAGENTA = 0x0005
FOREGROUND_YELLOW = 0x0006
FOREGROUND_GREY = 0x0007
FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.
BACKGROUND_BLACK = 0x0000
BACKGROUND_BLUE = 0x0010
BACKGROUND_GREEN = 0x0020
BACKGROUND_CYAN = 0x0030
BACKGROUND_RED = 0x0040
BACKGROUND_MAGENTA = 0x0050
BACKGROUND_YELLOW = 0x0060
BACKGROUND_GREY = 0x0070
BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
levelno = args[1].levelno
if(levelno>=50):
color = BACKGROUND_YELLOW | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY
elif(levelno>=40):
color = FOREGROUND_RED | FOREGROUND_INTENSITY
elif(levelno>=30):
color = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
elif(levelno>=20):
color = FOREGROUND_GREEN
elif(levelno>=10):
color = FOREGROUND_MAGENTA
else:
color = FOREGROUND_WHITE
args[0]._set_color(color)
ret = fn(*args)
args[0]._set_color( FOREGROUND_WHITE )
#print "after"
return ret
return new
def add_coloring_to_emit_ansi(fn):
# add methods we need to the class
def new(*args):
levelno = args[1].levelno
if(levelno>=50):
color = '\x1b[31m' # red
elif(levelno>=40):
color = '\x1b[31m' # red
elif(levelno>=30):
color = '\x1b[33m' # yellow
elif(levelno>=20):
color = '\x1b[32m' # green
elif(levelno>=10):
color = '\x1b[35m' # pink
else:
color = '\x1b[0m' # normal
args[1].msg = color + args[1].msg + '\x1b[0m' # normal
#print "after"
return fn(*args)
return new
import platform
if platform.system()=='Windows':
# Windows does not support ANSI escapes and we are using API calls to set the console color
logging.StreamHandler.emit = add_coloring_to_emit_windows(logging.StreamHandler.emit)
else:
# all non-Windows platforms are supporting ANSI escapes so we use them
logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
#log = logging.getLogger()
#log.addFilter(log_filter())
#//hdlr = logging.StreamHandler()
#//hdlr.setFormatter(formatter())
答案 3 :(得分:61)
快速而脏的解决方案,用于预定义的日志级别,无需定义新类。
logging.addLevelName( logging.WARNING, "\033[1;31m%s\033[1;0m" % logging.getLevelName(logging.WARNING))
logging.addLevelName( logging.ERROR, "\033[1;41m%s\033[1;0m" % logging.getLevelName(logging.ERROR))
答案 4 :(得分:57)
更新:因为这是一个让我长时间搔痒的痒,所以我继续为像我这样只想简单方法做事的懒人写了一个库: zenlog
Colorlog非常适合这种情况。它是available on PyPI(因此可以通过pip install colorlog
安装)并且是actively maintained。
这是一个快速复制并粘贴的代码段,用于设置日志记录和打印体面的日志消息:
import logging
LOG_LEVEL = logging.DEBUG
LOGFORMAT = " %(log_color)s%(levelname)-8s%(reset)s | %(log_color)s%(message)s%(reset)s"
from colorlog import ColoredFormatter
logging.root.setLevel(LOG_LEVEL)
formatter = ColoredFormatter(LOGFORMAT)
stream = logging.StreamHandler()
stream.setLevel(LOG_LEVEL)
stream.setFormatter(formatter)
log = logging.getLogger('pythonConfig')
log.setLevel(LOG_LEVEL)
log.addHandler(stream)
log.debug("A quirky message only developers care about")
log.info("Curious users might want to know this")
log.warn("Something is wrong and any user should be informed")
log.error("Serious stuff, this is red for a reason")
log.critical("OH NO everything is on fire")
输出:
答案 5 :(得分:14)
我更新了airmind支持前景和背景标签的示例。 只需在日志格式化程序字符串中使用颜色变量$ BLACK - $ WHITE即可。要设置背景,只需使用$ BG-BLACK - $ BG-WHITE。
import logging
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
COLORS = {
'WARNING' : YELLOW,
'INFO' : WHITE,
'DEBUG' : BLUE,
'CRITICAL' : YELLOW,
'ERROR' : RED,
'RED' : RED,
'GREEN' : GREEN,
'YELLOW' : YELLOW,
'BLUE' : BLUE,
'MAGENTA' : MAGENTA,
'CYAN' : CYAN,
'WHITE' : WHITE,
}
RESET_SEQ = "\033[0m"
COLOR_SEQ = "\033[1;%dm"
BOLD_SEQ = "\033[1m"
class ColorFormatter(logging.Formatter):
def __init__(self, *args, **kwargs):
# can't do super(...) here because Formatter is an old school class
logging.Formatter.__init__(self, *args, **kwargs)
def format(self, record):
levelname = record.levelname
color = COLOR_SEQ % (30 + COLORS[levelname])
message = logging.Formatter.format(self, record)
message = message.replace("$RESET", RESET_SEQ)\
.replace("$BOLD", BOLD_SEQ)\
.replace("$COLOR", color)
for k,v in COLORS.items():
message = message.replace("$" + k, COLOR_SEQ % (v+30))\
.replace("$BG" + k, COLOR_SEQ % (v+40))\
.replace("$BG-" + k, COLOR_SEQ % (v+40))
return message + RESET_SEQ
logging.ColorFormatter = ColorFormatter
现在您可以在配置文件中执行以下操作:
[formatter_colorFormatter]
class=logging.ColorFormatter
format= $COLOR%(levelname)s $RESET %(asctime)s $BOLD$COLOR%(name)s$RESET %(message)s
答案 6 :(得分:14)
您可以导入colorlog模块并使用其ColoredFormatter
来着色日志消息。
主模块的锅炉板:
import logging
import os
import sys
try:
import colorlog
except ImportError:
pass
def setup_logging():
root = logging.getLogger()
root.setLevel(logging.DEBUG)
format = '%(asctime)s - %(levelname)-8s - %(message)s'
date_format = '%Y-%m-%d %H:%M:%S'
if 'colorlog' in sys.modules and os.isatty(2):
cformat = '%(log_color)s' + format
f = colorlog.ColoredFormatter(cformat, date_format,
log_colors = { 'DEBUG' : 'reset', 'INFO' : 'reset',
'WARNING' : 'bold_yellow', 'ERROR': 'bold_red',
'CRITICAL': 'bold_red' })
else:
f = logging.Formatter(format, date_format)
ch = logging.StreamHandler()
ch.setFormatter(f)
root.addHandler(ch)
setup_logging()
log = logging.getLogger(__name__)
如果安装了colorlog模块并且输出实际上发送到终端,则代码仅启用日志消息中的颜色。这样可以避免在重定向日志输出时将转义序列写入文件。
此外,还设置了自定义配色方案,更适合背景较暗的终端。
一些示例日志记录调用:
log.debug ('Hello Debug')
log.info ('Hello Info')
log.warn ('Hello Warn')
log.error ('Hello Error')
log.critical('Hello Critical')
输出:
答案 7 :(得分:12)
嗯,我想我也可以添加我的彩色记录器的变体。
这没什么特别之处,但它使用起来非常简单,并且不会更改记录对象,从而避免在使用文件处理程序时将ANSI转义序列记录到日志文件中。它不会影响日志消息格式。
如果您已经在使用logging module's Formatter,那么要获得彩色级别名称,您只需要使用ColoredFormatter替换您的律师处理程序Formatter。如果您要记录整个应用程序,则只需要为顶级记录器执行此操作。
<强> colored_log.py 强>
#!/usr/bin/env python
from copy import copy
from logging import Formatter
MAPPING = {
'DEBUG' : 37, # white
'INFO' : 36, # cyan
'WARNING' : 33, # yellow
'ERROR' : 31, # red
'CRITICAL': 41, # white on red bg
}
PREFIX = '\033['
SUFFIX = '\033[0m'
class ColoredFormatter(Formatter):
def __init__(self, patern):
Formatter.__init__(self, patern)
def format(self, record):
colored_record = copy(record)
levelname = colored_record.levelname
seq = MAPPING.get(levelname, 37) # default white
colored_levelname = ('{0}{1}m{2}{3}') \
.format(PREFIX, seq, levelname, SUFFIX)
colored_record.levelname = colored_levelname
return Formatter.format(self, colored_record)
<强> app.py 强>
#!/usr/bin/env python
import logging
from colored_log import ColoredFormatter
# Create top level logger
log = logging.getLogger("main")
# Add console handler using our custom ColoredFormatter
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
cf = ColoredFormatter("[%(name)s][%(levelname)s] %(message)s (%(filename)s:%(lineno)d)")
ch.setFormatter(cf)
log.addHandler(ch)
# Add file handler
fh = logging.FileHandler('app.log')
fh.setLevel(logging.DEBUG)
ff = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(ff)
log.addHandler(fh)
# Set log level
log.setLevel(logging.DEBUG)
# Log some stuff
log.debug("app has started")
log.info("Logging to 'app.log' in the script dir")
log.warning("This is my last warning, take heed")
log.error("This is an error")
log.critical("He's dead, Jim")
# Import a sub-module
import sub_module
<强> sub_module.py 强>
#!/usr/bin/env python
import logging
log = logging.getLogger('main.sub_module')
log.debug("Hello from the sub module")
终端输出
app.log 内容
2017-09-29 00:32:23,434 - main - DEBUG - app has started
2017-09-29 00:32:23,434 - main - INFO - Logging to 'app.log' in the script dir
2017-09-29 00:32:23,435 - main - WARNING - This is my last warning, take heed
2017-09-29 00:32:23,435 - main - ERROR - This is an error
2017-09-29 00:32:23,435 - main - CRITICAL - He's dead, Jim
2017-09-29 00:32:23,435 - main.sub_module - DEBUG - Hello from the sub module
当然,您可以根据需要设置格式化终端和日志文件输出。只有日志级别才会着色。
我希望有人觉得这很有用,而且不仅仅是太多了。 :)
可以从这个GitHub Gist下载Python示例文件: https://gist.github.com/KurtJacobson/48e750701acec40c7161b5a2f79e6bfd
答案 8 :(得分:10)
我将Sorin提供的原始示例和子类化的StreamHandler修改为ColorizedConsoleHandler。
他们的解决方案的缺点是它修改了消息,因为这正在修改实际的logmessage,任何其他处理程序也将获得修改后的消息。
由于我们使用多个记录器,因此在我们的案例中产生了带有颜色代码的日志文件。
下面的课程仅适用于支持ansi的平台,但将窗口颜色代码添加到平台上应该是微不足道的。
import copy
import logging
class ColoredConsoleHandler(logging.StreamHandler):
def emit(self, record):
# Need to make a actual copy of the record
# to prevent altering the message for other loggers
myrecord = copy.copy(record)
levelno = myrecord.levelno
if(levelno >= 50): # CRITICAL / FATAL
color = '\x1b[31m' # red
elif(levelno >= 40): # ERROR
color = '\x1b[31m' # red
elif(levelno >= 30): # WARNING
color = '\x1b[33m' # yellow
elif(levelno >= 20): # INFO
color = '\x1b[32m' # green
elif(levelno >= 10): # DEBUG
color = '\x1b[35m' # pink
else: # NOTSET and anything else
color = '\x1b[0m' # normal
myrecord.msg = color + str(myrecord.msg) + '\x1b[0m' # normal
logging.StreamHandler.emit(self, myrecord)
答案 9 :(得分:10)
请看以下解决方案。流处理程序应该是着色的东西,然后你可以选择着色单词而不是整行(使用Formatter)。
http://plumberjack.blogspot.com/2010/12/colorizing-logging-output-in-terminals.html
答案 10 :(得分:9)
现在有一个已发布的PyPi模块可用于自定义彩色日志输出:
https://pypi.python.org/pypi/rainbow_logging_handler/
和
https://github.com/laysakura/rainbow_logging_handler
支持Windows
支持Django
可自定义颜色
由于它是作为Python egg分发的,因此很容易为任何Python应用程序安装。
答案 11 :(得分:7)
有很多回复。但没有人在谈论装饰者。所以这是我的。
因为它更简单。
无需导入任何内容,也无需编写任何子类:
#!/bin/sh
trap : SIGINT
echo begin
for((i=0;i<10;i++)); do printf "$i\r"; sleep 1; done &
wait || kill $!
echo
echo end
这将错误设置为红色,将调试消息设置为蓝色,等等。就像在问题中提到的那样。
我们甚至可以调整包装器以使用#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
NO_COLOR = "\33[m"
RED, GREEN, ORANGE, BLUE, PURPLE, LBLUE, GREY = \
map("\33[%dm".__mod__, range(31, 38))
logging.basicConfig(format="%(message)s", level=logging.DEBUG)
logger = logging.getLogger(__name__)
# the decorator to apply on the logger methods info, warn, ...
def add_color(logger_method, color):
def wrapper(message, *args, **kwargs):
return logger_method(
# the coloring is applied here.
color+message+NO_COLOR,
*args, **kwargs
)
return wrapper
for level, color in zip((
"info", "warn", "error", "debug"), (
GREEN, ORANGE, RED, BLUE
)):
setattr(logger, level, add_color(getattr(logger, level), color))
# this is displayed in red.
logger.error("Launching %s." % __file__)
参数动态设置消息的颜色color
编辑: 所以这里是改编的装饰器在运行时设置颜色:
logger.debug("message", color=GREY)
答案 12 :(得分:6)
airmind的另一种小混音方法,将所有内容保持在一个类别中:
class ColorFormatter(logging.Formatter):
FORMAT = ("[$BOLD%(name)-20s$RESET][%(levelname)-18s] "
"%(message)s "
"($BOLD%(filename)s$RESET:%(lineno)d)")
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
RESET_SEQ = "\033[0m"
COLOR_SEQ = "\033[1;%dm"
BOLD_SEQ = "\033[1m"
COLORS = {
'WARNING': YELLOW,
'INFO': WHITE,
'DEBUG': BLUE,
'CRITICAL': YELLOW,
'ERROR': RED
}
def formatter_msg(self, msg, use_color = True):
if use_color:
msg = msg.replace("$RESET", self.RESET_SEQ).replace("$BOLD", self.BOLD_SEQ)
else:
msg = msg.replace("$RESET", "").replace("$BOLD", "")
return msg
def __init__(self, use_color=True):
msg = self.formatter_msg(self.FORMAT, use_color)
logging.Formatter.__init__(self, msg)
self.use_color = use_color
def format(self, record):
levelname = record.levelname
if self.use_color and levelname in self.COLORS:
fore_color = 30 + self.COLORS[levelname]
levelname_color = self.COLOR_SEQ % fore_color + levelname + self.RESET_SEQ
record.levelname = levelname_color
return logging.Formatter.format(self, record)
使用将格式化程序附加到处理程序,例如:
handler.setFormatter(ColorFormatter())
logger.addHandler(handler)
答案 13 :(得分:5)
一种简单但非常灵活的着色工具,可用于着色任何终端文字&#39; colout&#39;。
pip install colout
myprocess | colout REGEX_WITH_GROUPS color1,color2...
输出&#39; myprocess&#39;中的任何文字。匹配正则表达式的组1将用color1着色,组2用color2等着色
例如:
tail -f /var/log/mylogfile | colout '^(\w+ \d+ [\d:]+)|(\w+\.py:\d+ .+\(\)): (.+)$' white,black,cyan bold,bold,normal
即。第一个正则表达式组(parens)匹配日志文件中的初始日期,第二个组匹配python文件名,行号和函数名称,第三个组匹配之后的日志消息。我还使用并行序列的&#39;粗体/法线&#39;以及颜色的顺序。这看起来像:
请注意,与我的任何正则表达式不匹配的行或部分行仍然会回显,所以这并不像grep --color&#39; - 没有任何东西从输出中滤除。
显然,这足够灵活,您可以将它用于任何进程,而不仅仅是拖尾日志文件。我通常只是在想要给某些东西上色的时候动态地制作一个新的正则表达式。出于这个原因,我更喜欢colout到任何自定义日志文件着色工具,因为我只需要学习一个工具,无论我的着色是什么:日志记录,测试输出,语法突出显示终端中的代码片段等。
它还避免在日志文件本身中实际转储ANSI代码,这是一个坏主意,因为它会破坏日志文件中的模式,除非你总是记得匹配grep正则表达式中的ANSI代码。
答案 14 :(得分:5)
import logging
import sys
colors = {'pink': '\033[95m', 'blue': '\033[94m', 'green': '\033[92m', 'yellow': '\033[93m', 'red': '\033[91m',
'ENDC': '\033[0m', 'bold': '\033[1m', 'underline': '\033[4m'}
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
def str_color(color, data):
return colors[color] + str(data) + colors['ENDC']
params = {'param1': id1, 'param2': id2}
logging.info('\nParams:' + str_color("blue", str(params)))`
答案 15 :(得分:4)
除了按级别着色外,高亮显示日志消息参数时还应使用交替的颜色吗?我最近为此编写了简单的代码。另一个优点是,日志调用是使用Python 3大括号样式的格式进行的。 ("{}"
)。
在此处查看最新的代码和示例:https://github.com/davidohana/colargulog
示例记录代码:
root_logger = logging.getLogger()
console_handler = logging.StreamHandler(stream=sys.stdout)
console_format = "%(asctime)s - %(levelname)-8s - %(name)-25s - %(message)s"
colored_formatter = ColorizedArgsFormatter(console_format)
console_handler.setFormatter(colored_formatter)
root_logger.addHandler(console_handler)
logger = logging.getLogger(__name__)
logger.info("Hello World")
logger.info("Request from {} handled in {:.3f} ms", socket.gethostname(), 11)
logger.info("Request from {} handled in {:.3f} ms", "127.0.0.1", 33.1)
logger.info("My favorite drinks are {}, {}, {}, {}", "milk", "wine", "tea", "beer")
logger.debug("this is a {} message", logging.getLevelName(logging.DEBUG))
logger.info("this is a {} message", logging.getLevelName(logging.INFO))
logger.warning("this is a {} message", logging.getLevelName(logging.WARNING))
logger.error("this is a {} message", logging.getLevelName(logging.ERROR))
logger.critical("this is a {} message", logging.getLevelName(logging.CRITICAL))
logger.info("Does old-style formatting also work? %s it is, but no colors (yet)", True)
输出:
实施:
"""
colargulog - Python3 Logging with Colored Arguments and new string formatting style
Written by david.ohana@ibm.com
License: Apache-2.0
"""
import logging
import logging.handlers
import re
class ColorCodes:
grey = "\x1b[38;21m"
green = "\x1b[1;32m"
yellow = "\x1b[33;21m"
red = "\x1b[31;21m"
bold_red = "\x1b[31;1m"
blue = "\x1b[1;34m"
light_blue = "\x1b[1;36m"
purple = "\x1b[1;35m"
reset = "\x1b[0m"
class ColorizedArgsFormatter(logging.Formatter):
arg_colors = [ColorCodes.purple, ColorCodes.light_blue]
level_fields = ["levelname", "levelno"]
level_to_color = {
logging.DEBUG: ColorCodes.grey,
logging.INFO: ColorCodes.green,
logging.WARNING: ColorCodes.yellow,
logging.ERROR: ColorCodes.red,
logging.CRITICAL: ColorCodes.bold_red,
}
def __init__(self, fmt: str):
super().__init__()
self.level_to_formatter = {}
def add_color_format(level: int):
color = ColorizedArgsFormatter.level_to_color[level]
_format = fmt
for fld in ColorizedArgsFormatter.level_fields:
search = "(%\(" + fld + "\).*?s)"
_format = re.sub(search, f"{color}\\1{ColorCodes.reset}", _format)
formatter = logging.Formatter(_format)
self.level_to_formatter[level] = formatter
add_color_format(logging.DEBUG)
add_color_format(logging.INFO)
add_color_format(logging.WARNING)
add_color_format(logging.ERROR)
add_color_format(logging.CRITICAL)
@staticmethod
def rewrite_record(record: logging.LogRecord):
if not BraceFormatStyleFormatter.is_brace_format_style(record):
return
msg = record.msg
msg = msg.replace("{", "_{{")
msg = msg.replace("}", "_}}")
placeholder_count = 0
# add ANSI escape code for next alternating color before each formatting parameter
# and reset color after it.
while True:
if "_{{" not in msg:
break
color_index = placeholder_count % len(ColorizedArgsFormatter.arg_colors)
color = ColorizedArgsFormatter.arg_colors[color_index]
msg = msg.replace("_{{", color + "{", 1)
msg = msg.replace("_}}", "}" + ColorCodes.reset, 1)
placeholder_count += 1
record.msg = msg.format(*record.args)
record.args = []
def format(self, record):
orig_msg = record.msg
orig_args = record.args
formatter = self.level_to_formatter.get(record.levelno)
self.rewrite_record(record)
formatted = formatter.format(record)
# restore log record to original state for other handlers
record.msg = orig_msg
record.args = orig_args
return formatted
class BraceFormatStyleFormatter(logging.Formatter):
def __init__(self, fmt: str):
super().__init__()
self.formatter = logging.Formatter(fmt)
@staticmethod
def is_brace_format_style(record: logging.LogRecord):
if len(record.args) == 0:
return False
msg = record.msg
if '%' in msg:
return False
count_of_start_param = msg.count("{")
count_of_end_param = msg.count("}")
if count_of_start_param != count_of_end_param:
return False
if count_of_start_param != len(record.args):
return False
return True
@staticmethod
def rewrite_record(record: logging.LogRecord):
if not BraceFormatStyleFormatter.is_brace_format_style(record):
return
record.msg = record.msg.format(*record.args)
record.args = []
def format(self, record):
orig_msg = record.msg
orig_args = record.args
self.rewrite_record(record)
formatted = self.formatter.format(record)
# restore log record to original state for other handlers
record.msg = orig_msg
record.args = orig_args
return formatted
答案 16 :(得分:2)
这是我的解决方案:
class ColouredFormatter(logging.Formatter):
RESET = '\x1B[0m'
RED = '\x1B[31m'
YELLOW = '\x1B[33m'
BRGREEN = '\x1B[01;32m' # grey in solarized for terminals
def format(self, record, colour=False):
message = super().format(record)
if not colour:
return message
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.RESET
elif level_no >= logging.DEBUG:
colour = self.BRGREEN
else:
colour = self.RESET
message = colour + message + self.RESET
return message
class ColouredHandler(logging.StreamHandler):
def __init__(self, stream=sys.stdout):
super().__init__(stream)
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()
except Exception:
self.handleError(record)
h = ColouredHandler()
h.formatter = ColouredFormatter('{asctime} {levelname:8} {message}', '%Y-%m-%d %H:%M:%S', '{')
logging.basicConfig(level=logging.DEBUG, handlers=[h])
答案 17 :(得分:2)
这是airmind示例的另一个Python3变体。我想要一些其他示例中没有的特定功能
注意:我使用了colorama,但是您可以修改它,因此不是必需的。同样,在我的测试中,我只是运行python文件,因此我的类位于模块__main__
中,您必须将(): __main__.ColoredFormatter
更改为模块所在的任何位置。
pip install colorama pyyaml
logging.yaml
---
version: 1
disable_existing_loggers: False
formatters:
simple:
format: "%(threadName)s - %(name)s - %(levelname)s - %(message)s"
color:
format: "%(threadName)s - %(name)s - %(levelname)s - %(message)s"
(): __main__.ColoredFormatter
use_color: true
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: color
stream: ext://sys.stdout
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: simple
filename: app.log
maxBytes: 20971520
backupCount: 20
encoding: utf8
error_file_handler:
class: logging.handlers.RotatingFileHandler
level: ERROR
formatter: simple
filename: errors.log
maxBytes: 10485760
backupCount: 20
encoding: utf8
root:
level: DEBUG
handlers: [console, info_file_handler, error_file_handler]
main.py
import logging
import logging.config
import os
from logging import Logger
import colorama
import yaml
from colorama import Back, Fore, Style
COLORS = {
"WARNING": Fore.YELLOW,
"INFO": Fore.CYAN,
"DEBUG": Fore.BLUE,
"CRITICAL": Fore.YELLOW,
"ERROR": Fore.RED,
}
class ColoredFormatter(logging.Formatter):
def __init__(self, *, format, use_color):
logging.Formatter.__init__(self, fmt=format)
self.use_color = use_color
def format(self, record):
msg = super().format(record)
if self.use_color:
levelname = record.levelname
if hasattr(record, "color"):
return f"{record.color}{msg}{Style.RESET_ALL}"
if levelname in COLORS:
return f"{COLORS[levelname]}{msg}{Style.RESET_ALL}"
return msg
with open("logging.yaml", "rt") as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
logger: Logger = logging.getLogger(__name__)
logger.info("Test INFO", extra={"color": Back.RED})
logger.info("Test INFO", extra={"color": f"{Style.BRIGHT}{Back.RED}"})
logger.info("Test INFO")
logger.debug("Test DEBUG")
logger.warning("Test WARN")
输出:
答案 18 :(得分:1)
虽然其他解决方案似乎很好,但它们存在一些问题。有些人会对整行进行着色,有些时候不需要,有些则省略了你们可能拥有的任何配置。下面的解决方案不会影响除消息本身以外的任何内容。
<强>代码强>
class ColoredFormatter(logging.Formatter):
def format(self, record):
if record.levelno == logging.WARNING:
record.msg = '\033[93m%s\033[0m' % record.msg
elif record.levelno == logging.ERROR:
record.msg = '\033[91m%s\033[0m' % record.msg
return logging.Formatter.format(self, record)
示例强>
logger = logging.getLogger('mylogger')
handler = logging.StreamHandler()
log_format = '[%(asctime)s]:%(levelname)-7s:%(message)s'
time_format = '%H:%M:%S'
formatter = ColoredFormatter(log_format, datefmt=time_format)
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.warn('this should be yellow')
logger.error('this should be red')
<强>输出强>
[17:01:36]:WARNING:this should be yellow
[17:01:37]:ERROR :this should be red
如您所见,其他所有内容仍然会输出并保持其初始颜色。如果您想要更改除消息之外的任何内容,您只需将颜色代码传递给示例中的log_format
。
答案 19 :(得分:1)
我有两个要添加的提交,其中一个只为消息着色(ColoredFormatter),其中一个为整行着色(ColorizingStreamHandler)。这些还包括比以前的解决方案更多的ANSI色码。
某些内容来自(经过修改)来自: 上面的帖子和http://plumberjack.blogspot.com/2010/12/colorizing-logging-output-in-terminals.html。
仅对消息着色:
class ColoredFormatter(logging.Formatter):
"""Special custom formatter for colorizing log messages!"""
BLACK = '\033[0;30m'
RED = '\033[0;31m'
GREEN = '\033[0;32m'
BROWN = '\033[0;33m'
BLUE = '\033[0;34m'
PURPLE = '\033[0;35m'
CYAN = '\033[0;36m'
GREY = '\033[0;37m'
DARK_GREY = '\033[1;30m'
LIGHT_RED = '\033[1;31m'
LIGHT_GREEN = '\033[1;32m'
YELLOW = '\033[1;33m'
LIGHT_BLUE = '\033[1;34m'
LIGHT_PURPLE = '\033[1;35m'
LIGHT_CYAN = '\033[1;36m'
WHITE = '\033[1;37m'
RESET = "\033[0m"
def __init__(self, *args, **kwargs):
self._colors = {logging.DEBUG: self.DARK_GREY,
logging.INFO: self.RESET,
logging.WARNING: self.BROWN,
logging.ERROR: self.RED,
logging.CRITICAL: self.LIGHT_RED}
super(ColoredFormatter, self).__init__(*args, **kwargs)
def format(self, record):
"""Applies the color formats"""
record.msg = self._colors[record.levelno] + record.msg + self.RESET
return logging.Formatter.format(self, record)
def setLevelColor(self, logging_level, escaped_ansi_code):
self._colors[logging_level] = escaped_ansi_code
将整行着色:
class ColorizingStreamHandler(logging.StreamHandler):
BLACK = '\033[0;30m'
RED = '\033[0;31m'
GREEN = '\033[0;32m'
BROWN = '\033[0;33m'
BLUE = '\033[0;34m'
PURPLE = '\033[0;35m'
CYAN = '\033[0;36m'
GREY = '\033[0;37m'
DARK_GREY = '\033[1;30m'
LIGHT_RED = '\033[1;31m'
LIGHT_GREEN = '\033[1;32m'
YELLOW = '\033[1;33m'
LIGHT_BLUE = '\033[1;34m'
LIGHT_PURPLE = '\033[1;35m'
LIGHT_CYAN = '\033[1;36m'
WHITE = '\033[1;37m'
RESET = "\033[0m"
def __init__(self, *args, **kwargs):
self._colors = {logging.DEBUG: self.DARK_GREY,
logging.INFO: self.RESET,
logging.WARNING: self.BROWN,
logging.ERROR: self.RED,
logging.CRITICAL: self.LIGHT_RED}
super(ColorizingStreamHandler, self).__init__(*args, **kwargs)
@property
def is_tty(self):
isatty = getattr(self.stream, 'isatty', None)
return isatty and isatty()
def emit(self, record):
try:
message = self.format(record)
stream = self.stream
if not self.is_tty:
stream.write(message)
else:
message = self._colors[record.levelno] + message + self.RESET
stream.write(message)
stream.write(getattr(self, 'terminator', '\n'))
self.flush()
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
def setLevelColor(self, logging_level, escaped_ansi_code):
self._colors[logging_level] = escaped_ansi_code
答案 20 :(得分:1)
您可以使用其他人在回答中提到的颜色作为文本颜色,以获得带有背景或前景色的彩色文本。
但是您可以改用表情符号!例如,您可以使用 ⚠️
表示警告消息,使用 ?
表示错误消息。
或者简单地将这些笔记本用作颜色:
print("?: error message")
print("?: warning message")
print("?: ok status message")
print("?: action message")
print("?: canceled status message")
print("?: Or anything you like and want to recognize immediately by color")
此方法还可以帮助您直接在源代码中快速扫描和查找日志。
mac os: 控制 + 命令 + 空格
windows: win + .
linux: control + . 或 control + ;
答案 21 :(得分:1)
我遇到麻烦的是正确设置格式化程序:
class ColouredFormatter(logging.Formatter):
def __init__(self, msg):
logging.Formatter.__init__(self, msg)
self._init_colour = _get_colour()
def close(self):
# restore the colour information to what it was
_set_colour(self._init_colour)
def format(self, record):
# Add your own colourer based on the other examples
_set_colour( LOG_LEVEL_COLOUR[record.levelno] )
return logging.Formatter.format(self, record)
def init():
# Set up the formatter. Needs to be first thing done.
rootLogger = logging.getLogger()
hdlr = logging.StreamHandler()
fmt = ColouredFormatter('%(message)s')
hdlr.setFormatter(fmt)
rootLogger.addHandler(hdlr)
然后使用:
import coloured_log
import logging
coloured_log.init()
logging.info("info")
logging.debug("debug")
coloured_log.close() # restore colours
答案 22 :(得分:1)
这是一个包含颜色代码的枚举:
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'
这可能适用于每个日志级别的名称。 请注意,这是一次骇人听闻的黑客行为。
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))
请注意,您的日志格式化程序必须包含日志级别的名称
%(levelname)
例如:
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'
},
答案 23 :(得分:1)
FriendlyLog是另一种选择。它可以在Linux,Windows和MacOS下与Python 2和3配合使用。
答案 24 :(得分:1)
以下解决方案仅适用于python 3,但对我来说,它看起来最清楚。
这个想法是使用日志记录工厂为日志记录对象添加“彩色”属性,然后以日志格式使用这些“彩色”属性。
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()
您可以轻松地修改此示例以创建其他彩色属性(例如message_c),然后使用这些属性在需要的位置(仅)获取彩色文本。
(最近发现的实用技巧:我有一个带有彩色调试日志的文件,每当我要临时增加应用程序的日志级别时,我只是tail -f
在不同终端中的日志文件,并在屏幕w上看到调试日志/ o更改任何配置并重新启动应用程序)
答案 25 :(得分:0)
pip install coloredlogs
import logging
import coloredlogs
coloredlogs.install() # install a handler on the root logger
logging.debug('message with level debug')
logging.info('message with level info')
logging.warning('message with level warning')
logging.error('message with level error')
logging.critical('message with level critical')
import logging
import coloredlogs
coloredlogs.install(level='DEBUG') # install a handler on the root logger with level debug
logging.debug('message with level debug')
logging.info('message with level info')
logging.warning('message with level warning')
logging.error('message with level error')
logging.critical('message with level critical')
import logging
import coloredlogs
logger = logging.getLogger(__name__) # get a specific logger object
coloredlogs.install(level='DEBUG') # install a handler on the root logger with level debug
coloredlogs.install(level='DEBUG', logger=logger) # pass a specific logger object
logging.debug('message with level debug')
logging.info('message with level info')
logging.warning('message with level warning')
logging.error('message with level error')
logging.critical('message with level critical')
import logging
import coloredlogs
logger = logging.getLogger(__name__) # get a specific logger object
coloredlogs.install(level='DEBUG') # install a handler on the root logger with level debug
coloredlogs.install(level='DEBUG', logger=logger) # pass a specific logger object
coloredlogs.install(
level='DEBUG', logger=logger,
fmt='%(asctime)s.%(msecs)03d %(filename)s:%(lineno)d %(levelname)s %(message)s'
)
logging.debug('message with level debug')
logging.info('message with level info')
logging.warning('message with level warning')
logging.error('message with level error')
logging.critical('message with level critical')
%(asctime)s
- 发出日志调用时作为人类可读字符串的时间%(created)f
- 发出日志调用时的浮动时间%(filename)s
- 文件名%(funcName)s
- 包含日志调用的函数名称%(hostname)s
- 系统主机名%(levelname)s
- 文本记录级别%(levelno)s
- 整数日志级别%(lineno)d
- 发出日志调用的行号%(message)s
- 传递给日志调用的消息(与 %(msg)s
相同)%(module)s
- 发出日志调用的不带扩展名的文件名%(msecs)d
- 发出日志记录调用时间的毫秒部分%(msg)s
- 传递给日志调用的消息(与 %(message)s
相同)%(name)s
- 记录器名称%(pathname)s
- 包含日志调用的文件的完整路径名%(process)d
- 进程 ID%(processName)s
- 进程名称%(programname)s
- 系统程序名%(relativeCreated)d
- 发出日志记录调用时的整数时间,相对于加载日志记录模块的时间%(thread)d
- 线程 ID%(threadName)s
- 线程名称%(username)s
- 系统用户名答案 26 :(得分:0)
安装colorlog软件包,您可以立即在日志消息中使用颜色:
logger
实例。DEBUG
之类的常量
和INFO
直接从日志记录模块中获取。ColoredFormatter
由colorlog
库提供。import colorlog
logger = colorlog.getLogger()
logger.setLevel(colorlog.colorlog.logging.DEBUG)
handler = colorlog.StreamHandler()
handler.setFormatter(colorlog.ColoredFormatter())
logger.addHandler(handler)
logger.debug("Debug message")
logger.info("Information message")
logger.warning("Warning message")
logger.error("Error message")
logger.critical("Critical message")
输出: https://timber.io/blog/multiprocessing-vs-multithreading-in-python-what-you-need-to-know/
只需更新ColoredFormatter
:
handler.setFormatter(colorlog.ColoredFormatter('%(log_color)s [%(asctime)s] %(levelname)s [%(filename)s.%(funcName)s:%(lineno)d] %(message)s', datefmt='%a, %d %b %Y %H:%M:%S'))
包装:
pip install colorlog
输出:
Collecting colorlog
Downloading colorlog-4.6.2-py2.py3-none-any.whl (10.0 kB)
Installing collected packages: colorlog
Successfully installed colorlog-4.6.2
答案 27 :(得分:0)
带有tput颜色的便捷bash脚本
# 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
答案 28 :(得分:0)
定义班级
import logging
class CustomFormatter(logging.Formatter):
"""Logging Formatter to add colors and count warning / errors"""
grey = "\x1b[38;21m"
yellow = "\x1b[33;21m"
red = "\x1b[31;21m"
bold_red = "\x1b[31;1m"
reset = "\x1b[0m"
format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)"
FORMATS = {
logging.DEBUG: grey + format + reset,
logging.INFO: grey + format + reset,
logging.WARNING: yellow + format + reset,
logging.ERROR: red + format + reset,
logging.CRITICAL: bold_red + format + reset
}
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
formatter = logging.Formatter(log_fmt)
return formatter.format(record)
实例化记录器
# create logger with 'spam_application'
logger = logging.getLogger("My_app")
logger.setLevel(logging.DEBUG)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(CustomFormatter())
logger.addHandler(ch)
并使用!
logger.debug("debug message")
logger.info("info message")
logger.warning("warning message")
logger.error("error message")
logger.critical("critical message")
答案 29 :(得分:0)
答案 30 :(得分:0)
另一种解决方案,使用ZetaSyanthis的颜色:
def config_log(log_level):
def set_color(level, code):
level_fmt = "\033[1;" + str(code) + "m%s\033[1;0m"
logging.addLevelName( level, level_fmt % logging.getLevelName(level) )
std_stream = sys.stdout
isatty = getattr(std_stream, 'isatty', None)
if isatty and isatty():
levels = [logging.DEBUG, logging.CRITICAL, logging.WARNING, logging.ERROR]
for idx, level in enumerate(levels):
set_color(level, 30 + idx )
set_color(logging.DEBUG, 0)
logging.basicConfig(stream=std_stream, level=log_level)
从__main__
函数调用一次。我有类似的东西:
options, arguments = p.parse_args()
log_level = logging.DEBUG if options.verbose else logging.WARNING
config_log(log_level)
它还验证输出是控制台,否则不使用颜色。
答案 31 :(得分:0)
import logging
logging.basicConfig(filename="f.log" filemode='w', level=logging.INFO,
format = "%(logger_name)s %(color)s %(message)s %(endColor)s")
class Logger(object):
__GREEN = "\033[92m"
__RED = '\033[91m'
__ENDC = '\033[0m'
def __init__(self, name):
self.logger = logging.getLogger(name)
self.extra={'logger_name': name, 'endColor': self.__ENDC, 'color': self.__GREEN}
def info(self, msg):
self.extra['color'] = self.__GREEN
self.logger.info(msg, extra=self.extra)
def error(self, msg):
self.extra['color'] = self.__RED
self.logger.error(msg, extra=self.extra)
Logger("File Name").info("This shows green text")
答案 32 :(得分:0)
答案 33 :(得分:-1)
在类似问题上回答相同问题:Python | change text color in shell
想法是使用clint库。它支持MAC,Linux和Windows shell(CLI)。