0

0

python logging如何输出到文件_python logging日志模块输出到文件配置

尼克

尼克

发布时间:2025-09-26 10:35:02

|

1019人浏览过

|

来源于php中文网

原创

Python logging通过配置FileHandler将日志输出到文件,可设置编码、格式和级别;使用RotatingFileHandler或TimedRotatingFileHandler实现按大小或时间滚动日志,避免文件过大;多线程下logging自带线程安全,多进程需用QueueHandler和QueueListener保证安全;可通过addLevelName自定义日志级别如TRACE;在Django或Flask等Web框架中可通过配置文件或app.logger集成日志功能,实现灵活的日志管理。

python logging如何输出到文件_python logging日志模块输出到文件配置

Python logging如何输出到文件?简单来说,就是配置logging模块,让它不仅在控制台显示日志,还能把日志保存到指定的文件里,方便后续分析和排查问题。

解决方案:

  1. 基础配置:

    import logging
    
    # 创建一个logger
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.DEBUG)  # 设置日志级别
    
    # 创建一个handler,用于写入日志文件
    fh = logging.FileHandler('my_log.log', encoding='utf-8')
    fh.setLevel(logging.DEBUG)
    
    # 定义日志格式
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(formatter)
    
    # 将handler添加到logger
    logger.addHandler(fh)
    
    # 记录日志
    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('This is a critical message')

    这段代码创建了一个名为my_logger的logger,并设置了日志级别为DEBUG。 然后,创建了一个FileHandler,指定日志文件名为my_log.log,并设置编码utf-8,避免中文乱码问题。 定义了一个日志格式,包括时间、logger名称、日志级别和消息内容。最后,将FileHandler添加到logger中,这样logger产生的日志就会写入到文件中。 编码设置很重要,特别是处理中文的时候,不设置的话,很有可能出现乱码。

    立即学习Python免费学习笔记(深入)”;

  2. 更灵活的配置方式:使用logging.basicConfig

    如果你觉得上面的方式有点繁琐,可以使用logging.basicConfig来简化配置:

    import logging
    
    logging.basicConfig(filename='my_log.log', level=logging.DEBUG,
                        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                        encoding='utf-8')
    
    logger = logging.getLogger('my_logger')
    
    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('This is a critical message')

    logging.basicConfig可以一次性配置日志文件名、日志级别、日志格式等。 注意,logging.basicConfig只能调用一次,多次调用只有第一次生效。 所以,如果你需要在不同的地方使用不同的配置,还是建议使用第一种方式。

  3. 更高级的配置:使用logging.config

    对于更复杂的配置,例如需要同时输出到多个文件、使用不同的日志级别、自定义handler等,可以使用logging.config模块,通过读取配置文件的方式进行配置。

    创建一个名为logging.conf的配置文件:

    [loggers]
    keys=root, my_logger
    
    [handlers]
    keys=consoleHandler, fileHandler
    
    [formatters]
    keys=myFormatter
    
    [logger_root]
    level=WARNING
    handlers=consoleHandler
    
    [logger_my_logger]
    level=DEBUG
    handlers=fileHandler
    qualname=my_logger
    propagate=0
    
    [handler_consoleHandler]
    class=StreamHandler
    level=WARNING
    formatter=myFormatter
    args=(sys.stdout,)
    
    [handler_fileHandler]
    class=FileHandler
    level=DEBUG
    formatter=myFormatter
    args=('my_log.log', 'a', 'utf-8')  ; filename, mode, encoding
    
    [formatter_myFormatter]
    format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
    datefmt=

    然后在Python代码中使用logging.config.fileConfig加载配置文件:

    import logging
    import logging.config
    import sys
    
    logging.config.fileConfig('logging.conf')
    
    logger = logging.getLogger('my_logger')
    
    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('This is a critical message')

    这种方式的优点是配置和代码分离,方便修改和维护。 配置文件可以使用ini格式,也可以使用yaml格式。 使用yaml格式需要安装PyYAML库。

如何设置日志文件的滚动?防止日志文件过大

