這篇“Python中l(wèi)oguru日志庫怎么使用”文章的知識點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Python中l(wèi)oguru日志庫怎么使用”文章吧。
創(chuàng)新互聯(lián)建站主要從事網(wǎng)站制作、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)石鼓,十多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575
python中的日志庫logging使用起來有點(diǎn)像log4j,但配置通常比較復(fù)雜,構(gòu)建日志服務(wù)器時(shí)也不是方便。標(biāo)準(zhǔn)庫logging的替代品是loguru,loguru使用起來就簡單的多。
loguru默認(rèn)的輸出格式是:時(shí)間、級別、模塊、行號以及日志內(nèi)容。loguru不需要手動創(chuàng)建 logger,開箱即用,比logging使用方便得多;另外,日志輸出內(nèi)置了彩色功能,顏色和非顏色控制很方便,更加友好。
loguru是非標(biāo)準(zhǔn)庫,需要事先安裝,命令是:**pip3 install loguru****。**安裝后,最簡單的使用樣例如下:
from loguru import logger
logger.debug('hello, this debug loguru')
logger.info('hello, this is info loguru')
logger.warning('hello, this is warning loguru')
logger.error('hello, this is error loguru')
logger.critical('hello, this is critical loguru')上述代碼輸出:

日志打印到文件的用法也很簡單,代碼如下:
from loguru import logger
logger.add('myloguru.log')
logger.debug('hello, this debug loguru')
logger.info('hello, this is info loguru')
logger.warning('hello, this is warning loguru')
logger.error('hello, this is error loguru')
logger.critical('hello, this is critical loguru')上述代碼運(yùn)行時(shí),可以打印到console,也可以打印到文件中去。

loguru默認(rèn)格式是時(shí)間、級別、名稱+模塊和日志內(nèi)容,其中名稱+模塊是寫死的,是當(dāng)前文件的__name__變量,此變量最好不要修改。
工程比較復(fù)雜的情況下,自定義模塊名稱,是非常有用的,容易定界定位,避免陷入細(xì)節(jié)中。我們可以通過logger.configure手工指定模塊名稱。如下如下:
import sys
from loguru import logger
logger.configure(handlers=[
{
"sink": sys.stderr,
"format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |<lvl>{level:8}</>| {name} : {module}:{line:4} | <cyan>mymodule</> | - <lvl>{message}</>",
"colorize": True
},
])
logger.debug('this is debug')
logger.info('this is info')
logger.warning('this is warning')
logger.error('this is error')
logger.critical('this is critical')
handlers:表示日志輸出句柄或者目的地,sys.stderr表示輸出到命令行終端。
"sink": sys.stderr,表示輸出到終端
"format":表示日志格式化。<lvl>{level:8}</>表示按照日志級別顯示顏色。8表示輸出寬度為8個(gè)字符。
"colorize":True**:表示顯示顏色。
上述代碼的輸出為:

