怎樣python重複輸出一句話 日誌重複輸出問題

2021-10-11 11:49:29 字數 4229 閱讀 2353

[toc]

# **python日誌重複輸出問題

## 問題起源:

​ 在學習了python的函式式程式設計後,又接觸到了logging這樣乙個強大的日誌模組。為了減少重複**,應該不少同學和我一樣便迫不及待的寫了乙個自己的日誌函式,比如下面這樣:

# 這裡為了便於理解,簡單的展示了乙個輸出到螢幕的日誌函式

def my_log():

logger = logging.getlogger('mysql.log')

ch = logging.streamhandler()

ch.setlevel(logging.error)

fmt = logging.formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setformatter(fmt)

logger.addhandler(ch)

return logger

my_log().error('run one')

my_log().error('run two')

my_log().error('run three')

函式寫好了,看起來似乎也沒有問題,我們來執行一下!

結果如下:

> 2018-06-21 13:06:37,569 - mysql.log - error - run one

> 2018-06-21 13:06:37,569 - mysql.log - error - run two

> 2018-06-21 13:06:37,569 - mysql.log - error - run two

> 2018-06-21 13:06:37,569 - mysql.log - error - run three

> 2018-06-21 13:06:37,569 - mysql.log - error - run three

> 2018-06-21 13:06:37,569 - mysql.log - error - run three

日誌居然重複輸出了,且數量遞增。

## 問題解析

* 實際上`logger = logging.getlogger('mysql.log')`在執行時,沒有每次生成乙個新的logger,而是先檢查記憶體中是否存在乙個叫做『mysql.log』的logger物件,存在則取出,不存在則新建。

* 例項化的logger物件具有『handlers』這樣乙個屬性來儲存 handler,**演示如下:

def my_log():

logger = logging.getlogger('mysql.log')

# 每次被呼叫後列印出logger的handlers列表

print(logger.handlers)

ch = logging.streamhandler()

ch.setlevel(logging.error)

fmt = logging.formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setformatter(fmt)

logger.addhandler(ch)

return logger

my_log().error('run one')

my_log().error('run two')

my_log().error('run three')

執行結果:

> 2018-06-21 13:26:14,059 - mysql.log - error - run one

> \[ (error)>\]

> 2018-06-21 13:26:14,060 - mysql.log - error - run two

> 2018-06-21 13:26:14,060 - mysql.log - error - run two

> \[ (error)>, (error)>\]

> 2018-06-21 13:26:14,060 - mysql.log - error - run three

> 2018-06-21 13:26:14,060 - mysql.log - error - run three

> 2018-06-21 13:26:14,060 - mysql.log - error - run three

1. `logger.handlers`最初是乙個空列表,執行『logger.addhandler(ch)』新增乙個『streamhandler』,輸出一條日誌

2. 在第二次被呼叫時,`logger.handlers`已經存在乙個『streamhandler』,再次執行『logger.addhandler(ch)』就會再次新增乙個『streamhandler』,此時的logger有兩個個『streamhandler』,輸出兩條重複的日誌

3. 在第三次被呼叫時,`logger.handlers`已經存在兩個『streamhandler』,再次執行『logger.addhandler(ch)』就會再次新增乙個,此時的logger有三個『streamhandler』,輸出三條重複的日誌

## 解決辦法

### 1.改名換姓

# 為日誌函式新增乙個name,每次呼叫時傳入不同的日誌名

def my_log(name):

logger = logging.getlogger(name)

ch = logging.streamhandler()

ch.setlevel(logging.error)

fmt = logging.formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setformatter(fmt)

logger.addhandler(ch)

return logger

my_log('log1').error('run one')

my_log('log2').error('run two')

my_log('log3').error('run three')

執行結果:

> 2018-06-21 13:40:51,685 - log1 - error - run one

> 2018-06-21 13:40:51,685 - log2 - error - run two

> 2018-06-21 13:40:51,685 - log3 - error - run three

### 2.及時清理(logger.handlers.clear)

def my_log():

logger = logging.getlogger()

# 每次被呼叫後,清空已經存在handler

logger.handlers.clear()

ch = logging.streamhandler()

ch.setlevel(logging.error)

fmt = logging.formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setformatter(fmt)

logger.addhandler(ch)

return logger

my_log().error('run one')

my_log().error('run two')

my_log().error('run three')

### 3.用前判斷

import logging

def my_log():

logger = logging.getlogger('mysql.log')

# 判斷logger是否已經新增過handler,是則直接返回,否則才執行

if not logger.handlers:

ch = logging.streamhandler()

ch.setlevel(logging.error)

fmt = logging.formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

ch.setformatter(fmt)

logger.addhandler(ch)

return logger

my_log().error('run one')

my_log().error('run two')

my_log().error('run three')

mysql 匯出一句話 MySQL 匯出一句話

drop table if exists temp 如果存在temp就刪掉 create table temp cmd text not null 建立temp表,裡面就乙個cmd欄位 insert into temp cmd values php eval post cmd 把一句話木馬插入到te...

一句話提醒

1 在c 中,父窗體要訪問子窗體變數,需將子窗體變數設為public才能訪問。2 每 5 秒重新整理頁面 5 秒後重定向頁面 3 block 此元素將顯示為塊級元素,此元素前後會帶有換行符。inline 預設。此元素會被顯示為內聯元素,元素前後沒有換行符。4 document.getelementb...

一句話命令

bash 型別 wget r nc np 分片20m 上傳 bypy vvv s 20m upload mac下檢視埠占用 nettop nm tcp brew brew uninstall zsh brew services list brew services start brew servic...