logging的日志输出没有现成的输出到数据库的,然后网上也没找到现成的输出到mysql数据库的,就看了下源码,自己封装了个
实现方法
简单来说,就是写一个类继承logging.Handler,并重写emit方法,我这里是结合sqlalchemy的,如果日志表不存在,会直接在指定数据库创建指定名字的表,也可以在init中采用普通的pymysql的方式创建数据库连接,然后在emit中使用cursor执行sql语句提交
# coding: utf-8
import logging
import pymysql
from sqlalchemy import (Column, DateTime, Integer, MetaData,
String, Table, create_engine, text)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import mapper, sessionmaker
class LoggerHandlerToMysql(logging.Handler):
def __init__(self, configdb_str, table_name):
self.config_engine = create_engine(configdb_str)
self.ConfigSession = sessionmaker(bind = self.config_engine)
self.config_session = self.ConfigSession()
metadata = MetaData(self.config_engine)
log_table = Table(table_name, metadata,
Column('id', Integer, primary_key = True),
Column('create_time', DateTime, nullable=False, server_default=text("'0000-00-00 00:00:00.000'")),
Column('level_name', String(10)),
Column('message', String(255)),
Column('splilt_type', String(10)),
Column('split_base', String(10)),
Column('exc_info', String(255)),
Column('exc_text', String(255)),
Column('file_name', String(100)),
Column('line_no', Integer),
Column('func_name', String(255)),
Column('stack_info', String(255)))
metadata.create_all(self.config_engine)
self.LogModel = getModel(table_name, self.config_engine)
logging.Handler.__init__(self)
def emit(self,record):
log_model = self.LogModel()
log_model.create_time = str(record.asctime).replace(",", ".")
log_model.level_name = record.levelname
message = record.message
message = message.split("---")
log_model.message = message[0].strip()
if len(message) > 1:
log_model.splilt_type = message[1].strip()
if len(message) > 2:
log_model.split_base = message[2].strip()
log_model.exc_info = record.exc_info
log_model.exc_text = record.exc_text
log_model.file_name = record.filename
log_model.line_no = record.lineno
log_model.func_name = record.funcName
log_model.stack_info = record.stack_info
self.config_session.add(log_model)
self.config_session.commit()
pass
def close(self):
self.config_session.commit()
self.config_session.close()
pass
调用方式
# 数据库连接字符串
configdb_str = 'mysql+pymysql://%s:%s@%s:%d/%s?charset=%s'%(user, password, host, int(port), db, charset)
# 表名
log_to_sql = 'service_log'
logger = logging.getLogger()
handler = LoggerHandlerToMysql(configdb_str, log_to_sql)
logger.addHandler(handler)