来了CSDN辣么多年,第一次写文章。博主还是个菜鸟,前段时间实习被公司要求研究一下Python版的spdlog怎么用来保存日志,在别的地方搜,但是搜到的资料特别少(大概是因为很少人用),然后自己搞了半天终于搞出了点结果,不过都是些简单的例子。先贡献上代码吧(现在大部分人用的是C++ 的,Python版的估计也没什么人看)
首先,下载安装spdlog。打开cmd,输入以下代码。(在pycharm直接搜索下载也可以)
pip install spdlog
1、在控制台输入日志,不保存文件:
name = 'aha?' # 名字随便起
logger = ConsoleLogger(name, multithreaded=False, stdout=True, colored=False, async_mode=False)
# or logger = ConsoleLogger(name, False, True, False) # multithreaded=False, stdout=True, colored=False
logger.trace('Trace what?')
logger.debug('Any thing wrong?')
logger.info('This is a piece of useless information')
logger.warn('Actually,no warn for you~')
logger.error('Always error')
logger.critical('I am so sleepy~~')
运行之后控制台就会输出logger的信息:
2、标准输出、标准错误输出、保存日志文件(普通文件、daily文件、rotate文件)
stdout_logger = spdlog.stdout_sink_st()
# or create a color logger
# stdout_logger = spdlog.stdout_color_sink_mt()
logger_1 = spdlog.SinkLogger("name", [stdout_logger])
logger_1.info("This is a stdout_logger1.")
# info can be replaced by warn, error, critical if it's needed...
stderr_logger = spdlog.stderr_sink_st()
# or create a color logger
# stderr_logger = spdlog.stderr_color_sink_mt()
logger_2 = spdlog.SinkLogger("name", [stderr_logger])
logger_2.info("This is a stderr_logger2.")
# info can be replaced by warn, error, critical if it's needed...
# create a basic logger
spdlog.basic_file_sink_st('filename.txt')
# multithreaded=false, truncate=false
logger_3 = spdlog.FileLogger('name', 'filename.txt', False,
False)
logger_3.info('You have create a basic logger.')
# info can be replaced by warn, error, critical if it's needed...
# hours=8,minutes=30
daily_logger = spdlog.daily_file_sink_st('filename_daily.log', 8, 30)
# update at 8:30am
logger_4 = spdlog.SinkLogger('name', [daily_logger])
logger_4.info('This is a daily logger.')
# info can be replaced by warn, error, critical if it's needed...
spdlog.rotating_file_sink_st('filename_rotate.log', 1024, 5)
# create a rotate file, size=1024, file number=5
# multithreaded=false, async_mode=False
logger_5 = spdlog.RotatingLogger('name1', 'filename_rotate.log', False, 1024, 5, False)
logger_5.info('This is a rotate logger.')
# info can be replaced by warn, error, critical if it's needed...
spdlog.stdout_sink_st() 和spdlog.stderr_sink_st()仅在控制台输出,其余输出保存在日志文件,位于根目录下面。
文件内容:
3、设置级别
from spdlog import ConsoleLogger, LogLevel
import unittest
def log_msg(logger, level):
if level == LogLevel.TRACE:
logger.trace('I am Trace')
elif level == LogLevel.DEBUG:
logger.debug('I am Debug')
elif level == LogLevel.INFO:
logger.info('I am Info')
elif level == LogLevel.WARN:
logger.warn('I am Warning')
elif level == LogLevel.ERR:
logger.error('I am Error')
else:
logger.critical('I am Critical')
def set_log_level(logger, level):
print("Setting Log level to %d" % level)
logger.set_level(level)
class Test(unittest.TestCase):
def test_log_level(self):
# multithreaded=False, stdout=True, colored=False
logger = ConsoleLogger('Logger', False, True, False)
for level in (LogLevel.TRACE, LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN,
LogLevel.ERR, LogLevel.CRITICAL):
set_log_level(logger, level)
log_msg(logger, level)
if __name__ == "__main__":
unittest.main()
结果:
在C++中,级别就是trace、debug这些,但是Python级别分别是结果中对应的0-5
4、通过等级设置日志信息何时出现在文件何时出现在控制台的例子
import spdlog
import unittest
class MyTestCase(unittest.TestCase):
def test_something(self):
spdlog.basic_file_sink_st('asynclogger.txt') # create a basic logger
logger = spdlog.FileLogger('name', 'asynclogger.txt', False,
False) # multithreaded=false, truncate=false
logger.async_mode() # setting async model
# queue_size = 2048, thread_count = 4, overflow_policy = 1
# logger.spdlog.set_async_mode(2048, 4, 1)
for i in range(100):
logger.info('You have create a async logger. test_%d' % i)
# multi sink example
console_sink = spdlog.stdout_sink_mt()
# level: trace=0, debug=1, info=2, warn=3, error=4, critical=5, off=6
console_sink.set_level(3)
file_sink = spdlog.basic_file_sink_mt('basic.txt')
file_sink.set_level(0)
sink = [file_sink, console_sink]
logger_multi = spdlog.SinkLogger('multi_sink', sink)
logger_multi.set_level(1)
# logger.set_pattern('{:%Y-%m-%d --- %H:%M:%S}', spdlog.PatternTimeType(0))
# while use set_pattern, inside '' must be string
logger_multi.warn('This should appear in both console and file?')
logger_multi.info('This message should not appear in the console, only in the file')
# end of multi sink example
# binary example
num = [10, 20, 30, 40]
binary_logger = spdlog.stdout_sink_st()
logger_n = spdlog.SinkLogger("name", [binary_logger])
logger_n.info('{:02X} {:02X} {:02X} {:02X}'.format(*num))
logger_n.info('{:#X} {:#b} {:#e} {:#o}'.format(*num))
# end of binary example
get_logger = spdlog.get('name')
get_logger.info('test spdlog.get, and this will be showed in name') # write into 'name' logger
get_logger.flush()
get_logger.flush_on(2) # number is level
get_logger.set_error_handler(Warning) # I am not sure
# null_sink seams to do nothing
null_logger = spdlog.null_sink_mt()
logger_1 = spdlog.SinkLogger("null", [null_logger])
logger_1.info("Notice: this will not be showed.")
get_logger = spdlog.get('null')
get_logger.debug('test spdlog.get')
if __name__ == '__main__':
unittest.main()
控制台结果:
保存的日志文件:
basic文件的内容:
以上。禁止转载。
代码已上传GitHub