杰瑞科技汇

Ubuntu Python如何打印log?

下面我将从简单到专业,为你详细介绍如何在 Ubuntu 中使用 Python 打印日志。

Ubuntu Python如何打印log?-图1
(图片来源网络,侵删)

最简单的方式:使用 print()

对于非常小的脚本或快速调试,直接使用 print() 是最直接的方法。

优点:

  • 简单、直观,无需任何额外知识。

缺点:

  • 功能有限:无法区分日志级别(如 INFO, ERROR)。
  • 格式单一:无法自定义日志格式(如时间戳、文件名)。
  • 难以管理:在生产环境中,很难控制 print 的输出(只输出 ERROR 级别以上的日志)。
  • 性能问题:频繁的 print 调用可能会对性能产生微小但可察觉的影响。

示例代码 (simple_print.py):

Ubuntu Python如何打印log?-图2
(图片来源网络,侵删)
import time
import os
def process_data(data):
    print(f"INFO: 开始处理数据: {data}")
    # 模拟处理过程
    time.sleep(1)
    if not data:
        print("ERROR: 数据为空,处理失败!")
        return None
    print(f"INFO: 数据处理成功: {data.upper()}")
    return data.upper()
if __name__ == "__main__":
    user_input = input("请输入要处理的数据: ")
    result = process_data(user_input)
    print(f"最终结果: {result}")

在 Ubuntu 中运行:

python3 simple_print.py

或者,如果你想将日志重定向到一个文件:

python3 simple_print.py > my_app.log 2>&1
  • > : 将标准输出 重定向到文件。
  • 2>&1 : 将标准错误 也重定向到同一个文件。

标准且专业的方式:使用 Python 内置的 logging 模块

这是 Python 官方推荐的方式,功能强大,灵活且是行业标准。

logging 模块有几个核心概念:

  • Logger (记录器):这是你直接交互的对象,你通过 getLogger(__name__) 获取一个 logger。__name__ 是一个好习惯,它会让你知道日志来自哪个模块。
  • Handler (处理器):决定日志输出到哪里。
    • StreamHandler: 输出到终端(控制台)。
    • FileHandler: 输出到文件。
    • RotatingFileHandler: 输出到文件,当日志文件达到一定大小时,会自动创建新文件。
  • Formatter (格式化器):决定日志的输出格式,可以包含时间戳、日志级别、模块名、行号、消息等。
  • Level (级别):定义日志的重要性程度,从低到高依次为:
    • DEBUG: 详细的调试信息。
    • INFO: 一般性的信息,确认程序按预期运行。
    • WARNING: 警告信息,表示可能发生了意想不到的事情,但程序仍在运行。
    • ERROR: 错误信息,表示程序某部分功能无法正常工作。
    • CRITICAL: 严重错误,表示程序可能无法继续运行。

示例代码 (basic_logging.py):

import logging
import time
# 1. 获取一个 logger 实例
# 使用 __name__ 是一个好习惯,可以标识日志的来源模块
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)  # 设置最低的日志级别,DEBUG 级别及以上的日志都会被处理
# 2. 创建一个 Handler,用于将日志输出到控制台
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)  # 这个 Handler 只处理 INFO 级别及以上的日志
# 3. 创建一个 Formatter,定义日志格式
# 格式说明:
# %(asctime)s: 时间戳
# %(name)s: logger 的名字
# %(levelname)s: 日志级别
# %(message)s: 日志消息
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 4. 将 Formatter 添加到 Handler
console_handler.setFormatter(formatter)
# 5. 将 Handler 添加到 Logger
logger.addHandler(console_handler)
def process_data(data):
    logger.debug(f"DEBUG: 开始处理数据: {data}") # 这个日志不会在控制台显示,因为 console_handler 的级别是 INFO
    time.sleep(1)
    if not data:
        logger.error("ERROR: 数据为空,处理失败!") # 这个日志会显示
        return None
    logger.info(f"INFO: 数据处理成功: {data.upper()}") # 这个日志会显示
    return data.upper()
if __name__ == "__main__":
    logger.info("应用程序启动")
    user_input = input("请输入要处理的数据: ")
    result = process_data(user_input)
    logger.info(f"应用程序结束,最终结果: {result}")

在 Ubuntu 中运行:

python3 basic_logging.py

输出结果: 你会看到 DEBUG 级别的日志被过滤掉了,只显示 INFOERROR 级别的日志。

2025-10-27 10:30:00,123 - __main__ - INFO - 应用程序启动
请输入要处理的数据: hello world
2025-10-27 10:30:01,124 - __main__ - INFO - INFO: 数据处理成功: HELLO WORLD
2025-10-27 10:30:01,125 - __main__ - INFO - 应用程序结束,最终结果: HELLO WORLD

进阶用法:将日志写入文件并配置

在实际项目中,我们通常需要将日志同时输出到控制台和文件,并希望文件能自动滚动,避免单个文件过大。