這里寫死了模塊名稱,每個(gè)日志都這樣設(shè)置也是比較繁瑣。下面會介紹指定不同模塊名稱的方法。
日志一般需要持久化,除了輸出到命令行終端外,還需要寫入文件。標(biāo)準(zhǔn)日志庫可以通過配置文件配置logger,在代碼中也可以實(shí)現(xiàn),但過程比較繁瑣。loguru相對而已就顯得稍微簡單一些,我們看下在代碼中如何實(shí)現(xiàn)此功能。日志代碼如下:
import sys
from loguru import logger
logger.configure(handlers=[
{
"sink": sys.stderr,
"format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |<lvl>{level:8}</>| {name} : {module}:{line:4} | <cyan>mymodule</> | - <lvl>{message}</>",
"colorize": True
},
{
"sink": 'first.log',
"format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |{level:8}| {name} : {module}:{line:4} | mymodule | - {message}",
"colorize": False
},
])
logger.debug('this is debug')
logger.info('this is info')
logger.warning('this is warning')
logger.error('this is error')
logger.critical('this is critical')與2.1.唯一不同的地方,
logger.configure新增了一個(gè)handler,寫入到日志文件中去。用法很簡單。
上述只是通過logger.configure設(shè)置日志格式,但是模塊名不是可變的,實(shí)際項(xiàng)目開發(fā)中,不同模塊寫日志,需要指定不同的模塊名稱。因此,模塊名稱需要參數(shù)化,這樣實(shí)用性更強(qiáng)。樣例代碼如下:
import sys
from loguru import logger
logger.configure(handlers=[
{
"sink": sys.stderr,
"format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |<lvl>{level:8}</>| {name} : {module}:{line:4} | <cyan>{extra[module_name]}</> | - <lvl>{message}</>",
"colorize": True
},
{
"sink": 'first.log',
"format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |{level:8}| {name} : {module}:{line:4} | {extra[module_name]} | - {message}",
"colorize": False
},
])
log = logger.bind(module_name='my-loguru')
log.debug("this is hello, module is my-loguru")
log2 = logger.bind(module_name='my-loguru2')
log2.info("this is hello, module is my-loguru2")
logger.bind(module_name='my-loguru')通過bind方法,實(shí)現(xiàn)module_name的參數(shù)化。bind返回一個(gè)日志對象,可以通過此對象進(jìn)行日志輸出,這樣就可以實(shí)現(xiàn)不同模塊的日志格式。loguru中自定義模塊名稱的功能比標(biāo)準(zhǔn)日志庫有點(diǎn)不同。通過bind方法,可以輕松實(shí)現(xiàn)標(biāo)準(zhǔn)日志
logging的功能。而且,可以通過bind和logger.configure,輕松實(shí)現(xiàn)結(jié)構(gòu)化日志。
上述代碼的輸出如下:

loguru保存成結(jié)構(gòu)化json格式非常簡單,只需要設(shè)置serialize=True參數(shù)即可。代碼如下:
from loguru import logger
logger.add('json.log', serialize=True, encoding='utf-8')
logger.debug('this is debug message')
logger.info('this is info message')
logger.error('this is error message')輸出內(nèi)容如下:

loguru日志文件支持三種設(shè)置:循環(huán)、保留、壓縮。設(shè)置也比較簡單。尤其是壓縮格式,支持非常豐富,常見的壓縮格式都支持,比如:"gz", "bz2", "xz", "lzma", "tar", "tar.gz", "tar.bz2", "tar.xz", "zip"。樣例代碼如下:
from loguru import logger
logger.add("file_1.log", rotation="500 MB") # 自動循環(huán)過大的文件
logger.add("file_2.log", rotation="12:00") # 每天中午創(chuàng)建新文件
logger.add("file_3.log", rotation="1 week") # 一旦文件太舊進(jìn)行循環(huán)
logger.add("file_X.log", retention="10 days") # 定期清理
logger.add("file_Y.log", compression="zip") # 壓縮節(jié)省空間loguru默認(rèn)是線程安全的,但不是多進(jìn)程安全的,如果使用了多進(jìn)程安全,需要添加參數(shù)enqueue=True,樣例代碼如下:
logger.add("somefile.log", enqueue=True)
loguru另外還支持協(xié)程,有興趣可以自行研究。
更換日志系統(tǒng)或者設(shè)計(jì)一套日志系統(tǒng),比較難的是兼容現(xiàn)有的代碼,尤其是第三方庫,因?yàn)椴荒芤驗(yàn)槿罩鞠到y(tǒng)的切換,而要去修改這些庫的代碼,也沒有必要。好在loguru可以方便的接管標(biāo)準(zhǔn)的日志系統(tǒng)。
樣例代碼如下:
import logging
import logging.handlers
import sys
from loguru import logger
handler = logging.handlers.SysLogHandler(address=('localhost', 514))
logger.add(handler)
class LoguruHandler(logging.Handler):
def emit(self, record):
try:
level = logger.level(record.levelname).name
except ValueError:
level = record.levelno
frame, depth = logging.currentframe(), 2
while frame.f_code.co_filename == logging.__file__:
frame = frame.f_back
depth += 1
logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())
logging.basicConfig(handlers=[LoguruHandler()], level=0, format='%(asctime)s %(filename)s %(levelname)s %(message)s',
datefmt='%Y-%M-%D %H:%M:%S')
logger.configure(handlers=[
{
"sink": sys.stderr,
"format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |<lvl>{level:8}</>| {name} : {module}:{line:4} | [ModuleA] | - <lvl>{message}</>",
"colorize": True
},
])
log = logging.getLogger('root')
# 使用標(biāo)注日志系統(tǒng)輸出
log.info('hello wrold, that is from logging')
log.debug('debug hello world, that is from logging')
log.error('error hello world, that is from logging')
log.warning('warning hello world, that is from logging')
# 使用loguru系統(tǒng)輸出
logger.info('hello world, that is from loguru')輸出為:

