Django中l(wèi)og日志記錄的最佳實(shí)踐
這一節(jié)介紹在 Django 系統(tǒng)里使用 logging 記錄日志
以下是一個(gè)簡單的 logging 模塊示例,可以先預(yù)覽一下,接下來會(huì)詳細(xì)介紹各個(gè)模塊的具體功能:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(message)s',
}
},
'handlers': {
'file_1': {
'level': 'INFO',
'filename': '/Users/hunter/python/log_path/file_1.log',
'formatter': 'verbose',
'class': 'logging.FileHandler',
},
'file_2': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '/Users/hunter/python/log_path/file_2.log',
'formatter': 'verbose',
},
'custom_file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '/Users/hunter/python/log_path/custome_file.log',
'formatter': 'verbose',
}
},
'loggers': {
'': {
'handlers': ['file_1'],
'level': 'INFO',
'propagate': False,
},
'django': {
'handlers': ['file_2'],
'level': 'INFO',
'propagate': True,
},
'custom': {
'handlers': ['custom_file'],
'level': 'INFO',
'propagate': False,
}
}
}
1、模塊總覽
在 Django 系統(tǒng)中,日志的記錄也可以在 setting.py 中配置,key 為 logging,然后下面有幾個(gè)主要的模塊:
loggers、handlers、filters、formatters
系統(tǒng)接收到日志信息后,進(jìn)入 logger,然后根據(jù)指定的 handler 列表發(fā)送到 handler 中
根據(jù) handler 的處理方式,將信息寫入文件、發(fā)送郵件或者其他方式
這些信息可以經(jīng)過 filter 進(jìn)行進(jìn)一步的過濾,根據(jù) formatter 的信息組織形式通過 handler 的處理方式進(jìn)行處理
2、Loggers
Loggers 是學(xué)習(xí)日志系統(tǒng)的一個(gè)切入點(diǎn),每個(gè) logger 都是一個(gè)命名的桶,處理的信息可以作為日志寫入到 logger 里
每一個(gè) logger 都可以被配置一個(gè)日志等級(jí),日志等級(jí)描述了 logger 記錄的信息的嚴(yán)重程度,python 定義了如下幾種日志等級(jí):
- DEBUG:低的、基于調(diào)試目的的系統(tǒng)信息
- INFO:一般系統(tǒng)消息
- WARNING:發(fā)生了小問題的信息
- ERROR:發(fā)生了大問題的信息
- CRITICAL:發(fā)生了嚴(yán)重的問題的信息
每個(gè)被寫入 logger 的消息都被稱為是一個(gè) Log Record(日志記錄)。
每個(gè)日志記錄在被發(fā)送到 logger 的時(shí)候都有一個(gè)日志等級(jí)來表示信息的嚴(yán)重程度
比如:
logger.info("xxx")
這些日志記錄應(yīng)該包含一些有用的、包含了問題產(chǎn)生原因的信息
當(dāng)一條消息被發(fā)送到 logger,消息的等級(jí)會(huì)和 logger 的日志等級(jí)做一個(gè)比較,只有當(dāng)消息的等級(jí)大于或等于 logger 的記錄等級(jí)時(shí),消息才會(huì)被當(dāng)前 logger 進(jìn)行更多的處理
如果這條消息被 logger 接收,那么它會(huì)被發(fā)送到 Handlers
3、Handlers
我們可以理解 handler 是一個(gè)處理器,用來決定每天發(fā)送到 logger 的信息應(yīng)該怎么處理,也就是日志的記錄形式
比如說寫入一個(gè)文件,發(fā)送郵件等
跟 Logger 一樣,handler也有一個(gè)日志等級(jí),只有當(dāng)發(fā)送到 handler 的日志等級(jí)大于等于 handler 的日志記錄時(shí),handler 才會(huì)處理信息
一個(gè) Logger 可以有多個(gè) handler 處理器,每個(gè) handler 都可以有自己的日志等級(jí),因此可以根據(jù)信息的重要程度來決定不同的輸出
比如你可以用一個(gè) handler 把 ERROR 和 CRITICAL 等級(jí)的信息轉(zhuǎn)發(fā)到服務(wù)頁面,另一個(gè) handler 記錄所有的信息到一個(gè)文件,用作后續(xù)的分析
4、Filters
過濾器常被用來提供額外的控制,處理從 logger 到 handler 的日志記錄
理論上來說,任何日志消息只要滿足了日志等級(jí)的要求,都會(huì)被發(fā)送到 handler 處理,如果加了一個(gè) filter 過濾器,你可以在日志處理上添加額外的標(biāo)準(zhǔn)
比如說你可以添加一個(gè)過濾器,只允許某個(gè)特定來源的 ERROR 等級(jí)的信息被處理
filter 也可以用來修改消息的嚴(yán)重等級(jí),比如一些特定的條件被滿足的情況下,你可以將ERROR等級(jí)的日志降級(jí)為 WARNING
在本篇筆記中,將不介紹 filter 的使用方法,因?yàn)槟芎唵尉秃唵我稽c(diǎn),暫時(shí)不用那么多配置
5、Formatters
格式化,一個(gè)日志記錄需要被渲染成一個(gè)文本,formatter 提供了一些格式器的屬性,格式化器由一些 LogRecord 的屬性值組成,你也可以自己定義一個(gè)屬性
6、日志記錄方式
當(dāng)你配置了 loggers,handlers,filters 和 formatters 之后,你可以先獲取一個(gè) logger 的實(shí)例,然后通過 logger 來記錄日志
以下是使用示例:
import logging
logger = logging.getLogger(__name__)
def my_view(request):
logger.info("this is a log")
這個(gè)在調(diào)用 my_view 的時(shí)候,系統(tǒng)就會(huì)記錄一條日志
如果是其他等級(jí)的日志記錄,則會(huì)是:
logger.debug() logger.info() logger.warning() logger.error() logger.critical()
以下是對日志的記錄流程匯總一下:
- 當(dāng)有一條日志信息需要被記錄,然后會(huì)被發(fā)送到對應(yīng)的 logger
- 然后 logger 根據(jù)指定的 handler 被發(fā)送到對應(yīng)的 handler 處理器
- 在 handler 中會(huì)根據(jù)日志的等級(jí)或者定義的 filter 進(jìn)行一定的過濾
- 最終將符合條件的日志信息根據(jù) formatter 的格式定義,將最終形成的日志信息,進(jìn)行 console 操作、記錄到文件、或者發(fā)送郵件等操作
在筆記開篇的 logging 示例中,日志的配置在這個(gè) dict 里編寫的順序和消息處理的順序是相反的
這里沒有設(shè)置 filter 的操作,所以消息的處理就是從 logger 到 handler 再到 formatter
我們手動(dòng)在接口里寫入一個(gè)日志消息,分別在 urls.py 和 views.py 里如下定義:
# blog/urls.py
from django.urls.conf import path
from blog.views import time_view
urlpatterns = [
path("curr_time", time_view),
]
# blog/views.py
import datetime
from django.http import HttpResponse
import logging
logger = logging.getLogger(__name__)
def time_view(request):
now = datetime.datetime.now()
html = "<h1>now: %s</h1>" % now
logger.info("this is a log !")
return HttpResponse(html)
啟動(dòng)系統(tǒng)后,在瀏覽器中訪問 http://localhost:9898/blog/curr_time,可以看到定義的日志目錄下已經(jīng)寫入了數(shù)據(jù):file_1.log 和 file_2.log
打開這兩個(gè)日志文件,可以看到 loggers 下空字符串指定的 logger 對應(yīng)的處理器寫入的 file_1.log 寫入的內(nèi)容如下:
INFO this is a log ! xxxx INFO "GET /blog/curr_time HTTP/1.1" 200 40 xxxx
其中包含接口訪問信息和我們在接口里自定義的 'this is a log !' 信息
在 file_2.log 中,則只有接口的訪問信息:
INFO 200 40 xxxx
在實(shí)例化 logger 的時(shí)候,如果不指定 logger 的名稱,那么則會(huì)默認(rèn)寫入我們定義的空字符串下的 logger
不指定 logger 名稱的意思即為,getLogger 的時(shí)候不指定 logger 的參數(shù):
logger = logging.getLogger(__name__)
7、logger 參數(shù)解析
在這里 loggers 里設(shè)置兩個(gè) key,一個(gè)為空字符串,一個(gè)是 django。
我們可以理解 key 為 django' 這個(gè) logger 是一個(gè)固定的值,會(huì)接收到所有來自系統(tǒng)的日志信息,比如一些接口的請求信息,但是不包括用戶自定的 logger 輸出。
空字符串這里的 logger,可以接收到用戶自定義的 logger 輸出,也可以接收到一些接口的請求信息,但是這個(gè)需要 propagate 的配置
在 loggers 的配置里面:
'loggers': {
'': {
'handlers': ['file_1'],
'level': 'INFO',
'propagate': False,
},
'django': {
'handlers': ['file_2'],
'level': 'INFO',
'propagate': True,
}
}
有如下幾個(gè)參數(shù):
handlers 是指定消息處理器的,value 是一個(gè)列表,可以指定多個(gè)處理器,比如說一條消息,你可以同時(shí)指定寫入文件和發(fā)送郵件,或者寫入不同的文件
level 參數(shù)表示日志的等級(jí),這里設(shè)置的是 INFO 等級(jí),如果接收到的消息的等級(jí)小于 INFO,那么就會(huì)不處理,大于等于 INFO 才會(huì)被發(fā)送到 handler 處理器中處理
propagate 參數(shù)意義可以理解為是否傳遞傳遞,在這兩個(gè) logger 里,如果 django 這個(gè) logger 的 propagate 的值設(shè)為了 True,django 這個(gè) logger 的消息是可以向 空字符串設(shè)置的 logger 傳遞的
換句話說,django 接收到的所有消息都會(huì)給空字符串的 logger 再發(fā)一遍,使用它的 logger 再進(jìn)行一遍處理,
如果 propagate 設(shè)為了 False,那么空字符串的 logger 僅能接收到用戶自定義的消息
8、handler 參數(shù)解析
當(dāng)一條消息從 logger 被發(fā)送到 handler,handlers 參數(shù)也可以定義多個(gè),通過不同的 key 來區(qū)分
在每個(gè) handler 下我們這里設(shè)置了四個(gè)值:
level 設(shè)置了 handler 處理的日志等級(jí),只有當(dāng)發(fā)送過來的日志的等級(jí)大于等于該等級(jí)時(shí),這個(gè) handler 才會(huì)處理
class 設(shè)置了日志處理的方式,這里我們的值為 logging.FileHandler,表示是文件處理方式
此外還有比如 StreamHandler 輸出到 Stream 打印到標(biāo)準(zhǔn)輸出,還有 HttpHandler 通過HTTP 協(xié)議向服務(wù)器發(fā)送 log, 還有 SMTPHandler 會(huì)通過 email 發(fā)送log
filename 指定輸出的日志地址,前面我們的 class 定義為向文件輸出,那么這里的 filename 就定義了輸出的文件的地址
formatter 則是指定下一級(jí)日志文本的輸出格式處理的 formatter
日志文件處理策略
對于日志文件,如果系統(tǒng)一直運(yùn)行,那么則會(huì)存在一個(gè)問題,那就是日志文件越來越大,這個(gè)對于系統(tǒng)的存儲(chǔ)和我們查找日志都是不合適的
因此接下來我們新增幾個(gè)參數(shù)用來制定日志文件的處理策略
maxBytes,這個(gè)定義了一個(gè)日志文件最大的字節(jié)數(shù),如果寫滿了就會(huì)新開一個(gè)文件繼續(xù)寫而不是繼續(xù)在原有文件繼續(xù)增加內(nèi)容
如果我們需要設(shè)置一個(gè)文件最大為5M,就可以設(shè)為 5 * 1024 * 1024
backupCount,最大的日志文件數(shù)量,當(dāng)文件的個(gè)數(shù)超出了我們定義的,則會(huì)刪除最早的日志文件,只保留 backupCount 個(gè)日志文件
但是使用上面這兩個(gè)參數(shù)的話,class 的值就得換成 logging.handlers.RotatingFileHandler
接下來介紹幾種 handler 的信息處理方式
1.RotatingFileHandler 配置
rotate 的是定期調(diào)換位子,輪換的意思
RotatingFileHandler 的作用是根據(jù)文件的大小決定是否寫入新文件,以下是一個(gè)示例:
'custom_file': {
'level': 'INFO',
'filename': '/home/hunter/python/log_path/custom.log',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose',
'maxBytes': 5 * 1024 * 1024,
'backupCount': 10
}
這個(gè)示例表示是將日志寫入文件,每個(gè)文件最大容量為 5 * 1024 * 1024,即 5M,當(dāng)日志寫入一個(gè)文件滿了 5M 之后,將會(huì)新開一個(gè)文件繼續(xù)寫入日志信息,文件夾下保留最新的 10 個(gè)文件。
這里新增了兩個(gè)配置項(xiàng)
backupCount 表示最多保留日志文件的個(gè)數(shù)
maxBytes 表示每個(gè)日志文件最大的存儲(chǔ)容量
2.TimedRotatingFileHandler 配置
TimedRotatingFileHandler 表示是根據(jù)時(shí)間間隔來決定是否寫入新文件,以下是示例:
'time_file': {
'level': 'INFO',
'filename': '/home/hunter/python/log_path/custom.log',
'class': 'logging.handlers.TimedRotatingFileHandler', # 記錄時(shí)間
'formatter': 'verbose',
'backupCount': 3,
'when': 'M',
'interval': 3,
}
當(dāng) handler 的 class 的值為這個(gè)的時(shí)候,表示的是根據(jù)時(shí)間來決定是否寫入新文件,上一個(gè)是根據(jù)文件的容量大小來定的
這里新增了兩個(gè)配置項(xiàng),
一個(gè)是 when,表示的時(shí)間間隔的單位,S為秒,M為分鐘,H為小時(shí),D或者 MIDNIGHT為天,W0-W6為從周一到周日某個(gè)周幾開始間隔一周
另一個(gè)是 interval,間隔時(shí)間的倍數(shù)
日志換新文件繼續(xù)寫入的時(shí)間為 when * interval
3.HttpHandler 基本配置
這個(gè)配置表示是如果來了需要處理的日志消息就調(diào)用一個(gè) HTTP 接口,這里我們可以只做一個(gè)示例:
'http_handler': {
'level': 'INFO',
'class': 'logging.handlers.HTTPHandler',
'formatter': 'verbose',
'host': '192.168.1.8:9898',
'url': '/test_url',
'method': 'POST',
},
這個(gè)地方,多了幾個(gè)配置項(xiàng)
host 表示需要調(diào)用接口的 ip 和 端口
url 表示調(diào)用的接口路徑
method 表示調(diào)用的方法
4.SMTPHandler 基本配置
這個(gè)配置用于發(fā)送郵件,如果日志消息發(fā)送到這個(gè)配置的 handler,系統(tǒng)會(huì)根據(jù)郵件的配置系統(tǒng)發(fā)送郵件給指定的郵箱
以下是一個(gè)使用示例:
'email': {
'level': 'WARNING',
'class': 'logging.handlers.SMTPHandler',
'mailhost': ('smtp.163.com', 25),
'fromaddr': 'xxxxxxxx@163.com',
'toaddrs': 'xxxxxxx@qq.com',
'subject': '系統(tǒng)出錯(cuò)啦?。?!',
'credentials': ('xxxxxxx@163.com', 'JBD******'),
'timeout': 20
},
在這個(gè)配置中,多的配置項(xiàng)的介紹如下:
mailhost 是系統(tǒng)發(fā)送郵件的郵箱的主機(jī)和端口,這里我們配置的是 163 郵箱
fromaddr 是從哪個(gè)郵箱發(fā)出來,我們可以創(chuàng)建一個(gè)163郵箱然后指定該值
toaddrs 是發(fā)送到哪個(gè)郵箱,即日志消息的郵件接收地址
subject 是我們發(fā)送郵件的標(biāo)題,而郵件的正文內(nèi)容即為我們在 logger.warning("報(bào)錯(cuò)信息") 中輸入的信息
credentials 是163郵箱的驗(yàn)證信息,兩個(gè)值,前一個(gè)值與 fromaddr 保持一致,后面的是一串驗(yàn)證碼,是163郵箱開啟 SMTP 服務(wù)之后163郵箱系統(tǒng)頁面給我們的一串授權(quán)密碼,這個(gè)可以自己去了解一下
這樣配置好之后,在 logger 的 handler 列表指定這個(gè) handler,然后通過 logger.warning("報(bào)錯(cuò)信息") 即可觸發(fā)這個(gè)郵件發(fā)送的功能
5.AdminEmailHandler 基本配置
這個(gè)配置也是用于日志發(fā)送郵件,但是是復(fù)用 Django 的默認(rèn)郵箱的功能
在 logging 中的配置是:
'mail_admins': {
'level': 'WARNING',
'class': 'django.utils.log.AdminEmailHandler',
'include_html': True,
},
但是這個(gè)還需要一些額外的在 settings.py 中的郵箱配置,相當(dāng)于是復(fù)用 Django 系統(tǒng)的功能
以下是 settings.py 中郵箱的配置項(xiàng):
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com' # 163 郵箱的配置地址
EMAIL_PORT = 465 # SMTP 端口
EMAIL_HOST_USER = 'xxxxxx@163.com' #這個(gè)是用來發(fā)送郵件的郵箱,與最后一個(gè)填寫的郵箱地址一致
EMAIL_HOST_PASSWORD = 'JBDM******' #這里就是前面提到的授權(quán)密碼
EMAIL_USE_SSL = True
EMAIL_FROM = SERVER_EMAIL = 'xxxxxxx@163.com' # 這個(gè)是發(fā)送郵件的地址,與上面的 163郵箱相同即可
ADMINS = [
['Hunter', 'xxxxxx@qq.com'],
] # 郵件接收地址
上面的參數(shù)都配置好之后也可以日志觸發(fā)郵件了。
9、formatter 參數(shù)解析
formatter 的參數(shù)就簡單一點(diǎn),通過不同的 key 來區(qū)分不同的 formatter,其下設(shè)置一個(gè) format 參數(shù)即可對信息進(jìn)行格式化處理
'formatters': {
'verbose': {
'format': '%(levelname)s %(message)s',
}
},
在示例中只設(shè)置了 levelname 和 message 兩個(gè)參數(shù),levelname 即為該日志消息的等級(jí),message為消息內(nèi)容
對于請求接口的 message 信息,返回的內(nèi)容是固定的,比如前面的示例:
"GET /blog/curr_time HTTP/1.1" 200 40
前面是接口的請求方式、接口路徑和HTTP協(xié)議,然后是接口返回的狀態(tài)碼,這里是 200,后面跟著的 40 這個(gè)數(shù)字則是接口返回的字符長度
如果是用戶在系統(tǒng)里手動(dòng)寫入的 message,則是定義的什么內(nèi)容,輸出的就是什么內(nèi)容
對于 format 的定義的參數(shù)還有很多,以下是幾個(gè)常用的匯總:
| 參數(shù)名稱 | 參數(shù)用法 | 含義 |
|---|---|---|
| levelname | %(levelname)s | 日志等級(jí) |
| message | %(message)s | 消息內(nèi)容 |
| asctime | %(asctime)s | 時(shí)間,格式為'2022-01-01 00:00:00,000' |
| pathname | %(pathname)s | 日志輸出所在文件的全路徑 |
| filename | %(filename)s | 日志輸出所在的文件名 |
| module | %(module)s | 日志輸出所在的模塊,可以理解成不帶后綴的文件名 |
| name | %(name)s | 調(diào)用日志使用的名稱,logging.getLogger(name)時(shí)為從模塊到函數(shù),比如 blog.views |
| funcName | %(funcName)s | 日志輸出的函數(shù)名稱 |
| lineno | %(lineno)d | 日志輸出所在的文件的行數(shù) |
| process | %(process)d | 進(jìn)程id |
| processName | %(processName)s | 進(jìn)程名稱 |
| thread | %(thread)d | 線程id |
| threadName | %(threadName)s | 線程名稱 |
10、指定 logger 輸出
之前我們設(shè)定的用戶手動(dòng)輸入的日志被傳送給了 key 為空字符串下的 logger,如果我們想把某一些日志信息專門輸出到某個(gè)文件怎么處理呢?
在獲取 logger 的時(shí)候就需要根據(jù) logger 的 key 來指定對應(yīng)的 logger,比如我們新建一個(gè)名為 custom 的 logger 和 對應(yīng)的 handler,然后輸出的地方指定即可,如下:
'custom': {
'handlers': ['custom_file'],
'level': 'INFO',
'propagate': False,
}
指定 logger 輸出:
import datetime
from django.http import HttpResponse
import logging
custom_logger = logging.getLogger("custom") # 對應(yīng) logging 配置中的 key 為 custom 的 logger
def time_view(request):
now = datetime.datetime.now()
html = "<h1>now: %s</h1>" % now
custom_logger.info("this is a custom log")
return HttpResponse(html)
這樣在對應(yīng)的地方就可以實(shí)現(xiàn)專門的日志輸出到專門的文件了。
11、日志配置示例
接下來我們實(shí)現(xiàn)這樣一個(gè)日志配置的功能:
- 實(shí)現(xiàn)用戶所有普通的手動(dòng)輸出都寫入一個(gè) manual.log 文件
- 所有接口的請求數(shù)據(jù)都輸入到一個(gè) request.log 文件
- 設(shè)置一個(gè)單獨(dú)的日志輸出,可以輸出到指定文件
- 所有 INFO 級(jí)別的日志都輸出到文件,高于 INFO 的都發(fā)送郵件通知指定聯(lián)系人
- 對于日志文件要求每個(gè)文件最大容量為 50M,且文件夾下每個(gè)類型的日志最多只有10個(gè)
- 日志的信息結(jié)構(gòu)為:日志等級(jí)-時(shí)間-日志輸出所在文件名-日志輸出所在函數(shù)名-日志輸出所在文件的行數(shù)-消息內(nèi)容
以下是實(shí)現(xiàn)上面這個(gè)功能的 logging 配置:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(filename)s %(funcName)s %(lineno)d %(message)s',
}
},
'handlers': {
'manual_file': {
'level': 'INFO',
'filename': '/Users/hunter/python/log_path/manual.log',
'formatter': 'verbose',
'class': 'logging.handlers.RotatingFileHandler',
'maxBytes': 5 * 1024 * 1024,
'backupCount': 10
},
'request_file': {
'level': 'INFO',
'filename': '/Users/hunter/python/log_path/request.log',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose',
'maxBytes': 5 * 1024 * 1024,
'backupCount': 10
},
'custom_file': {
'level': 'INFO',
'filename': '/Users/hunter/python/log_path/custom.log',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose',
'maxBytes': 5 * 1024 * 1024,
'backupCount': 10
},
'email': {
'level': 'WARNING',
'class': 'logging.handlers.SMTPHandler',
'mailhost': ('smtp.163.com', 25),
'fromaddr': 'xxxxxx@163.com',
'toaddrs': 'xxxxxxx@qq.com',
'subject': '系統(tǒng)出錯(cuò)啦!?。?,
'credentials': ('xxxxxx@163.com', 'JBD*******'),
'timeout': 20
},
},
'loggers': {
'': {
'handlers': ['manual_file', 'email'],
'level': 'INFO',
'propagate': False,
},
'django': {
'handlers': ['request_file'],
'level': 'INFO',
'propagate': True,
},
'custom': {
'handlers': ['custom_file'],
'level': 'INFO',
'propagate': False,
},
},
}
然后我們定義一個(gè)接口內(nèi)容:
import datetime
from django.http import HttpResponse, JsonResponse
import logging
logger = logging.getLogger(__name__)
custom_logger = logging.getLogger("custom")
def time_view(request):
now = datetime.datetime.now()
html = "<h1>now: %s</h1>abc\nabc" % now
logger.info("this is a log !")
custom_logger.info("this is a custom log")
logger.warning("報(bào)錯(cuò)啦?。。?)
return HttpResponse(html)
調(diào)用這個(gè)接口即可發(fā)現(xiàn)實(shí)現(xiàn)了我們想要的功能啦!
本文詳細(xì)介紹了Django中l(wèi)og日志記錄的基本概念和使用方法,包括如何配置log記錄器、如何設(shè)置log級(jí)別、如何記錄log信息等。同時(shí),本文還提供了一些最佳實(shí)踐,如如何避免log信息泄露、如何記錄異常信息等。通過本文的學(xué)習(xí),開發(fā)者可以更好地利用Django中的log日志記錄功能,提高應(yīng)用程序的可靠性和穩(wěn)定性。
到此這篇關(guān)于Django中l(wèi)og日志記錄的最佳實(shí)踐的文章就介紹到這了,更多相關(guān)Django中l(wèi)og日志記錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python scipy實(shí)現(xiàn)差分進(jìn)化算法
差分進(jìn)化算法是廣義的遺傳算法的一種,核心思想是變異,這篇文章主要為大家介紹的則是著名的scipy庫中對差分進(jìn)化算法的實(shí)現(xiàn),希望對大家有所幫助2023-08-08
Django DRF APIView源碼運(yùn)行流程詳解
這篇文章主要介紹了Django DRF APIView源碼運(yùn)行流程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
Python通過四大 AutoEDA 工具包快速產(chǎn)出完美數(shù)據(jù)報(bào)告
在三年前,我們做數(shù)據(jù)競賽或者數(shù)據(jù)建模類的項(xiàng)目時(shí),前期我們會(huì)耗費(fèi)較多的時(shí)間去分析數(shù)據(jù),但現(xiàn)在非常多擅長數(shù)據(jù)分析的大師們已經(jīng)將我們平時(shí)??吹臄?shù)據(jù)方式進(jìn)行了集成,開發(fā)了很多AutoEDA的工具包??梢詭椭覀児?jié)省大量時(shí)間2021-11-11
關(guān)于Python3爬蟲利器Appium的安裝步驟
在本篇文章里小編給大家整理的是一篇關(guān)于Python3爬蟲利器Appium的安裝步驟,需要的朋友們可以跟著參考下。2020-07-07
python簡單線程和協(xié)程學(xué)習(xí)心得(分享)
下面小編就為大家?guī)硪黄猵ython簡單線程和協(xié)程學(xué)習(xí)心得(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
Ruby使用eventmachine為HTTP服務(wù)器添加文件下載功能
這篇文章主要介紹了Ruby使用eventmachine為HTTP服務(wù)器添加文件下載功能的實(shí)例,同時(shí)作者也分享了Windows上eventmachine安裝報(bào)錯(cuò)問題的解決方法,需要的朋友可以參考下2016-04-04
Python連接PostgreSQL數(shù)據(jù)庫并查詢數(shù)據(jù)的詳細(xì)指南
在現(xiàn)代軟件開發(fā)中,數(shù)據(jù)庫是存儲(chǔ)和檢索數(shù)據(jù)的核心組件,PostgreSQ是一個(gè)功能強(qiáng)大的開源對象關(guān)系數(shù)據(jù)庫系統(tǒng),它以其穩(wěn)定性、強(qiáng)大的功能和靈活性而聞名,Python作為一種流行的編程語言,與PostgreSQL的結(jié)合使用非常廣泛,本文介紹了Python連接PostgreSQL數(shù)據(jù)庫并查詢數(shù)據(jù)2024-12-12
Python GUI教程之在PyQt5中使用數(shù)據(jù)庫的方法
Qt平臺(tái)對SQL編程有著良好的支持,PyQt5也一并繼承了過來,這篇文章主要介紹了Python GUI教程之在PyQt5中使用數(shù)據(jù)庫的方法,需要的朋友可以參考下2021-09-09

