python自带logging模块的使用总结 附github测试

本文详细介绍Django项目中如何使用Python的logging模块配置日志,包括日志级别、输出格式、文件滚动策略等,适用于生产环境日志管理和调试。

django使用python自带的logging日志模块来实现,调试或者生产环境中调试信息的记录。尤其是在生产环境中尤为重要,与调试环境下 日志输出控制台不同,生产环境下需要将日志打印到文件中,方便检查程序运行过程中的相关信息。
官方文档查看地址>>>>>>>>https://docs.python.org/3/library/logging.handlers.html#rotatingfilehandler
测试历程github地址>>>>>>>https://github.com/veujs/djangocelery

1、logging模块

  • 日志记录级别
    logging模块的重点在于生成和处理日志消息。每条消息由一些文本和指示其严重性的相关级别组成。级别包含符号名称和数字值。

    | 级别 | 值 | 描述 |
    |–|–|–|–|–|
    | CRITICAL| 50 | 关键错误/消息 |
    | ERROR | 40| 错误|
    | WARNING| 30| 警告消息|
    | INFO| 20| 通知消息|
    | DEBUG| 10| 调试
    | NOTSET| 0| 无级别|

  • 记录器
    记录器负责管理日志消息的默认行为,包括日志记录级别、输出目标位置、消息格式以及其它基本细节

    | 参数| 描述 |
    |–|–|–|–|–|
    | filename| 将日志消息附加到指定文件名的文件 |
    | filemode| 指定用于打开文件模式|
    | format| 用于生成日志消息的格式字符串|
    | datefmt|用于输出日期和时间的格式字符串|
    | level| 设置记录器的级别
    | stream| 提供打开的文件,用于把日志消息发送到文件。|

  • 日志格式

    | 格式| 描述 |
    |–|–|–|–|–|
    | %(name)s| 记录器的名称 |
    | %(levelno)s| 数字形式的日志记录级别|
    | %(levelname)s| 日志记录级别的文本名称|
    | %(filename)s|执行日志记录调用的源文件的文件名称|
    | %(pathname)s| 执行日志记录调用的源文件的路径名称 |
    | %(funcName)s| 执行日志记录调用的函数名称|
    | %(module)s| 执行日志记录调用的模块名称|
    | %(lineno)s| 执行日志记录调用的行号|
    | %(created)s| 执行日志记录的时间|
    | %(asctime)s| 日期和时间|
    | %(msecs)s| 毫秒部分|
    | %(thread)d| 线程ID|
    | %(threadName)s| 线程名称|
    | %(process)d| 进程ID|
    | %(message)s| 记录的消息|

  • Handler处理器(具体参数可参考官方使用文档,前三个为常用的)

    | 格式| 描述 |
    |–|–|–|–|–|
    | StreamHandler| 发送日志到sys.stdout、sys.stder等 |
    | RotatingFileHandler| 输出日志到文件中、支持以文件大小回滚切分文件|
    | TimedRotatingFileHandler| 输出日志到文件中、支持以时间间隔回滚切分文件|
    | HTTPHandler|使用HTTP的GET或POST方法将日志消息上传到一台HTTP 服务器|
    | SMTPHandler| 支持通过SMTP发送消息记录到一个电子邮件地址 |
    |QueueHandler| 支持发送记录消息到队列中|
    | SocketHandler| 送日志输出到网络套接字|
    | DatagramHandler| 支持通过UDP套接字发送日志记录消息|

2、django中使用logging模块记录日志

