python log日志 多线程安全

       python中的日志文件为logger,常用的有两个-RotatingFileHandler;TimedRotatingFileHandler。文件没满足分割条件前,保存在‘info.log’(自己命名的文件)中,如果满足分割条件,会生成‘info.log.1’。下一次满足分割条件后,将‘info.log’保存成‘info.log.1’,而‘info.log.1’顺延成‘info.log.2’;满足最多保存的个数后,会将其删掉。

       RotatingFileHandler,是按大小划分日志文件,使用方法如下。RotatingFileHandler是按文件大小自动分割保存,下文中设置的是1M保存一个文件,最多保存30个。此种方式支持多线程安全,支持软件的开关机(TimedRotatingFileHandler不支持,一旦关机,会重新计时)

import logging
from logging import handlers

def log_init():
    log = logging.getLogger('error.log')            # log保存位置
    format_str = log.Formatter('%(asctime)s - \     # log时间戳格式
        %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')                         
    log.setLevel(logging.DEBUG)                     # log日志等级(往下的内容不保存)
    sh = logging.StreamHandler()                    # 往屏幕上输出
    # filename:log文件名;maxBytes:超过最大尺寸,log会另存一个文件;
    # backupCount:最多保存多少个日志;encoding:保存编码格式
    th = handlers.RotatingFileHandler(filename='error.log', maxBytes=1024*1024, \
                                    backupCount=30, encoding='uft-8')        
    th.setFormatter(format_str)                     # 设置文件里写入的格式
    log.addHandler(sh)
    log.addHandler(th)
    return log

if __name__ == '__main__':
    log = log_init()
    log.debug('debug_msg')
    log.info('info_msg')
    log.warning('warning_msg')
    log.error('error_msg')
    log.critical('critical_msg')

        TimedRotatingFileHandler是按日期划分日志文件,使用方法如下。TimedRotatingFileHandler是按文件大小自动分割保存,下文中设置的是每天保存一个log文件,最多保存30个。此种方式支持多线程不安全不支持软件的关机(软件关机后,会重新计时,如果经常关机的项目,会只记录在一个文件中)。

import logging
from logging import handlers

def log_init():
    log = logging.getLogger('error.log')            # log保存位置
    format_str = log.Formatter('%(asctime)s - \     # log时间戳格式
        %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')                         
    log.setLevel(logging.DEBUG)                     # log日志等级(往下的内容不保存)
    sh = logging.StreamHandler()                    # 往屏幕上输出
    # filename:log文件名;when:多久另存一个文件(S/M/H/D/W/midnight);
    # backupCount:最多保存多少个日志;encoding:保存编码格式
    th = handlers.TimedRotatingFileHandler(filename='error.log', when='D', \
                                    backupCount=30, encoding='uft-8')        
    th.setFormatter(format_str)                     # 设置文件里写入的格式
    log.addHandler(sh)
    log.addHandler(th)
    return log

if __name__ == '__main__':
    log = log_init()
    log.debug('debug_msg')
    log.info('info_msg')
    log.warning('warning_msg')
    log.error('error_msg')
    log.critical('critical_msg')

       如果想多线程使用TimedRotatingFileHandler,就需要自己写一个线程,然后每一个log往消息队列中丢,用线程处理这个消息队列。Queue是线程安全的,所以作为消息队列使用没有影响。

import time
import _thread
import logging
from logging import handlers
from queue import Queue

logs_queue = Queue()

class LogMsg(object):
    def __init__(self, type, msg):
        self._type = type
        self._msg = msg

def log_init():
    log = logging.getLogger('error.log')            # log保存位置
    format_str = log.Formatter('%(asctime)s - \     # log时间戳格式
        %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')                         
    log.setLevel(logging.DEBUG)                     # log日志等级(往下的内容不保存)
    sh = logging.StreamHandler()                    # 往屏幕上输出
    # filename:log文件名;when:多久另存一个文件(S/M/H/D/W/midnight);
    # backupCount:最多保存多少个日志;encoding:保存编码格式
    th = handlers.TimedRotatingFileHandler(filename='error.log', when='D', \
                                    backupCount=30, encoding='uft-8')        
    th.setFormatter(format_str)                     # 设置文件里写入的格式
    log.addHandler(sh)
    log.addHandler(th)
    return log

def cop_log_queue(logger):
    while True:
        if logs_queue.empty():
           time.sleep(1)
        log_msg = logs_queue.get()
        if log_msg._type == 'debug':
            logger.debug(log_msg._msg)
        elif log_msg._type == 'info':
            logger.info(log_msg._msg)
        elif log_msg._type == 'warning':
            logger.warning(log_msg._msg)
        elif log_msg._type == 'error':
            logger.error(log_msg._msg)
        elif log_msg._type == 'critical':
            logger.critical(log_msg._msg)

def error_thread1():
    while True:
        logs_queue.put(LogMsg('debug','debug_msg'))
        time.sleep(1)

def error_thread2():
    while True:
        logs_queue.put(LogMsg('info','info_msg'))
        time.sleep(1)

if __name__ == '__main__':
    logger = log_init()
    _thread.start_new_thread(cope_log_queue, (logger, ))
    _thread.start_new_thread(error_thread1, ())
    _thread.start_new_thread(error_thread2, ())


 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 中,可以使用 `logging` 模块记录日志。如果需要在多线程环境下记录日志,可以使用 `concurrent_log_handler` 模块来实现。 首先需要安装 `concurrent_log_handler` 模块: ``` pip install concurrent_log_handler ``` 然后,可以使用以下代码来记录日志: ```python import logging from concurrent_log_handler import ConcurrentRotatingFileHandler import threading # 创建日志记录器 logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # 创建文件处理器 handler = ConcurrentRotatingFileHandler(filename='example.log', mode='a', maxBytes=1024, backupCount=3) handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) # 将处理器添加到记录器 logger.addHandler(handler) # 多线程记录日志 def worker(): logger.debug('Debug message from thread {0}'.format(threading.current_thread().name)) logger.info('Info message from thread {0}'.format(threading.current_thread().name)) logger.warning('Warning message from thread {0}'.format(threading.current_thread().name)) logger.error('Error message from thread {0}'.format(threading.current_thread().name)) logger.critical('Critical message from thread {0}'.format(threading.current_thread().name)) threads = [] for i in range(10): t = threading.Thread(target=worker) threads.append(t) t.start() for t in threads: t.join() ``` 上面的代码中,创建了一个 `ConcurrentRotatingFileHandler` 类实例化的文件处理器,它可以在多线程环境下安全地写入日志文件。然后,将处理器添加到日志记录器中,并使用多线程来记录日志

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值