loggerpython
⑴ flask中logger日誌的使用
日誌是一個正規系統都應該有的功能,否則當運行良好的系統突然無法正常運轉的時候,你就會束手無策,而有了日誌,你就可以通過日誌查看其中緣由,從而解決問題。
1.python中使用logger非常簡單,可以直接使用
2.我們可以通過設置logger的存貯方式,比如寫入文件
3.當然我們也可以設置logger的格式
4.藍圖中logger的使用
我們在使用藍圖的時候,如果想要統一的logger日誌文件,可以使用current_app來設置。
如果我們想要單獨設置藍圖的日誌的話。
⑵ Python出錯:AttributeError: type object 'Logger' has no attribute '_Logger__logger'
作為類內的方法,需要將類對象自己傳給該方法。
def __new__(clz, name):這一行中缺少自傳參數,系統會把clz當作class Logger的位置,所以報錯。
將它改成def __new__(self, clz, name):再試試!
⑶ python程序中logging怎麼用
簡單將日誌列印到屏幕:
[python] view plain
import logging
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
輸出:
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message
可見,默認情況下Python的
logging模塊將日誌列印到了標准輸出中,且只顯示了大於等於WARNING級別的日誌,這說明默認的日誌級別設置為WARNING(日誌級別等級
CRITICAL > ERROR > WARNING > INFO > DEBUG >
NOTSET),默認的日誌格式為日誌級別:Logger名稱:用戶輸出消息。
靈活配置日誌級別,日誌格式,輸出位置
[python] view plain
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='/tmp/test.log',
filemode='w')
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
查看輸出:
cat /tmp/test.log
Mon, 05 May 2014 16:29:53 test_logging.py[line:9] DEBUG debug message
Mon, 05 May 2014 16:29:53 test_logging.py[line:10] INFO info message
Mon, 05 May 2014 16:29:53 test_logging.py[line:11] WARNING warning message
Mon, 05 May 2014 16:29:53 test_logging.py[line:12] ERROR error message
Mon, 05 May 2014 16:29:53 test_logging.py[line:13] CRITICAL critical message
可見在logging.basicConfig()函數中可通過具體參數來更改logging模塊默認行為,可用參數有
filename:用指定的文件名創建FiledHandler(後邊會具體講解handler的概念),這樣日誌會被存儲在指定的文件中。
filemode:文件打開方式,在指定了filename時使用這個參數,默認值為「a」還可指定為「w」。
format:指定handler使用的日誌顯示格式。
datefmt:指定日期時間格式。
level:設置rootlogger(後邊會講解具體概念)的日誌級別
stream:用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件,默認為sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。
format參數中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 數字形式的日誌級別
%(levelname)s 文本形式的日誌級別
%(pathname)s 調用日誌輸出函數的模塊的完整路徑名,可能沒有
%(filename)s 調用日誌輸出函數的模塊的文件名
%(mole)s 調用日誌輸出函數的模塊名
%(funcName)s 調用日誌輸出函數的函數名
%(lineno)d 調用日誌輸出函數的語句所在的代碼行
%(created)f 當前時間,用UNIX標準的表示時間的浮 點數表示
%(relativeCreated)d 輸出日誌信息時的,自Logger創建以 來的毫秒數
%(asctime)s 字元串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒
%(thread)d 線程ID。可能沒有
%(threadName)s 線程名。可能沒有
%(process)d 進程ID。可能沒有
%(message)s用戶輸出的消息
⑷ 多進程環境python logging列印日誌混亂問題
解決辦法如下:
多麼痛的領悟,困擾了這么久的問題其實就是一個參數配置錯了。
fileMode:表示日誌文件的打開方式。w-直接寫,使用這個配置當系統重啟的時候日誌會清空,一個進程打開後其他進程是無法使用的;a-尾部追加,大家都可以打開往文件結尾進行追加寫入。
本人主語言是java,轉到python後日誌這塊踩了幾個坑。再說說另外一個坑,就是異常堆棧的列印問題,在java中logger是可以使用error直接列印出來的。在python中error跟其他日誌記錄方法沒太大差別,是無法列印異常堆棧的,列印堆棧請使用 logger.exception("異常說明", e) 。
⑸ Python日誌—Python日誌模塊logging介紹
從事與軟體相關工作的人,應該都聽過「日誌」一詞。
日誌就是跟蹤軟體運行時事件的方法,為了能夠在程序運行過程中記錄錯誤。
通過日誌記錄程序的運行,方便我們查詢信息,以便追蹤問題、進行維護和調試、還是數據分析。
並且各編程語言都形成了各自的日誌體系和相應的框架。
日誌的作用總結:
首先我們要樹立一個觀點,那就是「不是為了記錄日誌而記錄日誌,日誌也不是隨意記的」。要實現能夠只通過日誌文件還原整個程序執行的過程,達到能透明地看到程序里執行情況,每個線程每個過程到底執行結果的目的。日誌就像飛機的黑匣子一樣,應當能夠復原異常的整個現場乃至細節。
在項目中,日誌這個功能非常重要,我們要重視起來。
在Python中,使用logging模塊來進行日誌的處理。
logging是Python的內置模塊,主要用於將日誌信息進行格式化內容輸出,可將格式化內容輸出到文件,也可輸出到屏幕。
我們在開發過程中,常用print()函數來進行調試,但是在實際應用的部署時,我們要將日誌信息輸出到文件中,方便後續查找以及備份。
在我們使用日誌管理時,我們也可以將日誌格式化成Json對象轉存到ELK中方便圖形化查看及管理。
logging模塊將日誌系統從高向低依次定義了四個類,分別是logger(日誌器)、handler(處理器)、filter(過濾器)和formatter(格式器)。其中由日誌器生成的實例將接管原本日誌記錄函數logging.log的功能。
說明:
我們先來思考下下面的兩個問題:
在軟體開發階段或部署開發環境時,為了盡可能詳細的查看應用程序的運行狀態來保證上線後的穩定性,我們可能需要把該應用程序所有的運行日誌全部記錄下來進行分析,這是非常耗費機器性能的。
當應用程序正式發布或在生產環境部署應用程序時,我們通常只需要記錄應用程序的異常信息、錯誤信息等,這樣既可以減小伺服器的I/O壓力,也可以避免我們在排查故障時被淹沒在日誌的海洋里。
那麼怎樣才能在不改動應用程序代碼的情況下,根據事件的重要性或者稱之為等級,實現在不同的環境中,記錄不同詳細程度的日誌呢?
這就是日誌等級的作用了,我們通過配置文件指定我們需要的日誌等級就可以了。
說明:
總結:
開發應用程序時或部署開發環境時,可以使用DEBUG或INFO級別的日誌獲取盡可能詳細的日誌信息,可以方便進行開發或部署調試。 應用上線或部署生產環境時,應用使用WARNING或ERROR或CRITICAL級別的日誌,來降低機器的I/O壓力和提高獲取錯誤日誌信息的效率。 日誌級別的指定通常都是在應用程序的配置文件中進行指定的。 不同的應用程序所定義的日誌等級會有所差別,根據實際需求來決定。
⑹ python之配置日誌的幾種方式
1)使用Python代碼顯式的創建loggers, handlers和formatters並分別調用它們的配置函數;
2)創建一個日誌配置文件,然後使用fileConfig()函數來讀取該文件的內容;
3)創建一個包含配置信息的dict,然後把它傳遞個dictConfig()函數;
⑺ Python中的logger和handler到底是個什麼鬼
最近的任務經常涉及到日誌的記錄,特意去又學了一遍logging的記錄方法。跟java一樣,python的日誌記錄也是比較繁瑣的一件事,在寫一條記錄之前,要寫好多東西。典型的日誌記錄的步驟是這樣的:
創建logger
創建handler
定義formatter
給handler添加formatter
給logger添加handler
寫成代碼差不多就是醬嬸的(這個是照別的網頁抄的,參考附註):
1 import logging
2
3 # 1、創建一個logger
4 logger = logging.getLogger('mylogger')
5 logger.setLevel(logging.DEBUG)
6
7 # 2、創建一個handler,用於寫入日誌文件
8 fh = logging.FileHandler('test.log')
9 fh.setLevel(logging.DEBUG)
10
11 # 再創建一個handler,用於輸出到控制台
12 ch = logging.StreamHandler()
13 ch.setLevel(logging.DEBUG)
14
15 # 3、定義handler的輸出格式(formatter)
16 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
17
18 # 4、給handler添加formatter
19 fh.setFormatter(formatter)
20 ch.setFormatter(formatter)
21
22 # 5、給logger添加handler
23 logger.addHandler(fh)
24 logger.addHandler(ch)
之後才可以正式的開始記錄日誌。Java裡面的java.util.Logging類差不多也是這樣,代碼還要更復雜一點。Golang的日誌相對
寫法簡單一些,不過沒有什麼格式,系統記錄一條時間,內容格式完全自己手畫。第三方的日誌庫倒是沒有接觸過,像Java的Log4j,Golang的
log4go和seelog等等,不知道用起來會不會簡單一點。我一直都記不住這些,因為不太理解logger和handler為什麼要這樣寫。一直到這
次任務中出現的在我看來相當「詭異」的bug,才深入理解了一下。
我的任務是這樣的,要做一個日誌切割的工具,按天將日誌分割開,即每天0點產生一個新日誌,將舊日誌改名。並且,將超過3個月的日誌刪除掉,以保證磁碟空間不會被log占滿。程序要求可以切割多個目錄中的不同日誌,具體路徑由json中配置。
這里用到了logging.handlers類中的TimedRotatingFileHandler方法,用以獲得一個handler。大概的寫法為:
1 logger = logging.getLogger() #獲得logger
2 handler = logging.handlers.TimedRotatingFileHandler(logfile, 'S', 1, 0) #切割日誌
3 handler.suffix = '%Y%m%d' #切割後的日誌設置後綴
4 logger.addHandler(handler) #把logger添加上handler
5 logger.fatal(datetime.datetime.now().strftime('%Y-%m-%d')) #在新日誌中寫上當天的日期
這里我沒有設置level和formatter。因為只是分割,對新日誌沒有什麼影響。TimedRotatingFileHandler函數的方
法見附註,或查看python的源碼,這個函數是python寫的,可以找到定義。這里我使用的是每秒生成一個新的日誌文件,之後用Crontab在每天
0點調度,然後用for循環處理json中的每一個日誌文件。
但是奇怪的是,每次運行程序,第一個切割的日誌生成一個分割後的文件,而後面的都生成兩個新日誌。百思不得其解。後檢查代碼覺得,可能是程序中設置
的時間太短了,每秒生成一個文件,有可能一秒鍾處理不完,就生成了兩個。雖然這個說法沒有什麼科學根據,但是還是把
TimedRotatingFileHandler中的第三個參數改成了60,即每60秒生成一個文件。完成,靜靜的等待crontab到時間。
⑻ python 多線程logger問題
因為logging是threadsafe的,但不是process-safe(應該沒有這個詞兒,只是為了便於理解)的。這段代碼就是多個進程共同操作一個日誌文件。這種情況下,logging的行為就很難說了。
我測試了一下,日誌中大概幾百行。而且,可以看到一些順序錯亂現象:
Fri, 08 Aug 2014 01:19:38 logging_in_multithread.py[line:40] theadWorking ERROR 2
FFri, 08 Aug 2014 01:19:36 logging_in_multithread.py[line:40] theadWorking ERROR 11(注意這里的FFri)
把代碼這樣改:
fornuminrange(processNum):
p=Process(target=processWorking,args=('2',))
processs.append(p)
p.start()
p.join()
還有其他方法,比如:為logging實現一個FileHandler,以使logging在multiple process的環境下也能正常工作。這是我從網上了解到的做法,自己還沒實踐過。
Python Manual中logging Cookbook中有這么一段話:
Logging to a single file from multiple processes
Although logging is thread-safe, and logging to a single file from multiple threads in a single process is supported, logging to a single file from multiple processes is not supported, because there is no standard way to serialize access to a single file across multiple processes in Python. If you need to log to a single file from multiple processes, one way of doing this is to have all the processes log to a SocketHandler, and have a separate process which implements a socket server which reads from the socket and logs to file. (If you prefer, you can dedicate one thread in one of the existing processes to perform this function.)
這段話中也提出了另外一種解決方案。
⑼ python logging 使用記錄:設置INFO級別不生效,格式化,輸出到文件
沒有輸出INFO的日誌級別。默認是WARN級別的日誌,這里沒有輸出WARN說明沒有設置成功。
這時可以正常輸出INFO了
此時第二個logger也被設置了INFO級別了,查看源碼:
可以看到名字為None時返回的是一個root對象,這也是為什麼第二個logger也被修改的原因。
常見的輸出到控制台和文件
默認只是輸出了message,這樣子還不如直接用print()函數了。所以還需要格式化一下:
設置格式化要用到logging.Handler
輸出效果:
[圖片上傳失敗...(image-6690c5-1606835078864)]
formatter參數 :
⑽ Python中的logger和handler到底是個什麼鬼
import logging
# 1、創建一個logger
logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)
# 2、創建一個handler,用於寫入日誌文件
fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)
# 再創建一個handler,用於輸出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 3、定義handler的輸出格式(formatter)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 4、給handler添加formatter
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# 5、給logger添加handler
logger.addHandler(fh)
logger.addHandler(ch)