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

Python logging日志模塊 配置文件方式

 更新時間:2020年07月12日 09:55:49   作者:小恩阿  
這篇文章主要介紹了Python logging日志模塊 配置文件方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

在一些微服務或web服務中我們難免需要日志功能,用來記錄一些用戶的登錄記錄,操作記錄,以及一些程序的崩潰定位,執(zhí)行訪問定位等等;

Python內置 非常強大的日志模塊 ==> logging 今天給大家分享一下以配置文件形式進行配置log日志 ;

Centos6.7

Python3.6

logging0.5.1.2

logging模塊有三個比較重要的功能組件:

1、loggers 配置文件可定義一些輸出日志的appname

2、handler 過濾器,比如設置日志的分隔大小,輸出位置,日志文件創(chuàng)建等

3、formatters 指定日志輸出的格式

1: 創(chuàng)建一個文件,以.conf結尾 或以.ini結尾(PS: 其他的結尾沒試過,你可以試試)

vim log.conf

2: 定義日志輸出的APP名,指定過濾器這里用loggers功能

[loggers]        #固定寫法
keys=root,error,info  #創(chuàng)建三個app名,root是父類,必需存在的

[logger_root]      #創(chuàng)建完的app名我們要定義一些規(guī)則,嚴格要求格式為"logger_appname"
level=DEBUG       #設置日志級別
qualname=root      #這里在"root"appname下可以不填,所有沒獲取get的情況下默認app名都是root
handlers=debugs     #設置指定過濾器,多個以逗號分隔,這個名字待會兒 我們會以固定格式"handler_(value)"創(chuàng)建

[logger_error]
level=ERROR
qualname=error     #除了root appname以外,定義的app名必須要設置這個屬性,用于定義打印輸出時候的app名
handlers=errors

[logger_info]
level=INFO
qualname=INFO
handlers=infos

3: 定義日志過濾器這里用handler功能

[handlers]         #固定格式
keys=infos,errors,debugs  #定義過濾器名稱,下面定義以handler_keysname格式定義,上面引用名稱必須和keys一致

[handler_infos]       
class=FileHandler      #指定過濾器組件,詳情請看官網(wǎng),這個是以文件方式創(chuàng)建
level=INFO         #設置級別
formatter=form01      #定義日志打印格式,下面會創(chuàng)建formatters,格式也是嚴格要求formatter_keysname 創(chuàng)建
args=('info.log','a')    #創(chuàng)建文件名字,以什么方式打開

[handler_errors] 
class=FileHandler
level=DEBUG
formatter=form02
args=('info1.log','a')

[handler_debugs] 
class=FileHandler
level=DEBUG
formatter=form02
args=('info1.log','a')

3: 定義日志輸出格式,這里我們介紹最后一個組件formatters

[formatters]      #固定格式
keys=form01,form02   #定義名稱,下面會引用格式同上

[formatter_form01]
format=%(asctime)s %(filename)s %(levelname)s %(message)s #年-月-日 時-分-秒,毫秒,文件名,級別名,消息信息
datefmt=%Y-%m-%d %H:%M:%S  #日期輸出格式

[formatter_form02]
format=%(asctime)s %(filename)s %(levelname)s %(message)s
datefmt=%Y-%m-%d %H:%M:%S

4: 具體程序引用

#!/usr/bin/env python
import logging 
import logging.config 
logging.config.fileConfig('log.conf')

logs = logging.getLogger('error')
logs.error('errorsssss')

補充知識:python按照日志等級將日志輸出至不同的日志文件

將日志按照等級分別保存在不同的文件中,并在控制臺同步輸出。

import os
import sys
import logging
from logs.multiprocessloghandler import MultiprocessHandler

def loggerDefine(platform, log_name):
  base_dir = "F:\PythonProject\\xiao_new_resources\logs"

  info_dir_path = base_dir + "\\info\\{}".format(platform)
  error_dir_path = base_dir + "\\error\\{}".format(platform)

  # 判斷響應的文件是否存在
  if not os.path.exists(info_dir_path):
    os.makedirs(info_dir_path)
  info_dir = os.path.join(info_dir_path, log_name)

  if not os.path.exists(error_dir_path):
    os.makedirs(error_dir_path)
  error_dir = os.path.join(error_dir_path, log_name)

  # 返回一個logger對象,如果沒有指定名字將返回root logger
  log = logging.getLogger('test')

  # 定義日志輸出格式
  formattler = '%(asctime)s|%(processName)s|%(threadName)s|%(levelname)s|%(filename)s:%(lineno)d|%(funcName)s|%(message)s'
  fmt = logging.Formatter(formattler)

  # 設置日志控制臺輸出
  stream_handler = logging.StreamHandler(sys.stdout)
  stream_handler.setLevel(logging.INFO)

  # 設置控制臺文件輸出
  log_handler_info = MultiprocessHandler(info_dir)
  log_handler_err = MultiprocessHandler(error_dir)

  # 設置日志輸出格式:
  stream_handler.setFormatter(fmt)
  log_handler_info.setFormatter(fmt)
  log_handler_err.setFormatter(fmt)

  # 設置過濾條件
  info_filter = logging.Filter()
  info_filter.filter = lambda record: record.levelno < logging.WARNING # 設置過濾等級
  err_filter = logging.Filter()
  err_filter.filter = lambda record: record.levelno >= logging.WARNING

  # 對文件輸出日志添加過濾條件
  log_handler_info.addFilter(info_filter)
  log_handler_err.addFilter(err_filter)

  # 對logger增加handler日志處理器
  log.addHandler(log_handler_info)
  log.addHandler(log_handler_err)
  log.addHandler(stream_handler)

  log.setLevel("INFO")
  return log

