簡體   English   中英

Python:從配置文件中讀取日志級別,避免以前的 DEBUG 信息丟失

[英]Python: Reading Logging Level from a Config File and avoiding previous DEBUG Information not getting lost

我有以下 python 代碼,其中通過命令行參數設置全局記錄器的日志記錄級別:

logging.basicConfig (
    level = getattr (logging, clArgs.logLevel),
    ...

如果沒有通過 CL 參數指定日志記錄級別,則默認情況下 INFO 日志級別用於全局日志記錄:

# Define '--loglevel' argument
clArgsParser.add_argument (
    "-l", "--loglevel",
    help = "Set the logging level of the program. The default log level is 'INFO'.",
    default = 'INFO',                       # Default log level is 'INFO'
    dest = "logLevel",                      # Store the argument value into the variable 'logLevel'
    choices = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
)

現在我想給用戶第二個選項,這樣日志記錄級別也可以在配置文件中指定。 N.盡管如此,在讀出配置文件之前,腳本必須先讀出 CL arguments 以確定用戶是否設置了日志級別 CL 參數。 此外,還可以通過 CL 參數指定配置文件路徑。 腳本讀出 CL arguments 並設置日志級別后,它會存儲一些日志信息(例如日志文件位置、腳本正在執行的目錄等),並在讀取配置文件時存儲DEBUG日志信息在 function readProgramConfig 中 配置文件在最后讀出(函數readProgramConfig ),如下面的代碼片段所示:

# Parse the Command-line Arguments
clArgs, progName = parseClArgs ( __program__ )

# Initialize Global Logging with Command-line Arguments
defaultLogFilePath = configLogging ( clArgs )

# Log Program Version used
logging.info ( f"Program version: {__program__.swVersion}")

# Log Script Start Time
logging.info ( f"Program start time: {programStartDate}" )

# Log the program's current directory
logging.debug ( f"Directory where the Program is being executed: {PROGRAM_DIR}" )

# Output the log file location
logging.debug ( f"Log file location: {defaultLogFilePath}")

# Read out the program configuration
programConfig = readProgramConfig ( clArgs.programConfigPath )   

這會導致一個問題——如果沒有通過 CL 參數指定日志級別並且日志級別由用戶在配置文件中指定(例如DEBUG ),那么將發生以下情況:

  1. 沒有指定日志級別的 CL-Arg -> 默認使用INFO日志級別
  2. 在讀出配置文件之前記錄(程序版本、程序啟動時間)-> 但是,默認情況下使用INFO ,因此不會記錄DEBUG級別信息
  3. 此外,在讀取配置文件(函數readProgramConfig )時沒有記錄DEBUG信息
  4. 讀出配置文件后,腳本將確定配置文件想要將日志級別設置為DEBUG ,然后嘗試將全局日志級別從INFO更改為DEBUG
  5. 從現在開始,所有DEBUG信息都將被記錄,但是之前的DEBUG信息將丟失,即從未記錄

所以這有點像母雞和雞蛋的問題。

我確實有一個解決方案,但它相當復雜,我想看看你們中是否有人有更簡單的解決方案。

一種可能的解決方案是:

  1. 默認情況下以DEBUG日志級別啟動腳本以捕獲所有日志消息

  2. 讀出配置文件:

    2.1 如果配置文件中的日志級別設置為DEBUG ,則繼續以DEBUG日志級別登錄日志文件。

    2.2 如果配置文件中的日志級別設置為低於DEBUG的日志級別(例如INFO ),則刪除日志文件中的所有DEBUG條目,並僅使用INFO日志級別繼續記錄。

您會看到解決方案相當復雜 - 它涉及編輯日志文件並來回寫入......更不用說這種方法不適用於登錄控制台......

一種解決方案是使用logging.config python 模塊。 您可以讀取配置文件(例如 JSON 格式)並將其存儲為字典。 該模塊提供 function logging.config.dictConfig它將使用來自配置文件(即字典)的信息配置記錄器。 配置根記錄器的代碼看起來像這樣:

import logging                                 # Logging
from logging import config as LogConfig        # Logging Configuration

# Create the Log File name
logFileConfigName = "LogConfig.json"
logFileConfigPath = os.path.join ( PROGRAM_DIR, logFileConfigName )

# Open the JSON Config File
jsonLogConfigFile = open ( logFileConfigPath )

# Decode the JSON Config File
jsonLogConfig = json.load ( jsonLogConfigFile )

# Take the logging configuration from a dictionary
LogConfig.dictConfig ( jsonLogConfig )

記錄器配置將存儲在LogConfig.json文件中。 對於控制台和文件日志記錄,配置文件中定義了一個單獨的處理程序:

{
    "version": 1,
    "root":
    {
        "handlers" : ["console", "file"],
        "level": "DEBUG"
    },
    "handlers":
    {
        "console":
        {
            "formatter": "std_out",
            "class": "logging.StreamHandler"
        },
        "file":
        {
            "filename" : ".\\Program.log",
            "formatter" : "std_out",
            "class": "logging.FileHandler",
            "mode": "w"
        }
    },
    "formatters":
    {
        "std_out": 
        {
            "format": "%(asctime)s - %(levelname)s: %(message)s",
            "datefmt":"%Y-%m-%d - %H:%M:%S"
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM