Loguru打印日志

591 阅读2分钟
  1. loguru可方便打印python程序运行中输出的日志,也可把日志保存在其他地方,用法比logging简单。
  2. 多线程和多进程能达到一样的并行效果,多进程能利用多核cpu,多线程通过os快速切换实现在单核上并行执行。线程锁会防止不同线程间共用变量出错。

from loguru import logger
import sys
from threading import Thread, current_thread
import threading
import numpy as np
from atexit import register
import time

"""
参考: https://blog.csdn.net/bailang_zhizun/article/details/107863671 
loguru 日志级别: NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL
"""
lock = threading.Lock()


def main():
    logger.add(sys.stderr, format="{time}{level}{message}", filter="my_module", level="WARNING")
    """
    Handler 为控制台输出
    format 指定 输出格式
    """
    for i in range(10):
        if i == 0:
            logger.debug("{}是0".format(i))
        elif i % 2 == 0:
            logger.warning("{} 是2的整倍数.".format(i))
        else:
            if i % 3 == 0:
                logger.info("{} 是3的倍数.".format(i))
            else:
                logger.error("{}不是3的倍数.".format(i))
    logger.critical("running ended!")


def multiThreadAdd(num, c):
    with lock:                # 加线程锁是为了防止多线程间共用变量出问题
        myname = current_thread().name
        for i in range(c):
            num += num
            logger.info("线程{}-第{}次加和为{}".format(myname, i, num))
            time.sleep(0.5)


def multiThreadTest(N, M):
    # lock.acquire()
    # with lock:
    myname = current_thread().name
    logger.info("Startted {}", myname)
    matrix_list = []
    for i in range(M):
        matrix = np.ones([N, N])
        matrix_list.append(matrix)
        logger.info("线程{}-第{}次加入matrix_list.".format(myname, i))
    # lock.release()


# * python解释器中注册一个退出函数,也就是说,他会在脚本退出之前请求调用这个特殊函数
@register
def _atexit():
    logger.info("All Thread DONE!")
    logger.info("\n===========================================================================\n")


if __name__ == "__main__":

    main()

    logger.remove(handler_id=None)
    # 1. 通过add传入文件路径,loguru就可以自动创建一个日志文件了
    logger.add("runtime.log")

    # 2. 只想在文件中可见,不想在控制台看到日志,用remove
    logger.remove(handler_id=None)       # 去除语句要在add文件之前

    # 3. 通过添加占位符{time}添加文件的日期
    logger.add("runtime_{time}.log")

    # 4. 配置rotation参数,指定滚动记录的条件,及超过多大会新建一个log文件
    logger.add("runtime_{time}.log", rotation="500 MB")
    logger.add("runtime_{time}.log", rotation="12:00")
    logger.add("runtime_{time}.log", rotation="1 week")

    # 5. 配置retention参数,指定日志保留时长
    logger.add("runtime_{time}.log", retention="10 days")

    # 6. 配置日志文件的压缩格式
    logger.add("runtime_{time}.log", compression="zip")

    # 7. 通过catch装饰器捕获异常
    logger.remove(handler_id=None)
    logger.add("./Log_files/runtime_{time}.log")

    @logger.catch
    def my_function(x, y, z):
        return 1 / (x + y + z)
    my_function(0, 0, 0)

    # 7.1 通过exception方法也可捕获异常
    logger.remove(handler_id=None)
    logger.add("Log_files/runtime_{time}.log")

    def my_function1(x, y, z):
        try:
            return  1 / (x + y + z)
        except ZeroDivisionError:
            logger.exception("What?!")
    my_function1(0, 0, 0)

    # 8. loguru 可在多模块下使用而不会发生冲突(比如导包,会记录在一个文件下)
    #
    # 9. 多线程使用:所有添加至sink默认都是线程安全的,loguru可以很安全的在多线程情形下使用
    logger.remove(handler_id=None)
    logger.add("./Log_files/multiThreadAdd.log")
    t1 = Thread(target=multiThreadAdd, args=(10, 15,))
    t2 = Thread(target=multiThreadAdd, args=(20, 15,))
    t3 = Thread(target=multiThreadAdd, args=(15, 15,))
    t4 = Thread(target=multiThreadAdd, args=(12, 15,))
    T = [t1, t2, t3, t4]
    for t in T:
        t.start()
    for t in T:
        t.join()