注:以下内容为实际验证过的
  • settings.py文件中配置如下

    # 日志文件
    BASE_LOG_DIR = os.path.join(os.path.dirname(BASE_DIR), "logs")
    
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False, # 选择是否使用django默认的logger记录器
        'formatters': {  # 配置打印日志格式
            'standard': {  # name:记录器的名称  lineo:执行日志记录调用的行号 module:执行日志记录调用的模块名称 funcName:模块中调用的函数  levelname:日志级别
                'format': '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'}
        },
    
        # 'filters': {  # 过滤器   # 控制哪些日志可以从logger流向Handler
        #     'require_debug_true': {
        #         '()': 'django.utils.log.RequireDebugTrue',
        #     },
        # },
    
        'handlers': {  # 用来定义具体处理日志的方式(规定日志输出到哪里),可以定义多种,"default"就是默认方式,"console"就是打印到控制台方式
            'default': {
                'level': 'warning',  #  level==warning表示筛选logger传递过来的warning及以上的日志信息,下面配置含义相同
                'class': 'logging.handlers.RotatingFileHandler',  # 会根据文件大小(5M)自动切分log文件
                'filename': os.path.join(BASE_LOG_DIR, "warning.log"),  # 日志输出文件名称
                'maxBytes': 1024 * 1024 * 5,  # 文件大小
                'backupCount': 5,  # 备份份数
                'formatter': 'standard',  # 使用哪种formatters日志格式
            },
            'error': {
                'level': 'ERROR',
                'class': 'logging.handlers.RotatingFileHandler',
                'filename': os.path.join(BASE_LOG_DIR, "error.log"),
                'maxBytes': 1024 * 1024 * 5,
                'backupCount': 5,
                'formatter': 'standard',
            },
            'request_handler': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',
                'filename': os.path.join(BASE_LOG_DIR, "debug.log"),
                'maxBytes': 1024 * 1024 * 5,
                'backupCount': 5,
                'formatter': 'standard',
            },
            # # 在终端打印
            # 'console': {
            #     'level': 'DEBUG',
            #     'filters': ['require_debug_true'],  # 只有在Django debug为True时才在屏幕打印日志
            #     'class': 'logging.StreamHandler',  #
            #     'formatter': 'simple'
            # },
        },
    
        'loggers': {  # LOGGER记录器,配置用那种handlers来处理日志,比如你同时需要输出日志到文件、控制台。----logger传递日志到handler
            # 以下三个为django基本需要的记录器,尽量不要动
    
            # ‘’ 日志实例对象默认配置(需要'disable_existing_loggers': False才能生效),此时在别的模块中使用logger_default = logging.getLogger(__name__),记录器的名称为该模块的名称,并使用default处理器来处理日志
            '': {
                'handlers': ['default'],
                'level': 'DEBUG',
                'propagate': False  # 向不向更高级别的logger传递
            },
    
            'django': {  # 若将对应的handler中的level等级改为DEBUG,那么会在日志文件中把所有的信息打印出来,包括对数据库的操作(前提是django开启的是DEBUG模式!!)
                'handlers': ['default'],
                'level': 'DEBUG',
                'propagate': False  # 向不向更高级别的logger传递
            },
    
            'django.request': {  # 这个记录器用于记录django框架里面的所有request请求的记录,名称必须为django.request!!!!
                'handlers': ['request_handler'],
                'level': 'DEBUG',
                'propagate': False,
            },
    
    
            # 下面自定义记录器
            'views_error': {  #
                'handlers': ['default', 'error', 'request_handler'],  # 会根据三个handler中日志的等级,在其对应的日志文件中进行打印
                'level': 'DEBUG',
                'propagate': True
            },
        },
    }
    
  • view.py文件中设置

    # 首先,导入logging模块
    import logging
    
    # 获取记录器
    # logger = logging.getLogger('django.request') # 使用settings模块中设置的django.request记录器
    # logger = logging.getLogger('views_error') # 使用settings模块中设置的views_error记录器
    logger110 = logging.getLogger(__name__) # 以当前模块名为记录器名称,通过这种方式声明的,其loggers会默认使用上文中定义好的 ‘’ 对应的记录器
    
    def index(request):
        logger110.info("info: this is a info level")
        logger110.debug("debug: this is a debug level")
        logger110.warning("warning: this is a warning level")
    
        logger110.error("error: this is a error level")
        print(logger110.name)
        return render(request, 'index.html')
    
    
  • 结果展示
    运行django项目,访问127.0.0.1:8000
    查看error.log warning.log debug.log 三个文件中的日志打印情况,如下:
    在这里插入图片描述
    可以看到,在warning.log文件中打印了WARNINGERROR日志信息,而INFO信息则被过滤掉了

