我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Django 中使用日志的方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Django 中使用日志的方法

1. 日志的意义

日志是个好东西,但却并不是所有人都愿意记,直到出了问题才追悔莫及,长叹一声,当初要是记日志就好了。

但记日志却是个技术活,不能什么都不记,但也不能什么都记。如果记了很多没用的信息,反而给查日志排错的过程增加很多困难。

所以,日志要记录在程序的关键节点,而且内容要简洁,传递信息要准确。要清楚的反应出程序当时的状态,时间,错误信息等。

只有做到这样,我们才能在第一时间找到问题,并且解决问题

开发阶段,所有的问题都可以通过调试,在程序中输出,但项目上线后,会进行统一的错误处理,不能将错误信息暴漏出来,所以最好的方式,就是将程序运行信息存储在日志中

程序上线后,是万万不能没有日志的

2. django 中如何处理日志

Django 使用 Python 内置的 logging 模块处理系统日志,所以,只要掌握了 Python 中的 logging 模块,基本也就能够在 django 中使用日志了

3. Python 中使用日志

这里简单介绍 Python 中 logging 模块的使用,下一章再聊如何在 django 中使用

logging 模块的使用主要包含如下几个方面

  • 将日志信息直接输出
  • 将日志信息保存到文件中
  • 输出变量到日志中
  • 更改消息显示格式
  • 覆盖日志
  • 日志配置

3.1 直接输出日志信息

首先导入 logging 模块,然后在下面选择方法进行日志输出

级别何时使用
DEBUG细节信息,仅当诊断问题时适用。
INFO确认程序按预期运行。
WARNING表明有已经或即将发生的意外(例如:磁盘空间不足)。程序仍按预期进行。
ERROR由于严重的问题,程序的某些功能已经不能正常执行
CRITICAL严重的错误,表明程序已不能继续执行

简单例子

logging.debug('出现了bug')
logging.info('一般信息')
logging.warning('警告信息以下级别默认不出现')
logging.error('出现了错误')
logging.critical('严重问题')

日志信息,被直接输出出来,并没有记录到日志中

3.2 设置日志级别

上面的 logging.info('一般信息')logging.debug('出现了bug') 并没有任何输出,原因在于 logging 模块默认只输出 WARNING以上级别(包含 WARNING)

通过 basicConfig 方法更改日志级别

# 更改日志级别
    logging.basicConfig(level=logging.INFO)
    logging.info('一般信息')
    logging.debug('出现了bug')
    logging.warning('警告信息以下级别默认不出现')
    logging.error('出现了错误')
    logging.critical('严重问题')

级别 INFO 高于 DEBUG,如果希望 logging.debug 方法生效,需要更改 level 为 logging.DEBUG

3.3 保存日志到文件

实际开发中,日志信息一定要保存到文件的

basicConfig 方法页可以设置日志文件的目录信息

修改案例中第1行代码,添加 filename 参数,设置日志文件目录和名称

logging.basicConfig(filename='0707.log', level=logging.INFO)

打开日志文件,发现乱码了

3.4 设置编码

basicConfig 方法页可以设置日志文件编码

logging.basicConfig(filename='0707.log', encoding='utf-8', level=logging.INFO)

3.5 覆盖日志文件

默认情况下,新的日志内容采用的是追加模式

可以通过 filemode 参数设置覆盖之前的日志内容

logging.basicConfig(filename='0707.log', filemode='w', encoding='utf-8', level=logging.INFO)

basicConfig()被设计为一次性的配置,只有第一次调用会进行操作,随后的调用不会产生有效操作

此段的意思是,当程序启动后,第一次调用上面的方法,会生效,后面如果程序没有重新启动,无论调用多少次,此代码都不会生效

看下面代码

logging.basicConfig(filename='0707.log', filemode='w', encoding='utf-8', level=logging.INFO)
logging.info('一般信息')

启动程序,或者修改代码保存时也会热重载,此时日志文件内容就会被覆盖

但在没有重启的情况下,无论上面代码执行多少次,都不会覆盖内容,而是追加

此种模式的意义在于:程序重启后,旧的日志对于我们没有意义的情况

3.6 记录变量到日志

可以使用下面两种方式进行变量的格式化

logging.basicConfig(filename='0707.log', filemode='w', encoding='utf-8', level=logging.INFO)
logging.info('采用 %s 的方式输出变量', '%s')
logging.info('采用{}的方式输出变量'.format('format'))

3.7 更改显示消息的组成

这是默认情况下日志消息的组成

如果想更改,可以通过 basicConfig 方法的 format 参数设置