如果有需要,不同進(jìn)程的日志,可以輸出到同一個(gè)日志服務(wù)器上,便于日志的統(tǒng)一管理。我們可以利用自定義或者第三方庫進(jìn)行日志服務(wù)器和客戶端的設(shè)置。下面介紹兩種日志服務(wù)器的用法。
3.2.1.自定義日志服務(wù)器
日志客戶端段代碼如下:
# client.py
import pickle
import socket
import struct
import time
from loguru import logger
class SocketHandler:
def __init__(self, host, port):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, port))
def write(self, message):
record = message.record
data = pickle.dumps(record)
slen = struct.pack(">L", len(data))
self.sock.send(slen + data)
logger.configure(handlers=[{"sink": SocketHandler('localhost', 9999)}])
while True:
time.sleep(1)
logger.info("Sending info message from the client")
logger.debug("Sending debug message from the client")
logger.error("Sending error message from the client")日志服務(wù)器代碼如下:
# server.py
import pickle
import socketserver
import struct
from loguru import logger
class LoggingStreamHandler(socketserver.StreamRequestHandler):
def handle(self):
while True:
chunk = self.connection.recv(4)
if len(chunk) < 4:
break
slen = struct.unpack('>L', chunk)[0]
chunk = self.connection.recv(slen)
while len(chunk) < slen:
chunk = chunk + self.connection.recv(slen - len(chunk))
record = pickle.loads(chunk)
level, message = record["level"].no, record["message"]
logger.patch(lambda record: record.update(record)).log(level, message)
server = socketserver.TCPServer(('localhost', 9999), LoggingStreamHandler)
server.serve_forever()運(yùn)行結(jié)果如下:

3.2.2.第三方庫日志服務(wù)器
日志客戶端代碼如下:
# client.py
import zmq
from zmq.log.handlers import PUBHandler
from loguru import logger
socket = zmq.Context().socket(zmq.PUB)
socket.connect("tcp://127.0.0.1:12345")
handler = PUBHandler(socket)logger.add(handler)
logger.info("Logging from client")日志服務(wù)器代碼如下:
# server.py
import sys
import zmq
from loguru import logger
socket = zmq.Context().socket(zmq.SUB)
socket.bind("tcp://127.0.0.1:12345")
socket.subscribe("")
logger.configure(handlers=[{"sink": sys.stderr, "format": "{message}"}])
while True:
_, message = socket.recv_multipart()
logger.info(message.decode("utf8").strip())官方幫助中有一個(gè)講解loguru與pytest結(jié)合的例子,講得有點(diǎn)含糊不是很清楚。簡單的來說,pytest有個(gè)fixture,可以捕捉被測方法中的logging日志打印,從而驗(yàn)證打印是否觸發(fā)。
下面就詳細(xì)講述如何使用loguru與pytest結(jié)合的代碼,如下:
import pytest
from _pytest.logging import LogCaptureFixture
from loguru import logger
def some_func(i, j):
logger.info('Oh no!')
logger.info('haha')
return i + j
@pytest.fixture
def caplog(caplog: LogCaptureFixture):
handler_id = logger.add(caplog.handler, format="{message}")
yield caplog
logger.remove(handler_id)
def test_some_func_logs_warning(caplog):
assert some_func(-1, 3) == 2
assert "Oh no!" in caplog.text測試輸出如下:

以上就是關(guān)于“Python中l(wèi)oguru日志庫怎么使用”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)站名稱:Python中l(wèi)oguru日志庫怎么使用
標(biāo)題來源:http://chinadenli.net/article18/phoddp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、云服務(wù)器、微信小程序、靜態(tài)網(wǎng)站、外貿(mào)建站、小程序開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)