XiWind 西風之劍
HomeTechProContactGitHub
  • About
  • Git
    • Windows Terminal、PowerShell 安裝
    • Git 開始使用
    • Branch 入門
    • 合併多個 Commit , 編輯
    • 額外功能
  • deep learning
    • Dilated Convolution
  • Python
    • GIL 【全域直譯器鎖】
    • PyPy 【JIT 編譯器】
    • Decorator 【修飾器】
      • Class Decorators
  • Python library
    • abc 【抽象 Class】
      • ABC, ABCMeta
      • __abstractmethods__, get_cache_token, update_abstractmethods
    • dataclasses 【數據 Class】
      • make_dataclass(), replace(), is_dataclass(), __post_init__
    • enum 【列舉 Class】
      • Flag, auto(), unique, verify()
      • 範例
    • concurrent.futures 【執行緒、程序】
      • Future, Module Functions
    • queue 【佇列、同步】
      • full(), empty(), qsize(), join(), task_done()
    • functools 【可調用物件】
      • ordering、wrapper、partial
      • Overloading
    • heapq 【堆積佇列】
      • heapify(), merge(), nlargest(), nsmallest()
    • time 【時間】
      • time(), monotonic(), perf_counter()...
      • sleep(), 範例...
    • logging 【日誌】
Powered by GitBook
On this page
  • Logging
  • 最佳的紀錄工具
  • basicConfig
  • fileConfig
  • Logger
  • Handler
  • Filter
  • 範例
  • basicConfig
  • fileConfig
  • logger
  • Handler
  • Filter
  • Logger Decorator
  • 參考資料

Was this helpful?

  1. Python library

logging 【日誌】

Previoussleep(), 範例...

Last updated 1 year ago

Was this helpful?

Logging


Logging library module 允許開發人員將日誌功能整合到他們的應用程序中,從而在運行時記錄事件、錯誤和其他重要信息。

print() 是沒有嚴重性概念的普通文本。而 Logging 具有 4 個級別的日誌訊息嚴重性或重要性,有助於從訊息忽略較低嚴重性的訊息。

Log 級別
說明

info(msg, *args, **kwargs)

監視和理解應用程序行為。(例如: 報告流程、事件、顯示狀態)

debug(msg, *args, **kwargs)

用於開發和測試階段。(例如: 記錄變數值、路徑、內部狀態)

warning(msg, *args, **kwargs)

表示問題已經發生或即將發生,但應用程序仍可以繼續運行。

error(msg, *args, **kwargs)

表示特定操作或任務失敗或遇到異常。錯誤通常會阻止應用程序按預期運行或產生不正確的結果。

critical(msg, *args, **kwargs)

表示對應用程序的功能有重大的嚴重錯誤。當此類事件發生時,應用程序可能處於不穩定或不可恢復的狀態。

PYTHON
import logging

# log
logging.info("[This is a info]") 
logging.warning("[This is a warning]")
logging.error("[This is a error]")
logging.critical("[This is a critical]")

執行結果

WARNING:root:[This is a warning]
ERROR:root:[This is a error]
CRITICAL:root:[This is a critical]

最佳的紀錄工具


任務
工具

顯示在 Terminal

print()

監控或故障調查

logging.info()、 logging.debug()

發出事件的警告

logging.warning()(注意該事件)、warnings.warn();(必須修正該事件)

報告事件的錯誤

引發 Exception。詳見: [[exception 【異常】]]

抑制錯誤而不引發異常 (例如: 伺服器中的 Threading)

logging.error(), logging.exception(), logging.critical()

basicConfig


快速設定多個屬性 (logger、FileHandler...)

PYTHON
logging.basicConfig(**kwargs)

常用的參數:

輸出級別控制
說明

filename

寫入日誌訊息的檔案名稱,否則輸出在 Terminal。

filemode

寫入模式,即 open()。如果指定 filename,則使用 "a"。

format

datefmt

style