if __name__ == '__main__':
  logg = loggerDefine("youtube", "youtube.log")
  logg.info("info")
  logg.warning("warning")
  logg.error("error")

multiprocessloghandler源碼:

import datetime
import logging
import os
import re

try:
  import codecs
except ImportError:
  codecs = None

class MultiprocessHandler(logging.FileHandler):
  """支持多進程的TimedRotatingFileHandler"""

  def __init__(self, filename, when='D', backupCount=7, encoding="utf-8", delay=False):
    """
    filename 日志文件名,when 時間間隔的單位,backupCount 保留文件個數(shù)
    delay 是否開啟 OutSteam緩存
    True 表示開啟緩存,OutStream輸出到緩存,待緩存區(qū)滿后,刷新緩存區(qū),并輸出緩存數(shù)據(jù)到文件。
    False表示不緩存,OutStrea直接輸出到文件
    """
    self.prefix = filename
    self.backupCount = backupCount
    self.when = when.upper()
    # 正則匹配 年-月-日
    # 正則寫到這里就對了
    self.extMath = r"\d{4}-\d{2}-\d{2}"

    # S 每秒建立一個新文件
    # M 每分鐘建立一個新文件
    # H 每天建立一個新文件
    # D 每天建立一個新文件
    self.when_dict = {
      'S': "%Y-%m-%d-%H-%M-%S",
      'M': "%Y-%m-%d-%H-%M",
      'H': "%Y-%m-%d-%H",
      'D': "%Y-%m-%d"
    }
    # 日志文件日期后綴
    self.suffix = self.when_dict.get(when)
    # 源碼中self.extMath寫在這里
    # 這個正則匹配不應該寫到這里,不然非D模式下 會造成 self.extMath屬性不存在的問題
    # 不管是什么模式都是按照這個正則來搜索日志文件的。
    # if self.when == 'D':
    #  正則匹配 年-月-日
    #  self.extMath = r"^\d{4}-\d{2}-\d{2}"
    if not self.suffix:
      raise ValueError(u"指定的日期間隔單位無效: %s" % self.when)
    # 拼接文件路徑 格式化字符串
    self.filefmt = os.path.join(os.getcwd(), "%s.%s" % (self.prefix, self.suffix))
    a = "%s.%s" % (self.prefix, self.suffix)
    # 使用當前時間,格式化文件格式化字符串
    self.filePath = datetime.datetime.now().strftime(self.filefmt)
    # 獲得文件夾路徑
    _dir = os.path.dirname(self.filefmt)
    try:
      # 如果日志文件夾不存在,則創(chuàng)建文件夾
      if not os.path.exists(_dir):
        os.makedirs(_dir)
    except Exception:
      print("創(chuàng)建文件夾失敗")
      print("文件夾路徑:" + self.filePath)
      pass
    if codecs is None:
      encoding = None
      # 調用FileHandler
    logging.FileHandler.__init__(self, self.filePath, 'a+', encoding, delay)

  def shouldChangeFileToWrite(self):
    """更改日志寫入目的寫入文件
    return True 表示已更改,F(xiàn)alse 表示未更改"""
    # 以當前時間獲得新日志文件路徑
    _filePath = datetime.datetime.now().strftime(self.filefmt)
    # 新日志文件日期 不等于 舊日志文件日期,則表示 已經(jīng)到了日志切分的時候
    #  更換日志寫入目的為新日志文件。
    # 例如 按 天 (D)來切分日志
    #  當前新日志日期等于舊日志日期,則表示在同一天內,還不到日志切分的時候
    #  當前新日志日期不等于舊日志日期,則表示不在
    # 同一天內,進行日志切分,將日志內容寫入新日志內。
    if _filePath != self.filePath:
      self.filePath = _filePath
      return True
    return False

  def doChangeFile(self):
    """輸出信息到日志文件,并刪除多于保留個數(shù)的所有日志文件"""
    # 日志文件的絕對路徑
    self.baseFilename = os.path.abspath(self.filePath)
    # stream == OutStream
    # stream is not None 表示 OutStream中還有未輸出完的緩存數(shù)據(jù)
    if self.stream:
      # self.stream.flush()
      self.stream.close()
      self.stream = None
    # delay 為False 表示 不OutStream不緩存數(shù)據(jù) 直接輸出
    #  所有,只需要關閉OutStream即可
    if not self.delay:
      # self.stream.close()
      self.stream = self._open()

    # 刪除多于保留個數(shù)的所有日志文件
    if self.backupCount > 0:
      for s in self.getFilesToDelete():
        # print s
        os.remove(s)

  def getFilesToDelete(self):
    """獲得過期需要刪除的日志文件"""
    # 分離出日志文件夾絕對路徑
    # split返回一個元組(absFilePath,fileName)
    # 例如:split('I:\ScripPython\char4\mybook\util\logs\mylog.2017-03-19)
    # 返回(I:\ScripPython\char4\mybook\util\logs, mylog.2017-03-19)
    # _ 表示占位符,沒什么實際意義,
    dirName, _ = os.path.split(self.baseFilename)
    fileNames = os.listdir(dirName)
    result = []
    # self.prefix 為日志文件名 列如:mylog.2017-03-19 中的 mylog
    # 加上 點號 . 方便獲取點號后面的日期
    prefix = self.prefix
    prefix = _.rsplit(".", 1)[0] + "."
    plen = len(prefix)
    for fileName in fileNames:
      if fileName[:plen] == prefix:
        # 日期后綴 mylog.2017-03-19 中的 2017-03-19
        suffix = fileName[plen:]
        # 匹配符合規(guī)則的日志文件,添加到result列表中
        if re.compile(self.extMath).match(suffix):
          result.append(os.path.join(dirName, fileName))
    result.sort()

    # 返回 待刪除的日志文件
    #  多于 保留文件個數(shù) backupCount的所有前面的日志文件。
    if len(result) < self.backupCount:
      result = []
    else:
      result = result[:len(result) - self.backupCount]
    return result

  def emit(self, record):
    """發(fā)送一個日志記錄
    覆蓋FileHandler中的emit方法,logging會自動調用此方法"""
    try:
      if self.shouldChangeFileToWrite():
        self.doChangeFile()
      logging.FileHandler.emit(self, record)
    except (KeyboardInterrupt, SystemExit):
      raise
    except:
      self.handleError(record)