logging.basicConfig(format='%(levelname)s:%(message)s', filename='0707.log', filemode='w', encoding='utf-8',
                        level=logging.INFO)
    logging.info('采用 %s 的方式输出变量', '%s')
    logging.info('采用{}的方式输出变量'.format('format'))

下面只显示级别和日志内容,没有 root

代码中levelnamemessage LogRecord 的属性,完整属性列表如下

args此属性不需要用户进行格式化。合并到 msg 以产生 message 的包含参数的元组,或是其中的值将被用于合并的字典(当只有一个参数且其类型为字典时)。
asctime%(asctime)s表示人类易读的 LogRecord 生成时间。 默认形式为 ‘2003-07-08 16:49:45,896’ (逗号之后的数字为时间的毫秒部分)。
created%(created)fLogRecord 被创建的时间(即 time.time() 的返回值)。
exc_info此属性不需要用户进行格式化。异常元组(例如 sys.exc_info)或者如未发生异常则为 None
filename%(filename)spathname 的文件名部分。
funcName%(funcName)s函数名包括调用日志记录.
levelname%(levelname)s消息文本记录级别('DEBUG''INFO''WARNING''ERROR''CRITICAL')。
levelno%(levelno)s消息数字的记录级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL).
lineno%(lineno)d发出日志记录调用所在的源行号(如果可用)。
message%(message)s记入日志的消息,即 msg % args 的结果。 这是在发起调用 Formatter.format() 时设置的。
module%(module)s模块 (filename 的名称部分)。
msecs%(msecs)dLogRecord 被创建的时间的毫秒部分。
msg此属性不需要用户进行格式化。在原始日志记录调用中传入的格式字符串。 与 args 合并以产生 message,或是一个任意对象 (参见 使用任意对象作为消息)。
name%(name)s用于记录调用的日志记录器名称。
pathname%(pathname)s发出日志记录调用的源文件的完整路径名(如果可用)。
process%(process)d进程ID(如果可用)
processName%(processName)s进程名(如果可用)
relativeCreated%(relativeCreated)d以毫秒数表示的 LogRecord 被创建的时间,即相对于 logging 模块被加载时间的差值。
stack_info此属性不需要用户进行格式化。当前线程中从堆栈底部起向上直到包括日志记录调用并引发创建当前记录堆栈帧创建的堆栈帧信息(如果可用)。
thread%(thread)d线程ID(如果可用)
threadName%(threadName)s线程名(如果可用)

比如,修改上面代码,加上 asctime 属性

logging.basicConfig(format='%(levelname)s:%(message)s:%(asctime)s', filename='0707.log', filemode='w', encoding='utf-8',
                        level=logging.INFO)

查看日志

3.8 模块化

上面介绍的方法已经可以为程序配置日志功能了

logging 模块页提供了模块化的方法,通过下面几个组件来配置日志

  • 记录器:暴露了应用程序代码直接使用的接口
  • 处理器:将日志记录(由记录器创建)发送到适当的目标
  • 过滤器:提供了更细粒度的功能,用于确定要输出的日志记录
  • 格式器:指定最终输出中日志记录的样式

其实完成的还是上面的功能,只不过可以进行模块化拆分,比如可以创建多个处理器,多个格式器,通过配置的方式进行处理器、格式器的切换

3.8.1 通过 Python 方法配置

# 创建记录器
logger = logging.getLogger('simple')
# 设置日志记录级别
logger.setLevel(logging.DEBUG)
# 创建处理器
ch = logging.StreamHandler()
# 设置处理器级别
ch.setLevel(logging.DEBUG)
# 创建格式器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 为处理器设置格式器
ch.setFormatter(formatter)
# 将处理器添加到记录器
logger.addHandler(ch)

logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

总结:

①:创建记录器:记录器中提供了 info、debu、warning、error、critical 方法用来记录日志

②:设置记录器级别:此级别了哪个级别以上的信息会被记录到日志中

③:创建处理器:处理器决定如何处理消息、比如打印到控制台、写入日志文件、发送邮件等

④:设置处理器级别:决定处理器发送哪些消息。记录器中设置的级别,决定哪个级别以上的消息会被发送给处理器,处理器中的设置级别决定了,哪些消息会被处理,比如哪些消息会被写到文件中。

⑤:创建格式器:决定日志的格式和日志中包含哪些内容

⑥:将格式器添加到处理器:处理器将使用此格式器格式化日志

⑦:将处理器添加到记录器:记录器将使用此处理器处理日志

如果希望日志保存到文件中,只需重新创建一个处理器,将其添加到记录器中即可

# 创建控制器,将日志写入到文件中
    ch_file = logging.FileHandler('aa.log')
    ch_file.setLevel(logging.DEBUG)
    # 为处理器设置格式器
    ch_file.setFormatter(formatter)

    # 将处理器添加到记录器
    logger.addHandler(ch_file)