日誌訊息的格式('%', '{', '$'),預設為%。

level

設置根記錄器級別,不會記錄較小的級別的日誌。級別大小為: DEBUG < INFO < WARNING < ERROR < CRITICAL。

encoding

編碼模式。常使用 encoding="UTF-8"。

fileConfig

fileConfig() 允許使用 Configuration file 設定日誌記錄,而不是透過程式碼的方式定義。 支持的格式有:.ini、.yaml、.json。

透過使用 logging.config.fileConfig(),您可以將日誌記錄設定與您的程式碼分開,從而在不修改代碼本身的情況下更輕鬆地管理。此外,您可以為不同的環境或模塊使用不同的 Configuration file。

PYTHON
logging.config.fileConfig(fname, 
                          defaults=None, 
                          disable_existing_loggers=True, 
                          encoding=None)

Logger


建立 Logger ,可以過濾 log 資訊。

設定 Logger。

PYTHON
logging.getLogger(name=None)
logging.getLogger(loggeyr_1)           # Ex1.
logging.getLogger(logger_1.logger_1_2) # Ex2. 可以使用`.` 代表 Logger 的階層。

建議使用 logger.getLogger(__name__)。

因為它將返回當前的 package 命名空間。如果有多個.py 檔案時很有用。

Handler


如何處理 Logger 的資訊。

將 Logger 輸出到 File。

logging.FileHandler(filename, 
                    mode='a', 
                    encoding=NoHne, 
                    delay=False, 
                    errors=None)

將 Logger 輸出到 Terminal。

logging.StreamHandler(stream=None)

將 Logger 輸出到 Web 。

PYTHON
handlers.HTTPHandler(host, 
                     url, 
                     method='GET', 
                     secure=False, 
                     credentials=None, 
                     context=None)
PYTHON
file_handler = logging.FileHandler('app.log')

# =========================================================
# level
file_handler.setLevel(logging.INFO)

# Formatter
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)

Filter


Filter class 允許您自定義過濾器以根據特定條件有選擇地過濾掉日誌記錄。 它提供了一種微調日誌記錄系統中日誌記錄處理的方法。

Filter Filter class 是一個 base class, 它提供了一個 filter(record) 的方法,您需要在子 class 中覆蓋該方法。 filter() 方法將日誌記錄作為輸入,如果返回 True,則處理該日誌;則返回 True,如果返回 False,則跳過該日誌 。

過濾器與日誌級別將會一起運行,日誌級別具有較高的優先度。

例如:如果日誌級別設置為 WARNING,則只有 WARNING 或更高級別的日誌記錄才會被處理,而不管過濾器的設定。

範例


basicConfig

PYTHON
'''basicConfig'''

import logging

# 建立 logger 和 FileHandler
logging.basicConfig(filename = 'log.txt',
                    level = logging.DEBUG,
                    format = '{asctime}: {levelname}: {name}: {message}',
                    style='{')
                    #format = '%(asctime)s:%(levelname)s:%(name)s:%(message)s')

logging.debug('Debug message')
logging.info('Info message')
logging.warning('Warning message')
logging.error('Error message')
logging.critical('Critical message')

執行結果:

PYTHON
'''
basicConfig ->logger
            ->logger
'''

import logging

# 設定多個屬性
logging.basicConfig(filename='app.log', 
                    level=logging.INFO, 
                    format='%(asctime)s - %(levelname)s - %(message)s')

# =========================================================
# logger 1 
logger = logging.getLogger('my_logger_1')
logger.setLevel(logging.DEBUG)

# log
logger.debug('This is a debug message.')         # ✔️✔️
logger.info('This is an informational message.') # ✔️✔️
logger.warning('This is a warning message.')     # ✔️✔️

# =========================================================
# logger 2
logger_2 = logging.getLogger('my_logger_2') 
logger_2.setLevel(logging.WARNING)

# log
logger_2.debug('This is a debug message.')
logger_2.info('This is an informational message.')
logger_2.warning('This is a warning message.')   # ✔️✔️

