Scribe是跨語言的日誌彙總架構,如何在Python中使用它呢?其在Python中的簡單使用方法如下:
#!/usr/bin/env python
# encoding: utf8
"""scribe_cat: A simple script for sending messages to scribe."""
__author__ = 'zhoubo'
import sys
from scribe import scribe
from thrift.transport import TTransport, TSocket
from thrift.protocol import TBinaryProtocol
if len(sys.argv) == 2:
category = sys.argv[1]
host = '127.0.0.1'
port = 1463
elif len(sys.argv) == 4 and sys.argv[1] == '-h':
category = sys.argv[3]
host_port = sys.argv[2].split(':')
host = host_port[0]
if len(host_port) > 1:
port = int(host_port[1])
else:
port = 1463
else:
sys.exit('usage (message is stdin): scribe_cat [-h host[:port]] category')
log_entry = scribe.LogEntry(category=category, message=sys.stdin.read())
socket = TSocket.TSocket(host=host, port=port)
transport = TTransport.TFramedTransport(socket)
protocol = TBinaryProtocol.TBinaryProtocol(trans=transport, strictRead=False, strictWrite=False)
client = scribe.Client(iprot=protocol, oprot=protocol)
transport.open()
result = client.Log(messages=[log_entry])
transport.close()
if result == scribe.ResultCode.OK:
sys.exit()
elif result == scribe.ResultCode.TRY_LATER:
print >> sys.stderr, "TRY_LATER"
sys.exit(84) # 'T'
else:
sys.exit("Unknown error code.")
使用方式如下:
$echo "hello world" | ./scribe_cat [-h host[:port]] category
為了使程式更方便的使用Scribe日誌彙總架構,我將scribeTlog整合到python logging中,使其作為python logging中的一個Handler來使用Scribe系統。
下面是我修改的python logging原始碼,增加部分見下方:
from scribe import scribe
from thrift.transport import TTransport, TSocket
from thrift.protocol import TBinaryProtocol
class ScribeHandler(StreamHandler):
"""
A handler class which writes formatted logging records to Scrbie Server
"""
client = None
def __init__(self, host='127.0.0.1', port=1464, category=None, delay=0):
"""
Open the specified file and use it as the stream for logging.
"""
if category is None:
category = 'root'
self.host = host
self.port = port
self.category = category
if delay:
self.stream = None
else:
stream = self._open()
StreamHandler.__init__(self, stream)
def close(self):
"""
Closes the stream.
"""
if self.stream:
self.flush()
if hasattr(self.stream, "close"):
self.stream.close()
StreamHandler.close(self)
self.stream = None
def _open(self):
"""
Open the current base file with the (original) mode and encoding.
Return the resulting stream.
"""
socket = TSocket.TSocket(host=self.host, port=self.port)
transport = TTransport.TFramedTransport(socket)
protocol = TBinaryProtocol.TBinaryProtocol(trans=transport, strictRead=False, strictWrite=False)
self.client = scribe.Client(iprot=protocol, oprot=protocol)
transport.open()
return transport
def emit(self, record):
"""
Emit a record.
If the stream was not opened because 'delay' was specified in the
constructor, open it before calling the superclass's emit.
"""
if self.stream is None:
stream = self._open()
StreamHandler.__init__(self, stream)
self.record(record)
def record(self, record):
"""
Emit a record.
If a formatter is specified, it is used to format the record.
The record is then written to the stream with a trailing newline. If
exception information is present, it is formatted using
traceback.print_exception and appended to the stream. If the stream
has an 'encoding' attribute, it is used to encode the message before
output to the stream.
"""
try:
msg = self.format(record)
fs = "%s\n"
log_entry = scribe.LogEntry(category=self.category, message=fs%msg)
#print msg,log_entry
if self.client is not None:
result = self.client.Log(messages=[log_entry])
if result == scribe.ResultCode.TRY_LATER:
sys.stderr.write("TRY_LATE")
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
將/usr/lib/python2.6/logging/__init__.py檔案替換為附件__init__.py
測試執行個體:
[loggers]
keys=root,test
[handlers]
keys=consoleHandler,scribeHandler
[formatters]
keys=simpleFormatter,scribeFormatter
[formatter_simpleFormatter]
format=[%(asctime)s] - (%(levelname)s) : %(message)s
[formatter_scribeFormatter]
format=[192.168.0.55] - [%(asctime)s] - (%(levelname)s) : %(message)s
[logger_root]
level=WARN
handlers=consoleHandler
[logger_test]
level=INFO
qualname=test
handlers=scribeHandler
[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)
[handler_scribeHandler]
class=ScribeHandler
level=INFO
formatter=scribeFormatter
args=('localhost', 1464, 'zhoubo',)
測試小程式:
#!/usr/bin/env python
# encoding: utf8
import logging
import logging.config
logging.config.fileConfig("logging.config")
#create logger
logger = logging.getLogger("test")
#"application" code
logger.debug("debug message")
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
logger.critical("critical message")
logHello = logging.getLogger("hello")
logHello.info("Hello world!")