日志文件一直增长会占用大量磁盘空间,所以需要设置日志文件的滚动。 logging.handlers模块提供了RotatingFileHandlerTimedRotatingFileHandler两种方式来实现日志文件的滚动。

  1. RotatingFileHandler:按文件大小滚动

    import logging
    from logging.handlers import RotatingFileHandler
    
    # 创建一个logger
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.DEBUG)
    
    # 创建一个handler,用于写入日志文件
    # maxBytes:单个日志文件的最大大小,单位是字节
    # backupCount:保留的日志文件数量
    rfh = RotatingFileHandler('my_log.log', maxBytes=1024*1024, backupCount=5, encoding='utf-8')
    rfh.setLevel(logging.DEBUG)
    
    # 定义日志格式
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    rfh.setFormatter(formatter)
    
    # 将handler添加到logger
    logger.addHandler(rfh)
    
    # 记录日志
    for i in range(10000):
        logger.debug(f'This is a debug message {i}')

    RotatingFileHandler会根据文件大小进行滚动。 当日志文件达到maxBytes指定的大小时,会自动创建一个新的日志文件,并将原来的日志文件重命名。 backupCount指定了保留的日志文件数量,超过这个数量的日志文件会被删除。

  2. TimedRotatingFileHandler:按时间滚动

    import logging
    from logging.handlers import TimedRotatingFileHandler
    import datetime
    
    # 创建一个logger
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.DEBUG)
    
    # 创建一个handler,用于写入日志文件
    # when:指定滚动的时间间隔,例如'S'(秒), 'M'(分), 'H'(小时), 'D'(天), 'W'(周), 'midnight'(每天凌晨)
    # interval:滚动的时间间隔的倍数
    # backupCount:保留的日志文件数量
    trfh = TimedRotatingFileHandler('my_log.log', when='D', interval=1, backupCount=7, encoding='utf-8')
    trfh.setLevel(logging.DEBUG)
    
    # 定义日志格式
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    trfh.setFormatter(formatter)
    
    # 将handler添加到logger
    logger.addHandler(trfh)
    
    # 记录日志
    for i in range(1000):
        logger.debug(f'This is a debug message {i}')
    
    print(f"Current time: {datetime.datetime.now()}")

    TimedRotatingFileHandler会根据时间进行滚动。 when参数指定了滚动的时间间隔,例如'D'表示每天滚动一次,'midnight'表示每天凌晨滚动一次。 interval参数指定了滚动的时间间隔的倍数,例如when='D', interval=2表示每两天滚动一次。

如何在多线程或多进程中使用logging?

在多线程或多进程中使用logging需要注意线程安全和进程安全的问题。 多个线程或进程同时写入同一个日志文件可能会导致日志内容混乱或丢失。

Bandy AI
Bandy AI

全球领先的电商设计Agent

下载
  1. 线程安全:使用logging.Lock

    logging模块本身是线程安全的,但是如果多个线程同时使用同一个handler写入日志文件,可能会出现问题。 可以使用logging.Lock来保证线程安全。

    import logging
    import threading
    
    # 创建一个logger
    logger = logging.getLogger('my_logger')
    logger.setLevel(logging.DEBUG)
    
    # 创建一个handler,用于写入日志文件
    fh = logging.FileHandler('my_log.log', encoding='utf-8')
    fh.setLevel(logging.DEBUG)
    
    # 定义日志格式
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(formatter)
    
    # 将handler添加到logger
    logger.addHandler(fh)
    
    # 创建一个锁
    log_lock = threading.Lock()
    
    def log_message(message):
        with log_lock:
            logger.debug(message)
    
    # 创建多个线程
    threads = []
    for i in range(5):
        t = threading.Thread(target=log_message, args=(f'This is a message from thread {i}',))
        threads.append(t)
        t.start()
    
    # 等待所有线程结束
    for t in threads:
        t.join()

    在这个例子中,我们创建了一个threading.Lock对象,并在写入日志之前获取锁,写入日志之后释放锁。 这样可以保证同一时间只有一个线程可以写入日志文件,避免了线程安全问题. 其实logging模块内部已经使用了锁,在大多数情况下,不需要手动添加锁。

  2. 进程安全:使用logging.handlers.QueueHandlerlogging.handlers.QueueListener

    在多进程中使用logging需要使用logging.handlers.QueueHandlerlogging.handlers.QueueListenerQueueHandler将日志消息放入一个队列中,QueueListener从队列中读取日志消息并写入到日志文件中。 这样可以避免多个进程同时写入同一个日志文件,保证进程安全。

    import logging
    import logging.handlers
    import multiprocessing
    import queue
    
    # 创建一个队列
    log_queue = queue.Queue(-1)
    
    # 创建一个handler,用于写入日志文件
    file_handler = logging.FileHandler('my_log.log', encoding='utf-8')
    file_handler.setLevel(logging.DEBUG)
    
    # 定义日志格式
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    file_handler.setFormatter(formatter)
    
    # 创建一个listener
    listener = logging.handlers.QueueListener(log_queue, file_handler)
    listener.start()
    
    def log_message(i):
        # 创建一个logger
        logger = logging.getLogger(f'process_{i}')
        logger.setLevel(logging.DEBUG)
    
        # 创建一个queue handler
        queue_handler = logging.handlers.QueueHandler(log_queue)
        logger.addHandler(queue_handler)
    
        logger.debug(f'This is a message from process {i}')
    
    # 创建多个进程
    processes = []
    for i in range(5):
        p = multiprocessing.Process(target=log_message, args=(i,))
        processes.append(p)
        p.start()
    
    # 等待所有进程结束
    for p in processes:
        p.join()
    
    # 停止listener
    listener.stop()

    在这个例子中,我们创建了一个queue.Queue对象,用于存储日志消息。 然后,创建了一个QueueHandler,并将日志消息放入队列中。 创建了一个QueueListener,从队列中读取日志消息并写入到日志文件中。 这样可以保证多个进程安全地写入日志文件。