執行結果:

app.log
2023-07-19 18:18:20,495 - DEBUG - This is a debug message.
2023-07-19 18:18:20,495 - INFO - This is an informational message.
2023-07-19 18:18:20,495 - WARNING - This is a warning message.
2023-07-19 18:18:20,495 - WARNING - This is a warning message.

fileConfig


INI
[loggers]
keys=root

[handlers]
keys=fileHandler, consoleHandler

[formatters]
keys=defaultFormatter

[logger_root]
level=DEBUG
handlers=fileHandler, consoleHandler

[handler_fileHandler]     # 輸出到 檔案
class=FileHandler
level=DEBUG
formatter=defaultFormatter
args=('example.log', 'a')

[handler_consoleHandler]  # 輸出到 Terminal
class=StreamHandler
level=DEBUG
formatter=defaultFormatter
args=(sys.stdout,)

[formatter_defaultFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S
YAML
version: 1
formatters:
  defaultFormatter:
    format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    datefmt: "%Y-%m-%d %H:%M:%S"
    
handlers:
  fileHandler:         # 輸出到 檔案
    class: logging.FileHandler
    level: DEBUG
    formatter: defaultFormatter
    filename: app.log
  consoleHandler:      # 輸出到 Terminal
    class: logging.StreamHandler
    level: DEBUG
    formatter: defaultFormatter
    stream: ext://sys.stdout
    
loggers:
    root:
        level: DEBUG
        handlers: [fileHandler, consoleHandler]
        propagate: yes
PYTHON
import yaml
import logging
import logging.config

# 載入 configuration_file.conf,建立 logger
logging.config.fileConfig('logging.conf')
logger = logging.getLogger(__name__)

# 寫入 Log
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')

# =========================================================
# 載入 configuration_file.yaml,建立 logger
with open('logging.yaml', 'r') as f:
    config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)
logger = logging.getLogger(__name__)

# 寫入 Log
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')

logger


PYTHON
'''getLogger('my_logger') ->FileHandler'''

import logging

# 建立 logger
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)

# 建立 FileHandler
file_handler = logging.FileHandler('app.log')
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)

# 加入 handler
logger.addHandler(file_handler)

# 寫入 log
logger.info('This is an informational message.')
logger.warning('This is a warning message.')

執行結果:

app.log
2023-07-19 17:58:12,393 - INFO - This is an informational message.
2023-07-19 17:58:12,393 - WARNING - This is a warning message.

PYTHON
'''getLogger(__name__) ->FileHandler'''
import logging

# 建立 logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(name)s - %(asctime)s - %(levelname)s - %(message)s')

# 建立 FileHandler
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.WARNING)
file_handler.setFormatter(formatter)

# 加入 handler
logger.addHandler(file_handler)

# log
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')

執行結果:

app.log
__main__ - 2023-07-19 18:01:14,806 - WARNING - This is a warning message
__main__ - 2023-07-19 18:01:14,806 - ERROR - This is an error message

Handler


PYTHON
import logging

# 設定多個屬性
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

# =========================================================
# 建立 FileHandler
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)

# =========================================================
# 建立 StreamHandler
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
console_handler.setFormatter(formatter)

# =========================================================
# 加入 handler
logger.addHandler(file_handler)
logger.addHandler(console_handler)

# =========================================================
# 寫入 log
logger.debug('This is a debug message.')
logger.info('This is an informational message.')
logger.warning('This is a warning message.')

執行結果:

2023-07-19 18:04:38,094 - DEBUG - This is a debug message.
2023-07-19 18:04:38,094 - INFO - This is an informational message.
2023-07-19 18:04:38,094 - WARNING - This is a warning message.
app.log
2023-07-19 18:04:38,094 - INFO - This is an informational message.
2023-07-19 18:04:38,094 - WARNING - This is a warning message.

Filter


PYTHON
import logging