3、需要进一步整理的内容如下:

  • django中默认的logger记录器在哪儿定义的

  • filters的使用

  • 使用函数配置logger

    # 利用函数的方式手动配置单个logger记录器的方法如下:
    import logging
    logger = logging.getLogger(__name__) # __name__为当前模块的名称
    logger.setLevel(level=logging.INFO)
    Handler = logging.FileHandler(os.path.join(settings.BASE_LOG_DIR, "tasksystem.log"))
    formatter = logging.Formatter('%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s')
    Handler.setFormatter(formatter)
    logger.addHandler(Handler)
    
### Python代码单元测试教程和最佳实践 #### 单元测试的重要性 单元测试是软件开发过程中不可或缺的一部分,它能够验证单个模块的功能是否按预期工作。对于Python开发者而言,良好的单元测试可以显著提高代码质量并减少Bug的发生率。 #### 测试覆盖率的概念 测试覆盖率是一种度量标准,用于衡量测试是否覆盖了代码中的各个部分。这一指标可以帮助识别未被充分检验的部分,进而改进测试套件以增强程序稳定性和健壮性[^1]。 #### 基础框架unittest简介 `unittest` 是Python自带的标准库之一,提供了丰富的功能支持创建结构化的测试案例集。下面是一个简单的例子展示如何利用 `unittest` 进行基本函数的测试: ```python import unittest def add(a, b): """返回两个数相加的结果""" return a + b class TestAddFunction(unittest.TestCase): def test_add_positive_numbers(self): self.assertEqual(add(1, 2), 3) if __name__ == '__main__': unittest.main() ``` #### pytest框架介绍及其优势 除了内置的 `unittest` 外,`pytest` 是另一个非常流行的第三方测试框架,具有更简洁直观的语法以及强大的插件生态系统。以下是使用 `pytest` 的相同示例: ```python # content of test_sample.py def add(a, b): """返回两个数相加的结果""" return a + b def test_add_positive_numbers(): assert add(1, 2) == 3 ``` 要运行上述测试只需在命令行输入 `pytest` ,该工具会自动发现所有匹配模式(如test_*.py)下的测试文件并执行它们。 #### 提高测试效率的方法——参数化测试 为了使测试更加灵活高效,在面对大量相似场景时可以通过参数化的方式一次性定义多个数据点来进行批量验证。这里给出基于 `@pytest.mark.parametrize()` 装饰器实现的例子: ```python @pytest.mark.parametrize( "input_x,input_y,output", [ (0, 0, 0), (-1, 1, 0), (2, 3, 5) ] ) def test_add(input_x, input_y, output): assert add(input_x, input_y) == output ``` 此方法允许一次性的配置多组不同的输入输出组合,极大地提升了编写重复性测试工作的便捷程度。 #### 集成持续集成/部署(CI/CD)管道 将自动化构建与发布流程相结合可以在每次提交新版本之前确保现有功能正常运作,并及时捕捉潜在问题。GitHub Actions、GitLab CI 和 Travis CI 等平台都提供简单易用的服务接口来设置CI环境。 #### 使用mock对象模拟外部依赖关系 当待测组件涉及到网络请求或其他难以控制的因素时,借助 `unittest.mock` 或者专门设计用来做Mocking的库比如 `responses` 可以为这些交互行为创造虚拟替身,从而专注于核心逻辑本身而不受外界干扰影响。 #### 记录日志辅助调试过程 适当加入日志打印语句有助于追踪复杂业务流内部状态变化情况;特别是在遇到异常状况时能快速定位原因所在。Python日志模块(`logging`)非常适合完成这项任务,而且可以根据实际需求调整不同级别的消息显示策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值