以上這篇Python logging日志模塊 配置文件方式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • pandas如何修改某一列的數(shù)據(jù)

    pandas如何修改某一列的數(shù)據(jù)

    這篇文章主要介紹了pandas如何修改某一列的數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • python實現(xiàn)微信自動回復機器人功能

    python實現(xiàn)微信自動回復機器人功能

    wxpy基于itchat,使用了 Web 微信的通訊協(xié)議,通過大量接口優(yōu)化提升了模塊的易用性,并進行豐富的功能擴展。這篇文章主要介紹了python實現(xiàn)微信自動回復機器人功能,需要的朋友可以參考下
    2019-07-07
  • Python字符串和其常用函數(shù)合集

    Python字符串和其常用函數(shù)合集

    這篇文章主要給大介紹Python字符串和分享其常用函數(shù)合集,字符串、首字母大寫定義、所有字母大寫、所有字母小寫等函數(shù),具有一定的參考價值,需要的朋友可以參考一下
    2022-03-03
  • 詳解pyqt5 動畫在QThread線程中無法運行問題

    詳解pyqt5 動畫在QThread線程中無法運行問題

    這篇文章主要介紹了詳解pyqt5 動畫在QThread線程中無法運行問題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Python import模塊的緩存問題解決方案

    Python import模塊的緩存問題解決方案

    這篇文章主要介紹了Python import模塊的緩存問題解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • tensorflow指定GPU與動態(tài)分配GPU memory設置

    tensorflow指定GPU與動態(tài)分配GPU memory設置

    今天小編就為大家分享一篇tensorflow指定GPU與動態(tài)分配GPU memory設置,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • pandas分組聚合詳解

    pandas分組聚合詳解

    這篇文章主要介紹了pandas分組聚合詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Python用matplotlib庫畫圖中文和負號顯示為方框的問題解決

    Python用matplotlib庫畫圖中文和負號顯示為方框的問題解決

    matplotlib中畫圖的時候會遇到負號顯示為方框的問題,下面這篇文章主要給大家介紹了關于Python用matplotlib庫畫圖中文和負號顯示為方框的問題解決,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • Python下使用Psyco模塊優(yōu)化運行速度

    Python下使用Psyco模塊優(yōu)化運行速度

    這篇文章主要介紹了Python下使用Psyco模塊優(yōu)化運行速度,Psyco模塊可以使你的Python程序運行的像C語言一樣快,本文給出了多個代碼示例,并講解了Psyco的安裝和使用方法,需要的朋友可以參考下
    2015-04-04
  • python爬蟲獲取京東手機圖片的圖文教程

    python爬蟲獲取京東手機圖片的圖文教程

    下面小編就為大家分享一篇python爬蟲獲取京東手機圖片的圖文教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12

最新評論