class LoggerFilter(logging.Filter):
    def filter(self, record):
        return record.levelno >= logging.WARNING


class HandlerFilter(logging.Filter):
    def filter(self, record):
        if record.msg.find('abc') == -1:
            return True
        return False
        
# 建立 Handler
logger = logging.getLogger('test')
logger.setLevel(logging.INFO)

# 建立 Handler
stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)

# =========================================================
logger.warning('this is warning-1')    # ✔️✔️
logger.info('this is info-1')          # ✔️✔️

# =========================================================
logger.addFilter(LoggerFilter())
logger.warning('this is warning-2')    # ✔️✔️
logger.info('this is info-2')          # Skip this log

# =========================================================
stream_handler.addFilter(HandlerFilter())
logger.warning('this is warning-3')    # ✔️✔️
logger.info('this is info-3')          # Skip this log
logger.warning('this is warning-abc')  # Skip this log

執行結果:

this is warning-1
this is info-1
this is warning-2
this is warning-3

Logger Decorator


PYTHON
import logging

def logger(func):
    def wrapper(*args, **kwargs):
        logging.info(f"Running \"{func.__name__}\" with arguments {args} and kwargs {kwargs}")
        result = func(*args, **kwargs)
        logging.info(f"{func.__name__} returned {result}")
        return result
    return wrapper

logging.basicConfig(level=logging.INFO)

@logger
def adder(x, y):
    return x + y

print(adder(10, 5))

執行結果:

INFO:root:Running "adder" with arguments (10, 5) and kwargs {}
INFO:root:adder returned 15
15

PYTHON
import logging

class LevelFilter(logging.Filter):
    """
    This is a custom filter class that filters out log messages below certain level.
    """
    def filter(self, record):
        return record.levelno >= logging.INFO

def setup_logger():
    logger = logging.getLogger('custom_logger')
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # Create console handler with a higher log level
    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)
    ch.setFormatter(formatter)
    logger.addHandler(ch)

    # Create file handler which logs even debug messages
    fh = logging.FileHandler('log_file.log')
    fh.setLevel(logging.INFO)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    
    # Add filter to the logger
    logger.addFilter(LevelFilter())
    return logger

logger = setup_logger()

def logger_decorator(func):
    def wrapper(*args, **kwargs):
        logger.info(f"Running \"{func.__name__}\" with arguments {args} and kwargs {kwargs}")
        result = func(*args, **kwargs)
        logger.info(f"{func.__name__} returned {result}")
        return result
    return wrapper

@logger_decorator
def adder(x, y):
    return x + y

print(adder(10, 5))

執行結果:

2023-07-19 18:40:51,589 - custom_logger - INFO - Running "adder" with arguments (10, 5) and kwargs {}
2023-07-19 18:40:51,589 - custom_logger - INFO - adder returned 15
15

參考資料


Python Doc

Blog

需要寫入的日誌訊息。詳見: 。

指定的日期/時間格式。與 的格式相同。

設定 Handler 屬性。 其他屬性詳見:

logging.Handler
基礎 Logging 指南 — Python 3.11.3 說明文件
進階日誌教程 — Python 3.11.3 說明文件
日誌操作手冊 — Python 3.11.3 說明檔
logging.basicConfig — Python 3.11.3 說明文件
logging.getLogger — Python 3.11.3 說明文件
handlers — Python 3.11.3 文檔
config.fileConfig — Python 3.11.3 documentation
filter objects
Logging in Python - MachineLearningMastery.com
Logging in Python ——真正的 Python
Python 日誌記錄基礎:方法教程、示例及更多 - Sematext
在 Python 中登錄 - MachineLearningMastery.com
如何使用logging.Filter? | Python笔记
Python logging 模組之 logging.basicConfig 用法和參數詳解_Sir靜堂的博客-CSDN博客
Python - 日誌 (logging) 模組 | Titangene Blog
LogRecord attributes
time.strftime()
Logging library module
執行結果
Logging library module
執行結果
Page cover image