如何自定义日志级别?

Python logging 模块预定义了几个日志级别:DEBUG, INFO, WARNING, ERROR, CRITICAL。 但是,有时候我们需要自定义日志级别,例如,我们需要添加一个TRACE级别,用于记录更详细的调试信息。

import logging

# 定义一个新的日志级别
TRACE = 5
logging.addLevelName(TRACE, 'TRACE')

# 创建一个logger
logger = logging.getLogger('my_logger')
logger.setLevel(TRACE)

# 为logger添加一个trace方法
def trace(self, message, *args, **kws):
    if self.isEnabledFor(TRACE):
        self._log(TRACE, message, args, **kws)
logging.Logger.trace = trace

# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('my_log.log', encoding='utf-8')
fh.setLevel(TRACE)

# 定义日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)

# 将handler添加到logger
logger.addHandler(fh)

# 记录日志
logger.trace('This is a trace message')
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')

首先,我们使用logging.addLevelName函数定义了一个新的日志级别TRACE,并将其值设置为5。 然后,我们为logging.Logger类添加了一个trace方法,用于记录TRACE级别的日志。 最后,我们就可以像使用其他日志级别一样使用trace级别了。 需要注意的是,自定义的日志级别的值必须小于logging.DEBUG的值,大于logging.CRITICAL的值。 通常情况下,TRACE级别的值设置为5,DEBUG级别的值设置为10。

如何在Django或Flask等Web框架中使用logging?

在Django或Flask等Web框架中使用logging,通常需要在项目的配置文件中配置logging。

  1. Django:

    settings.py文件中配置logging:

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'verbose': {
                'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
                'style': '{',
            },
            'simple': {
                'format': '{levelname} {message}',
                'style': '{',
            },
        },
        'handlers': {
            'file': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',
                'filename': 'django.log',
                'formatter': 'verbose'
            },
        },
        'loggers': {
            'django': {
                'handlers': ['file'],
                'level': 'INFO',
                'propagate': True,
            },
            'my_app': {  # 你的app名称
                'handlers': ['file'],
                'level': 'DEBUG',  # 设置你的app的日志级别
                'propagate': False,
            },
        },
    }

    然后在你的代码中使用logging:

    import logging
    
    logger = logging.getLogger('my_app')  # 使用你的app名称
    
    def my_view(request):
        logger.debug('This is a debug message')
        logger.info('This is an info message')
        logger.warning('This is a warning message')
        logger.error('This is an error message')
        logger.critical('This is a critical message')
        # ...

    在Django中,你需要确保LOGGING配置正确,并且使用正确的logger名称。 通常情况下,logger名称应该与你的app名称相同。

  2. Flask:

    在Flask中,你可以直接使用logging模块,或者使用Flask提供的app.logger对象。

    from flask import Flask
    import logging
    
    app = Flask(__name__)
    app.logger.setLevel(logging.DEBUG)  # 设置Flask app的日志级别
    
    # 或者使用logging模块
    # logger = logging.getLogger('my_app')
    # logger.setLevel(logging.DEBUG)
    
    @app.route('/')
    def index():
        app.logger.debug('This is a debug message')  # 使用app.logger
        app.logger.info('This is an info message')
        app.logger.warning('This is a warning message')
        app.logger.error('This is an error message')
        app.logger.critical('This is a critical message')
        # logger.debug('This is a debug message') # 或者使用logging模块
        return 'Hello, World!'
    
    if __name__ == '__main__':
        # 配置logging
        logging.basicConfig(filename='flask.log', level=logging.DEBUG,
                            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        app.run(debug=True)

    在Flask中,你可以使用app.logger对象来记录日志,也可以直接使用logging模块。 如果你使用logging模块,需要手动配置logging。

总而言之,Python logging模块非常强大,可以灵活地配置日志输出到文件,并且支持日志滚动、多线程/多进程安全、自定义日志级别等高级功能。 掌握logging模块的使用,可以帮助你更好地调试和维护你的Python程序。

相关文章

python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python Flask框架
Python Flask框架

本专题专注于 Python 轻量级 Web 框架 Flask 的学习与实战,内容涵盖路由与视图、模板渲染、表单处理、数据库集成、用户认证以及RESTful API 开发。通过博客系统、任务管理工具与微服务接口等项目实战,帮助学员掌握 Flask 在快速构建小型到中型 Web 应用中的核心技能。

86

2025.08.25

Python Flask Web框架与API开发
Python Flask Web框架与API开发

本专题系统介绍 Python Flask Web框架的基础与进阶应用,包括Flask路由、请求与响应、模板渲染、表单处理、安全性加固、数据库集成(SQLAlchemy)、以及使用Flask构建 RESTful API 服务。通过多个实战项目,帮助学习者掌握使用 Flask 开发高效、可扩展的 Web 应用与 API。

72

2025.12.15

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

297

2023.10.25

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

503

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

166

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

14

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

15

2026.01.21

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

2

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.3万人学习

Django 教程
Django 教程

共28课时 | 3.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号