3.8.2 配置字典

Python 3.2中引入的一种新的配置日志记录的方法–用字典来保存logging配置信息。这相对于上面所讲的基于配置文件来保存logging配置信息的方式来说,功能更加强大,也更加灵活,因为我们可把很多的数据转换成字典。比如,我们可以使用JSON格式的配置文件、YAML格式的配置文件,然后将它们填充到一个配置字典中;或者,我们也可以用Python代码构建这个配置字典,或者通过socket接收pickled序列化后的配置信息。总之,你可以使用你的应用程序可以操作的任何方法来构建这个配置字典

编写配置字典,然后通过 logging.config.dictConfig 方法调用此字典

1、简单配置

    # 用于格式化
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

    log_dict = {
        "version": 1,
        'disable_existing_loggers': False,
        "formatters": {
            "simple": {
                'format': simple_format
            }
        },

        "handlers": {
            "console": {
                "class": 'logging.StreamHandler',
                "level": 'INFO',
                "formatter": "simple"
            }
        },
        "loggers": {
            "simple": {
                "level": "DEBUG",
                "handlers": ['console'],
                'propagate': True,
            }
        }
    }
    logging.config.dictConfig(log_dict)

    logger = logging.getLogger('simple')

    logger.debug('debug message')
    logger.info('info message')
    logger.warning('warn message')
    logger.error('error message')
    logger.critical('critical message')

①:创建了一个名为 simple 的格式器

②:创建了一个名为 console 的处理器,并设置处理器使用的格式器为 simple

③:创建了额一个名为 simple 的记录器,并设置记录器使用的处理器为 console

2、增加新的格式器、处理器和记录器

创建一个新的格式器

standard = '%(levelname)s:%(asctime)s:%(filename)s:%(lineno)d:%(message)s'

添加

创建新的处理器,用于将日志写入文件

在记录器中添加此处理器

运行程序,日志将同时打印到控制台和日志文件中

这里应该体会到了使用配置字典的好处

创建记录器时,选择 standard,则只会输出 ERROR 以上的日志信息

3、配置文件-yaml

开发时,最好的方式,当然不是在程序中编写代码做出上面配置

而是,新建配置文件,程序运行时,读取配置文件

我们将配置写到一个 yaml ,然后读取此文件

根目录下新建 log_config.yml (yaml 文件的后缀名可以是yaml 或者 yml)

version: 1
formatters:
    simple:
        format: '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    standard:
        format: '%(levelname)s:%(asctime)s:%(filename)s:%(lineno)d:%(message)s'
handlers:
    console:
        class: logging.StreamHandler
        level: DEBUG
        formatter: simple
    file:
        class: logging.FileHandler
        formatter: simple
        filename: logtest.log

loggers:
    simple:
        level: DEBUG
        handlers: [ file ]
        propagate: True
    standard:
        level: ERROR
        handlers: [ console,file ]
        propagate: True

视图函数代码,读取 yaml 文件,并将其转换成 dict,使用 logging.config.dictConfig 方法加载配置,并使用其中名称为 simple 的记录器

BASE_DIR = Path(__file__).resolve().parent.parent
    with open(str(BASE_DIR) + '\config.yaml', 'r', encoding='utf-8') as f:
        file = f.read()
        config = yaml.load(file, Loader=yaml.FullLoader)

    logging.config.dictConfig(config)

    logger = logging.getLogger('simple')

    logger.debug('debug message')
    logger.info('info message')
    logger.warning('warn message')
    logger.error('error message')
    logger.critical('critical message')

切换记录器,看看效果

练习:自己再配置几个处理器和格式器

4、写到 settings 中

也可以将上面的配置直接写到 settings.py 中

变量名称必须为 LOGGING

# 日志配置
LOGGING = {
    "version": 1,
    "formatters": {
        "simple": {
            "format": '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
        },
        "standard": {
            "format": '%(levelname)s:%(asctime)s:%(filename)s:%(lineno)d:%(message)s'
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "simple"
        },
        "file": {
            "class": "logging.FileHandler",
            "formatter": "simple",
            "filename": "logtest.log"
        }
    },
    "loggers": {
        "simple": {
            "level": "DEBUG",
            "handlers": ["file"],
            "propagate": True
        },
        "standard": {
            "level": "ERROR",
            "handlers": ["console", "file"],
            "propagate": True
        }
    }
}

视图函数

logger = logging.getLogger('simple')

logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

4. django 日志

上面介绍了 Python 中使用日志的方式,有了这些基础之后,学习 django 中日志的使用就事半功倍了

