欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python中的log日志多線程安全

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

python log日志多線程安全

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

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

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

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

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

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

import logging
from logging import handlers
def log_init():
? ? log = logging.getLogger('error.log') ? ? ? ? ? ?# log保存位置
? ? format_str = log.Formatter('%(asctime)s - \ ? ? # log時間戳格式
? ? ? ? %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') ? ? ? ? ? ? ? ? ? ? ? ??
? ? log.setLevel(logging.DEBUG) ? ? ? ? ? ? ? ? ? ? # log日志等級(往下的內(nèi)容不保存)
? ? sh = logging.StreamHandler() ? ? ? ? ? ? ? ? ? ?# 往屏幕上輸出
? ? # filename:log文件名;maxBytes:超過最大尺寸,log會另存一個文件;
? ? # backupCount:最多保存多少個日志;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è)置的是每天保存一個log文件,最多保存30個。

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

import logging
from logging import handlers
def log_init():
? ? log = logging.getLogger('error.log') ? ? ? ? ? ?# log保存位置
? ? format_str = log.Formatter('%(asctime)s - \ ? ? # log時間戳格式
? ? ? ? %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') ? ? ? ? ? ? ? ? ? ? ? ??
? ? log.setLevel(logging.DEBUG) ? ? ? ? ? ? ? ? ? ? # log日志等級(往下的內(nèi)容不保存)
? ? sh = logging.StreamHandler() ? ? ? ? ? ? ? ? ? ?# 往屏幕上輸出
? ? # filename:log文件名;when:多久另存一個文件(S/M/H/D/W/midnight);
? ? # backupCount:最多保存多少個日志;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,就需要自己寫一個線程,然后每一個log往消息隊列中丟,用線程處理這個消息隊列。

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

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時間戳格式
? ? ? ? %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') ? ? ? ? ? ? ? ? ? ? ? ??
? ? log.setLevel(logging.DEBUG) ? ? ? ? ? ? ? ? ? ? # log日志等級(往下的內(nèi)容不保存)
? ? sh = logging.StreamHandler() ? ? ? ? ? ? ? ? ? ?# 往屏幕上輸出
? ? # filename:log文件名;when:多久另存一個文件(S/M/H/D/W/midnight);
? ? # backupCount:最多保存多少個日志;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日志

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

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

logging日志級別介紹

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

  • DEBUG
  • INFO
  • WARNING
  • ERROR
  • CRITICAL

日志等級說明:

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

logging日志的使用

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

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

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

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

運行結(jié)果:

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

說明:

日志信息只顯示了大于等于WARNING級別的日志,這說明默認的日志級別設(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('這是一個debug級別的日志信息')
logging.info('這是一個info級別的日志信息')
logging.warning('這是一個warning級別的日志信息')
logging.error('這是一個error級別的日志信息')
logging.critical('這是一個critical級別的日志信息')

運行結(jié)果:

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

代碼說明:

  • level 表示設(shè)置的日志等級
  • format 表示日志的輸出格式, 參數(shù)說明:
  • %(levelname)s: 打印日志級別名稱
  • %(filename)s: 打印當(dāng)前執(zhí)行程序名
  • %(lineno)d: 打印日志的當(dāng)前行號
  • %(asctime)s: 打印日志的時間
  • %(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('這是一個debug級別的日志信息')
logging.info('這是一個info級別的日志信息')
logging.warning('這是一個warning級別的日志信息')
logging.error('這是一個error級別的日志信息')
logging.critical('這是一個critical級別的日志信息')

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

運行結(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項目中應(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ù)個數(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è)置一次,整個程序都可以生效。
  • logging.basicConfig 表示 logging 日志配置操作

小結(jié)

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

logging日志等級有5個:

  • DEBUG
  • INFO
  • WARNING
  • ERROR
  • CRITICAL

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

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

總結(jié)

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

相關(guān)文章

  • Python 腳本實現(xiàn)淘寶準點秒殺功能

    Python 腳本實現(xiàn)淘寶準點秒殺功能

    這篇文章主要介紹了python實現(xiàn)淘寶準點秒殺腳本,本文圖文實例相結(jié)合給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • python實現(xiàn)百度關(guān)鍵詞排名查詢

    python實現(xiàn)百度關(guān)鍵詞排名查詢

    這篇文章主要介紹了python實現(xiàn)百度關(guān)鍵詞排名查詢,需要的朋友可以參考下
    2014-03-03
  • python三引號如何輸入

    python三引號如何輸入

    在本篇文章里小編給大家整理的是關(guān)于python三引號輸入方法及相關(guān)實例,需要的朋友們可以學(xué)習(xí)下。
    2020-07-07
  • python 使用多線程創(chuàng)建一個Buffer緩存器的實現(xiàn)思路

    python 使用多線程創(chuàng)建一個Buffer緩存器的實現(xiàn)思路

    這篇文章主要介紹了python 使用多線程創(chuàng)建一個Buffer緩存器的實現(xiàn)思路,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • python 抓取知乎指定回答下視頻的方法

    python 抓取知乎指定回答下視頻的方法

    這篇文章主要介紹了python 抓取知乎指定回答下視頻的方法,文中講解非常詳細,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • python算法測試結(jié)果自動保存到excel表格的實現(xiàn)步驟

    python算法測試結(jié)果自動保存到excel表格的實現(xiàn)步驟

    我們在進行算法評估是通常會針對每個樣本的算法處理結(jié)果進行統(tǒng)計,例如每個樣本正確預(yù)測數(shù)量、漏檢數(shù)量和誤檢數(shù)量、精度等,本文小編將給大家介紹python算法測試結(jié)果自動保存到excel表格的實現(xiàn)步驟,感興趣的朋友可以參考下
    2023-12-12
  • Python遞歸函數(shù)返回值為None問題及解決

    Python遞歸函數(shù)返回值為None問題及解決

    文章主要討論了在Python中使用遞歸函數(shù)時可能出現(xiàn)的問題,特別是遞歸函數(shù)的返回值不符合預(yù)期的情況,文章通過一個具體的例子說明了這個問題,并解釋了如何通過在遞歸調(diào)用時加上return語句來解決這個問題
    2024-11-11
  • python導(dǎo)出requirements.txt的幾種方法以及環(huán)境配置詳細流程

    python導(dǎo)出requirements.txt的幾種方法以及環(huán)境配置詳細流程

    這篇文章主要給大家介紹了關(guān)于python導(dǎo)出requirements.txt的幾種方法以及環(huán)境配置詳細流程,requirements.txt 文件是一個文本文件,用于列出你的Python項目所依賴的軟件包及其版本,需要的朋友可以參考下
    2023-11-11
  • python如何編寫win程序

    python如何編寫win程序

    在本篇文章里小編給大家分享的是關(guān)于python編寫win程序的實例內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。
    2020-06-06
  • python判斷列表字典字符串元組是否存在某個值或者空值(多種方法)

    python判斷列表字典字符串元組是否存在某個值或者空值(多種方法)

    這篇文章主要介紹了python判斷列表字典字符串元組是否存在某個值或者空值,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-02-02

最新評論