亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

python中的log日志多線程安全

 更新時(shí)間:2023年08月15日 08:38:15   作者:peach_orange  
這篇文章主要介紹了python中的log日志多線程安全,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

python log日志多線程安全

python中的日志文件為logger,常用的有兩個(gè)-RotatingFileHandler;TimedRotatingFileHandler。

文件沒滿足分割條件前,保存在‘info.log’(自己命名的文件)中,如果滿足分割條件,會生成‘info.log.1’。

下一次滿足分割條件后,將‘info.log’保存成‘info.log.1’,而‘info.log.1’順延成‘info.log.2’;滿足最多保存的個(gè)數(shù)后,會將其刪掉。

RotatingFileHandler,是按大小劃分日志文件,使用方法如下。

RotatingFileHandler是按文件大小自動分割保存,下文中設(shè)置的是1M保存一個(gè)文件,最多保存30個(gè)。

此種方式支持多線程安全,支持軟件的開關(guān)機(jī)(TimedRotatingFileHandler不支持,一旦關(guān)機(jī),會重新計(jì)時(shí))

import logging
from logging import handlers
def log_init():
? ? log = logging.getLogger('error.log') ? ? ? ? ? ?# log保存位置
? ? format_str = log.Formatter('%(asctime)s - \ ? ? # log時(shí)間戳格式
? ? ? ? %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') ? ? ? ? ? ? ? ? ? ? ? ??
? ? log.setLevel(logging.DEBUG) ? ? ? ? ? ? ? ? ? ? # log日志等級(往下的內(nèi)容不保存)
? ? sh = logging.StreamHandler() ? ? ? ? ? ? ? ? ? ?# 往屏幕上輸出
? ? # filename:log文件名;maxBytes:超過最大尺寸,log會另存一個(gè)文件;
? ? # backupCount:最多保存多少個(gè)日志;encoding:保存編碼格式
? ? th = handlers.RotatingFileHandler(filename='error.log', maxBytes=1024*1024, \
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? backupCount=30, encoding='uft-8') ? ? ? ?
? ? th.setFormatter(format_str) ? ? ? ? ? ? ? ? ? ? # 設(shè)置文件里寫入的格式
? ? log.addHandler(sh)
? ? log.addHandler(th)
? ? return log
if __name__ == '__main__':
? ? log = log_init()
? ? log.debug('debug_msg')
? ? log.info('info_msg')
? ? log.warning('warning_msg')
? ? log.error('error_msg')
? ? log.critical('critical_msg')

TimedRotatingFileHandler是按日期劃分日志文件,使用方法如下。

TimedRotatingFileHandler是按文件大小自動分割保存,下文中設(shè)置的是每天保存一個(gè)log文件,最多保存30個(gè)。

此種方式支持多線程不安全,不支持軟件的關(guān)機(jī)(軟件關(guān)機(jī)后,會重新計(jì)時(shí),如果經(jīng)常關(guān)機(jī)的項(xiàng)目,會只記錄在一個(gè)文件中)。

import logging
from logging import handlers
def log_init():
? ? log = logging.getLogger('error.log') ? ? ? ? ? ?# log保存位置
? ? format_str = log.Formatter('%(asctime)s - \ ? ? # log時(shí)間戳格式
? ? ? ? %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') ? ? ? ? ? ? ? ? ? ? ? ??
? ? log.setLevel(logging.DEBUG) ? ? ? ? ? ? ? ? ? ? # log日志等級(往下的內(nèi)容不保存)
? ? sh = logging.StreamHandler() ? ? ? ? ? ? ? ? ? ?# 往屏幕上輸出
? ? # filename:log文件名;when:多久另存一個(gè)文件(S/M/H/D/W/midnight);
? ? # backupCount:最多保存多少個(gè)日志;encoding:保存編碼格式
? ? th = handlers.TimedRotatingFileHandler(filename='error.log', when='D', \
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? backupCount=30, encoding='uft-8') ? ? ? ?
? ? th.setFormatter(format_str) ? ? ? ? ? ? ? ? ? ? # 設(shè)置文件里寫入的格式
? ? log.addHandler(sh)
? ? log.addHandler(th)
? ? return log
if __name__ == '__main__':
? ? log = log_init()
? ? log.debug('debug_msg')
? ? log.info('info_msg')
? ? log.warning('warning_msg')
? ? log.error('error_msg')
? ? log.critical('critical_msg')

如果想多線程使用TimedRotatingFileHandler,就需要自己寫一個(gè)線程,然后每一個(gè)log往消息隊(duì)列中丟,用線程處理這個(gè)消息隊(duì)列。

Queue是線程安全的,所以作為消息隊(duì)列使用沒有影響。

import time
import _thread
import logging
from logging import handlers
from queue import Queue
logs_queue = Queue()
class LogMsg(object):
? ? def __init__(self, type, msg):
? ? ? ? self._type = type
? ? ? ? self._msg = msg
def log_init():
? ? log = logging.getLogger('error.log') ? ? ? ? ? ?# log保存位置
? ? format_str = log.Formatter('%(asctime)s - \ ? ? # log時(shí)間戳格式
? ? ? ? %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') ? ? ? ? ? ? ? ? ? ? ? ??
? ? log.setLevel(logging.DEBUG) ? ? ? ? ? ? ? ? ? ? # log日志等級(往下的內(nèi)容不保存)
? ? sh = logging.StreamHandler() ? ? ? ? ? ? ? ? ? ?# 往屏幕上輸出
? ? # filename:log文件名;when:多久另存一個(gè)文件(S/M/H/D/W/midnight);
? ? # backupCount:最多保存多少個(gè)日志;encoding:保存編碼格式
? ? th = handlers.TimedRotatingFileHandler(filename='error.log', when='D', \
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? backupCount=30, encoding='uft-8') ? ? ? ?
? ? th.setFormatter(format_str) ? ? ? ? ? ? ? ? ? ? # 設(shè)置文件里寫入的格式
? ? log.addHandler(sh)
? ? log.addHandler(th)
? ? return log
def cop_log_queue(logger):
? ? while True:
? ? ? ? if logs_queue.empty():
? ? ? ? ? ?time.sleep(1)
? ? ? ? log_msg = logs_queue.get()
? ? ? ? if log_msg._type == 'debug':
? ? ? ? ? ? logger.debug(log_msg._msg)
? ? ? ? elif log_msg._type == 'info':
? ? ? ? ? ? logger.info(log_msg._msg)
? ? ? ? elif log_msg._type == 'warning':
? ? ? ? ? ? logger.warning(log_msg._msg)
? ? ? ? elif log_msg._type == 'error':
? ? ? ? ? ? logger.error(log_msg._msg)
? ? ? ? elif log_msg._type == 'critical':
? ? ? ? ? ? logger.critical(log_msg._msg)
def error_thread1():
? ? while True:
? ? ? ? logs_queue.put(LogMsg('debug','debug_msg'))
? ? ? ? time.sleep(1)
def error_thread2():
? ? while True:
? ? ? ? logs_queue.put(LogMsg('info','info_msg'))
? ? ? ? time.sleep(1)
if __name__ == '__main__':
? ? logger = log_init()
? ? _thread.start_new_thread(cope_log_queue, (logger, ))
? ? _thread.start_new_thread(error_thread1, ())
? ? _thread.start_new_thread(error_thread2, ())

python之log日志

記錄程序日志信息的目的是

  • 可以很方便的了解程序的運(yùn)行情況
  • 可以分析用戶的操作行為、喜好等信息
  • 方便開發(fā)人員檢查bug

logging日志級別介紹

日志等級可以分為5個(gè),從低到高分別是:

  • DEBUG
  • INFO
  • WARNING
  • ERROR
  • CRITICAL

日志等級說明:

  • DEBUG:程序調(diào)試bug時(shí)使用
  • INFO:程序正常運(yùn)行時(shí)使用
  • WARNING:程序未按預(yù)期運(yùn)行時(shí)使用,但并不是錯(cuò)誤,如:用戶登錄密碼錯(cuò)誤
  • ERROR:程序出錯(cuò)誤時(shí)使用,如:IO操作失敗
  • CRITICAL:特別嚴(yán)重的問題,導(dǎo)致程序不能再繼續(xù)運(yùn)行時(shí)使用,如:磁盤空間為空,一般很少使用
  • 默認(rèn)的是WARNING等級,當(dāng)在WARNING或WARNING之上等級的才記錄日志信息。
  • 日志等級從低到高的順序是: DEBUG < INFO < WARNING < ERROR < CRITICAL

logging日志的使用

在 logging 包中記錄日志的方式有兩種:

  • 輸出到控制臺
  • 保存到日志文件

日志信息輸出到控制臺的示例代碼:

import logging
logging.debug('這是一個(gè)debug級別的日志信息')
logging.info('這是一個(gè)info級別的日志信息')
logging.warning('這是一個(gè)warning級別的日志信息')
logging.error('這是一個(gè)error級別的日志信息')
logging.critical('這是一個(gè)critical級別的日志信息')

運(yùn)行結(jié)果:

WARNING:root:這是一個(gè)warning級別的日志信息
ERROR:root:這是一個(gè)error級別的日志信息
CRITICAL:root:這是一個(gè)critical級別的日志信息

說明:

日志信息只顯示了大于等于WARNING級別的日志,這說明默認(rèn)的日志級別設(shè)置為WARNING

logging日志等級和輸出格式的設(shè)置:

import logging
# 設(shè)置日志等級和輸出日志格式
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
logging.debug('這是一個(gè)debug級別的日志信息')
logging.info('這是一個(gè)info級別的日志信息')
logging.warning('這是一個(gè)warning級別的日志信息')
logging.error('這是一個(gè)error級別的日志信息')
logging.critical('這是一個(gè)critical級別的日志信息')

運(yùn)行結(jié)果:

2019-02-13 20:41:33,080 - hello.py[line:6] - DEBUG: 這是一個(gè)debug級別的日志信息
2019-02-13 20:41:33,080 - hello.py[line:7] - INFO: 這是一個(gè)info級別的日志信息
2019-02-13 20:41:33,080 - hello.py[line:8] - WARNING: 這是一個(gè)warning級別的日志信息
2019-02-13 20:41:33,080 - hello.py[line:9] - ERROR: 這是一個(gè)error級別的日志信息
2019-02-13 20:41:33,080 - hello.py[line:10] - CRITICAL: 這是一個(gè)critical級別的日志信息

代碼說明:

  • level 表示設(shè)置的日志等級
  • format 表示日志的輸出格式, 參數(shù)說明:
  • %(levelname)s: 打印日志級別名稱
  • %(filename)s: 打印當(dāng)前執(zhí)行程序名
  • %(lineno)d: 打印日志的當(dāng)前行號
  • %(asctime)s: 打印日志的時(shí)間
  • %(message)s: 打印日志信息

日志信息保存到日志文件的示例代碼:

import logging
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
                    filename="log.txt",
                    filemode="w")
logging.debug('這是一個(gè)debug級別的日志信息')
logging.info('這是一個(gè)info級別的日志信息')
logging.warning('這是一個(gè)warning級別的日志信息')
logging.error('這是一個(gè)error級別的日志信息')
logging.critical('這是一個(gè)critical級別的日志信息')

 會在此目錄中自動生成log.txt文件,生成日志數(shù)據(jù)

運(yùn)行結(jié)果:

2022-01-15 11:31:14,529 - web.py[line:59] - INFO: 動態(tài)資源請求:/index.html
2022-01-15 11:31:22,542 - web.py[line:63] - INFO: 靜態(tài)資源請求:/df
2022-01-15 11:46:14,034 - web.py[line:60] - INFO: 動態(tài)資源請求:/index.html
2022-01-15 11:46:14,036 - web.py[line:60] - INFO: 動態(tài)資源請求:/index.html
2022-01-15 11:47:24,065 - web.py[line:60] - INFO: 動態(tài)資源請求:/index.html
2022-01-15 11:47:26,655 - web.py[line:60] - INFO: 動態(tài)資源請求:/index.html
2022-01-15 11:47:45,224 - web.py[line:75] - INFO: 靜態(tài)資源請求:/favicon.ico
2022-01-15 11:52:15,723 - web.py[line:60] - INFO: 動態(tài)資源請求:/index.html
2022-01-15 11:52:23,513 - web.py[line:60] - INFO: 動態(tài)資源請求:/index.html
2022-01-15 11:52:31,315 - web.py[line:60] - INFO: 動態(tài)資源請求:/index.html
2022-01-15 11:52:36,838 - web.py[line:75] - INFO: 靜態(tài)資源請求:/favicon.ico

logging日志在mini-web項(xiàng)目中應(yīng)用

web.py 程序使用logging日志示例:

1.程序入口模塊設(shè)置logging日志的設(shè)置

 import socket
 import threading
 import sys
 import framework
 import logging
 # logging日志的配置
 logging.basicConfig(level=logging.DEBUG,
                     format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
                     filename="log.txt",
                     filemode="w")

2.INFO級別的日志輸出,示例代碼:

 # 判斷是否是動態(tài)資源請求
 if request_path.endswith(".html"):
     """這里是動態(tài)資源請求,把請求信息交給框架處理"""
     logging.info("動態(tài)資源請求:" + request_path)
     ...
 else:
     """這里是靜態(tài)資源請求"""
     logging.info("靜態(tài)資源請求:" + request_path)
     ...

3.WARNING級別的日志輸出,示例代碼:

 # 獲取命令行參數(shù)判斷長度
 if len(sys.argv) != 2:
     print("執(zhí)行命令如下: python3 xxx.py 9000")
     logging.warning("用戶在命令行啟動程序參數(shù)個(gè)數(shù)不正確!")
     return
 # 判斷端口號是否是數(shù)字
 if not sys.argv[1].isdigit():
     print("執(zhí)行命令如下: python3 xxx.py 9000")
     logging.warning("用戶在命令行啟動程序參數(shù)不是數(shù)字字符串!")
     return

framework.py 程序使用logging日志示例:

ERROR級別的日志輸出,示例代碼:

 # 處理動態(tài)資源請求
 def handle_request(env):
     # 獲取動態(tài)請求資源路徑
     request_path = env["request_path"]
     print("接收到的動態(tài)資源請求:", request_path)
     # 遍歷路由列表,選擇執(zhí)行的函數(shù)
     for path, func in route_list:
         if request_path == path:
             result = func()
             return result
     else:
         logging.error("沒有設(shè)置相應(yīng)的路由:" + request_path)
         # 沒有找到動態(tài)資源
         result = not_found()
         return result

說明:

  • logging日志配置信息在程序入口模塊設(shè)置一次,整個(gè)程序都可以生效。
  • logging.basicConfig 表示 logging 日志配置操作

小結(jié)

記錄python程序中日志信息使用 logging 包來完成

logging日志等級有5個(gè):

  • DEBUG
  • INFO
  • WARNING
  • ERROR
  • CRITICAL

打印(記錄)日志的函數(shù)有5個(gè):

  • logging.debug函數(shù), 表示: 打印(記錄)DEBUG級別的日志信息
  • logging.info函數(shù), 表示: 打印(記錄)INFO級別的日志信息
  • logging.warning函數(shù), 表示: 打印(記錄)WARNING級別的日志信息
  • logging.error函數(shù), 表示: 打印(記錄)ERROR級別的日志信息
  • logging.critical函數(shù), 表示: 打印(記錄)CRITICAL級別的日志信息

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論