示例代码 (advanced_logging.py):

import logging
import os
from logging.handlers import RotatingFileHandler
# 1. 创建 logger
logger = logging.getLogger("my_app")
logger.setLevel(logging.DEBUG) # 设置 logger 的最低级别为 DEBUG
# 2. 创建 Formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s')
# 3. 创建控制台 Handler 并设置级别
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO) # 控制台只显示 INFO 及以上
console_handler.setFormatter(formatter)
# 4. 创建文件 Handler (带滚动功能)
# 日志文件最大 1MB,保留 3 个备份
log_file_path = os.path.join(os.getcwd(), 'app.log')
file_handler = RotatingFileHandler(
    log_file_path, 
    maxBytes=1*1024*1024, 
    backupCount=3,
    encoding='utf-8'
)
file_handler.setLevel(logging.DEBUG) # 文件中记录所有级别的日志
file_handler.setFormatter(formatter)
# 5. 将 Handler 添加到 logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)
def another_function():
    logger.debug("这是一个来自 another_function 的调试信息。")
    logger.warning("这是一个警告,但程序可以继续运行。")
if __name__ == "__main__":
    logger.info("应用程序启动")
    for i in range(5):
        logger.info(f"正在处理第 {i} 项任务...")
        another_function()
    logger.info("应用程序结束")

在 Ubuntu 中运行:

python3 advanced_logging.py

你会看到:

  1. 控制台输出:只显示 INFOWARNING 级别的日志,格式符合 console_handler 的设置。
  2. 文件输出 (app.log):文件中包含了 DEBUG, INFO, WARNING 所有级别的日志,格式更详细(包含了文件名和行号)。
  3. 文件滚动:当你多次运行这个脚本,app.log 文件大小超过 1MB 后,它会自动被重命名为 app.log.1,并创建一个新的 app.log 文件,之前的 app.log.1, app.log.2, app.log.3 会被保留。

最佳实践:使用配置文件 (logging.config)

对于大型项目,将所有 logging 配置硬编码在 Python 文件中会变得非常臃肿,推荐使用配置文件(如 YAML 或 JSON)来管理日志配置。

步骤:

  1. 安装 PyYAML (如果使用 YAML 配置文件):

    pip install pyyaml
  2. 创建一个配置文件 logging_config.yaml:

    version: 1
    disable_existing_loggers: False
    formatters:
      simple:
        format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
      detailed:
        format: "%(asctime)s - %(name)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s"
    handlers:
      console:
        class: logging.StreamHandler
        level: INFO
        formatter: simple
        stream: ext://sys.stdout
      file:
        class: logging.handlers.RotatingFileHandler
        level: DEBUG
        formatter: detailed
        filename: app.log
        maxBytes: 1048576 # 1MB
        backupCount: 3
        encoding: utf8
    loggers:
      my_app:
        level: DEBUG
        handlers: [console, file]
        propagate: no # 阻止日志向上传递到 root logger
    root:
      level: WARNING
      handlers: [console]
  3. 创建一个使用该配置文件的 Python 脚本 (config_logging_example.py):

    import logging
    import logging.config
    import yaml
    import os
    def setup_logging(default_path='logging_config.yaml', default_level=logging.INFO):
        """Setup logging configuration"""
        path = default_path
        if os.path.exists(path):
            with open(path, 'r') as f:
                config = yaml.safe_load(f)
                logging.config.dictConfig(config)
                logging.info("Logging configuration loaded from YAML.")
        else:
            logging.basicConfig(level=default_level)
            logging.warning(f"Logging config file not found at {path}. Using basicConfig.")
    # 设置日志
    setup_logging()
    # 获取 logger
    logger = logging.getLogger("my_app")
    if __name__ == "__main__":
        logger.debug("这是一个调试信息,只会在文件中看到。")
        logger.info("应用程序启动,使用配置文件进行日志记录。")
        logger.warning("这是一个警告,会在控制台和文件中都看到。")
        logger.error("这是一个错误!")

在 Ubuntu 中运行:

python3 config_logging_example.py

这种方式非常灵活,你可以在不修改任何代码的情况下,通过修改 logging_config.yaml 文件来调整日志行为,非常适合不同环境(开发、测试、生产)的配置管理。

方法 优点 缺点 适用场景
print() 极其简单,无需学习 功能弱,难以管理,不专业 快速脚本、临时调试
logging 模块 功能强大,灵活,可配置,是行业标准 相对 print 来说有学习曲线 所有 Python 项目,从小脚本到大型应用
logging.config 配置与代码分离,灵活,易于维护不同环境 需要额外依赖(如 PyYAML) 中大型项目,需要灵活切换环境配置

强烈建议你从学习并使用 logging 模块开始,这是成为专业 Python 开发者的必经之路。

分享:
扫描分享到社交APP
上一篇
下一篇