django 中仍然使用了 logging 模块做日志处理

其实,3.8 节已经讲完了,就是这么用。。。。

附:关于 logging 模块的详细说明

在Python的logging模块中,主要包含下面四大方面:

  • Loggers: 记录器
  • Handlers:处理器
  • Filters: 过滤器
  • Formatters: 格式化器

下文详细说明一下这四大模块

4.1 Loggers

logger 是日志系统的入口。每个 logger 都是命名了的 bucket, 消息写入 bucket 以便进一步处理。

logger 可以配置日志级别。日志级别描述了由该 logger 处理的消息的严重性。Python 定义了下面几种日志级别:

DEBUG:排查故障时使用的低级别系统信息;INFO:一般的系统信息;WARNING:描述系统发生了一些小问题的信息;ERROR:描述系统发生了大问题的信息;CRITICAL:描述系统发生严重问题的信息;

每一条写入 logger 的消息都是一条日志记录。每一条日志记录也包含日志级别,代表对应消息的严重程度。日志记录还包含有用的元数据,来描述被记录的事件细节,例如堆栈跟踪或者错误码。

当logger处理一条消息时,会将自己的日志级别和这条消息的日志级别做对比。如果消息的日志级别匹配或者高于 logger 的日志级别,它就会被进一步处理。否则这条消息就会被忽略掉。

当 logger 确定了一条消息需要处理之后,会把它传给Handler。

4.2 Handlers

Handler是决定如何处理logger中每一条消息的引擎。它描述特定的日志行为,比如把消息输出到屏幕、文件或网络 socket。

和logger一样,handler也有日志级别的概念。如果一条日志记录的级别不匹配或者低于handler的日志级别,对应的消息会被 handler忽略。

一个logger可以有多个handler,每一个handler可以有不同的日志级别。这样就可以根据消息的重要性不同,来提供不同格式的输出。例如,你可以添加一个 handler 把ERROR和CRITICAL消息发到寻呼机,再添加另一个handler把所有的消息(包括 ERROR和CRITICAL消息)保存到文件里以便日后分析。

4.3 过滤器

在日志从 logger 传到 handler 的过程中,使用 Filter 来做额外的控制。

默认情况下,只要级别匹配,任何日志消息都会被处理。不过,也可以通过添加filter来给日志处理的过程增加额外条件。例如,可以添加一个filter只允许某个特定来源的ERROR消息输出。

Filter还被用来在日志输出之前对日志记录做修改。例如,可以写一个filter,当满足一定条件时,把日志记录从ERROR降到 WARNING级别。

Filter在logger和handler中都可以添加;多个filter可以链接起来使用,来做多重过滤操作。

4.4 Formatters

日志记录最终是需要以文本来呈现的。Formatter 描述了文本的格式。一个 formatter 通常由包含 LogRecord attributes 的 Python 格式化字符串组成,不过你也可以为特定的格式来配置自定义的 formatter。

到此这篇关于django 中使用日志的文章就介绍到这了,更多相关django 使用日志内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Django 中使用日志的方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

MySQL中binlog日志的使用方法

这篇文章主要介绍MySQL中binlog日志的使用方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!binlog 就是binary log,二进制日志文件,这个文件记录了MySQL所有的DML操作。通过binlog日
2023-06-14

Java日志的使用方法

这篇文章将为大家详细讲解有关Java日志的使用方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. 客户端开发;4.
2023-06-14

Django记录操作日志与LogEntry的使用方法是什么

这篇文章主要介绍“Django记录操作日志与LogEntry的使用方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Django记录操作日志与LogEntry的使用方法是什么”文章能帮助大家解
2023-06-26

php错误日志的使用方法

这篇文章主要介绍了php错误日志的使用方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。使用php错误日志的方法是,首先打开php配置文件;然后修改配置【log_errors
2023-06-15

MySQL中Binlog日志的使用方法详细介绍

MySQLBinlog(二进制日志)记录数据库操作,用于数据复制、数据恢复和审计。启用后,记录修改操作并写入Binlog。通过不同格式和管理命令,可查看和管理Binlog。在主从复制中,Binlog用于同步数据变更。Binlog也可用于数据恢复,通过应用日志将数据库恢复到特定时间点。此外,Binlog可作为审计记录,提供操作历史、用户和时间等信息。建议始终启用Binlog,定期备份,监视大小,进行跨服务器复制和审计。
MySQL中Binlog日志的使用方法详细介绍
2024-04-02

怎么在Python中使用handler方法输出日志

今天就跟大家聊聊有关怎么在Python中使用handler方法输出日志,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Python主要用来做什么Python主要应用于:1、Web开发;
2023-06-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录