SpringBoot Logback日志记录到数据库的实现方法
对于日志的处理,有时候需要把符合条件的日志计入数据库中
一、添加pom依赖
org.springframework.boot spring-boot-starter-web commons-dbcp commons-dbcp 1.4 mysql mysql-connector-java runtime
二、创建logback配置文件
%d{yyyy-MM-ddHH:mm:ss.SSS}[%thread]%-5level%logger{50}-%msg%n ${LOG_HOME}/info/info.log.%d{yyyy-MM-dd}.log 30 %d{yyyy-MM-ddHH:mm:ss.SSS}[%thread]%-5level%logger{50}-%msg%n 500MB ${LOG_HOME}/error/error.log.%d{yyyy-MM-dd}.log 30 %d{yyyy-MM-ddHH:mm:ss.SSS}[%thread]%-5level%logger{50}-%msg%n 500MB error ACCEPT DENY com.mysql.cj.jdbc.Driver jdbc:mysql://127.0.0.1:3306/logdb?serverTimezone=Asia/Shanghai root 123456
三、创建数据库表
在ch.qos.logback.classic.db包下可以找到对应数据库的表创建语句
mysql的数据库sql语句:
BEGIN; DROPTABLEIFEXISTSlogging_event_property; DROPTABLEIFEXISTSlogging_event_exception; DROPTABLEIFEXISTSlogging_event; COMMIT; BEGIN; CREATETABLElogging_event ( timestmpBIGINTNOTNULL, formatted_messageTEXTNOTNULL, logger_nameVARCHAR(254)NOTNULL, level_stringVARCHAR(254)NOTNULL, thread_nameVARCHAR(254), reference_flagSMALLINT, arg0VARCHAR(254), arg1VARCHAR(254), arg2VARCHAR(254), arg3VARCHAR(254), caller_filenameVARCHAR(254)NOTNULL, caller_classVARCHAR(254)NOTNULL, caller_methodVARCHAR(254)NOTNULL, caller_lineCHAR(4)NOTNULL, event_idBIGINTNOTNULLAUTO_INCREMENTPRIMARYKEY ); COMMIT; BEGIN; CREATETABLElogging_event_property ( event_idBIGINTNOTNULL, mapped_keyVARCHAR(254)NOTNULL, mapped_valueTEXT, PRIMARYKEY(event_id,mapped_key), FOREIGNKEY(event_id)REFERENCESlogging_event(event_id) ); COMMIT; BEGIN; CREATETABLElogging_event_exception ( event_idBIGINTNOTNULL, iSMALLINTNOTNULL, trace_lineVARCHAR(254)NOTNULL, PRIMARYKEY(event_id,i), FOREIGNKEY(event_id)REFERENCESlogging_event(event_id) ); COMMIT;
四、测试
1、编写测试代码
@RunWith(SpringRunner.class) @SpringBootTest publicclassSpringboot02MybatisApplicationTests{ privatefinalLoggerlogger=LoggerFactory.getLogger(Springboot02MybatisApplicationTests.class); @Test publicvoidcontextLoads(){ logger.info("数据库日志info"); logger.error("数据库日志error"); } }
2、运行结果
五、自定义数据库表字段和存储内容
当然,默认的表字段那么多,存储了很多内容,但是我们很多时候只是自己打印的日志内容,为了节省磁盘空间,这个时候可以自定义存储字段和存储内容
步骤:
1、创建数据库表
DROPTABLEIFEXISTS`logging`; CREATETABLE`logging`( `id`BIGINT(20)NOTNULLAUTO_INCREMENT, `message`VARCHAR(300)NOTNULLCOMMENT'内容', `level_string`VARCHAR(254)NOTNULLCOMMENT'级别', `created_time`DATETIMENOTNULLCOMMENT'时间', `logger_name`VARCHAR(300)NOTNULLCOMMENT'全类名', PRIMARYKEY(`id`) )ENGINE=INNODBDEFAULTCHARSET=utf8COMMENT='自定义日志记录表'
2、重写DBAppender类为LogDBAppender类
packagecom.me.study.springboot02mybatis.config; importch.qos.logback.classic.spi.CallerData; importch.qos.logback.classic.spi.ILoggingEvent; importch.qos.logback.core.db.DBAppenderBase; importorg.springframework.context.annotation.Configuration; importjava.lang.reflect.Method; importjava.sql.Connection; importjava.sql.PreparedStatement; importjava.sql.SQLException; importjava.sql.Timestamp; @Configuration publicclassLogDBAppenderextendsDBAppenderBase{ protectedstaticfinalMethodGET_GENERATED_KEYS_METHOD; //插入sql protectedStringinsertSQL; //message日志内容 staticfinalintMESSAGE=1; //level_string staticfinalintLEVEL_STRING=2; //created_time时间 staticfinalintCREATE_TIME=3; //logger_name全类名 staticfinalintLOGGER_NAME=4; staticfinalStackTraceElementEMPTY_CALLER_DATA=CallerData.naInstance(); static{ //PreparedStatement.getGeneratedKeys()methodwasaddedinJDK1.4 MethodgetGeneratedKeysMethod; try{ //the getGeneratedKeysMethod=PreparedStatement.class.getMethod("getGeneratedKeys",(Class[])null); }catch(Exceptionex){ getGeneratedKeysMethod=null; } GET_GENERATED_KEYS_METHOD=getGeneratedKeysMethod; } @Override publicvoidstart(){ //将写好的sql语句赋值给insertSQL insertSQL=buildInsertSQL(); super.start(); } //自己写新增sql语句 privatestaticStringbuildInsertSQL(){ return"INSERTINTO`logging`(`message`,`level_string`,`created_time`,`logger_name`)"+ "VALUES(?,?,?,?)"; } @Override protectedMethodgetGeneratedKeysMethod(){ returnGET_GENERATED_KEYS_METHOD; } @Override protectedStringgetInsertSQL(){ returninsertSQL; } /** *主要修改的方法 * *@paramstmt *@paramevent *@throwsSQLException */ privatevoidbindLoggingEventWithInsertStatement(PreparedStatementstmt,ILoggingEventevent)throwsSQLException{ //event.getFormattedMessage()日志打印内容 Stringmessage=event.getFormattedMessage(); //如果只想存储自己打印的日志,可以这样写日志:logger.info("-XXXX") if(message.startsWith("-")){//判断日志消息首字母为-的日志,记录到数据库表 stmt.setString(MESSAGE,message); //event.getLevel().toString()日志级别 stmt.setString(LEVEL_STRING,event.getLevel().toString()); //newTimestamp(event.getTimeStamp())时间 stmt.setTimestamp(CREATE_TIME,newTimestamp(event.getTimeStamp())); //event.getLoggerName()全类名 stmt.setString(LOGGER_NAME,event.getLoggerName()); } } @Override protectedvoidsubAppend(ILoggingEventeventObject,Connectionconnection,PreparedStatementstatement)throwsThrowable{ bindLoggingEventWithInsertStatement(statement,eventObject); //Thisisexpensive...shouldwedoiteverytime? intupdateCount=statement.executeUpdate(); if(updateCount!=1){ addWarn("FailedtoinsertloggingEvent"); } } @Override protectedvoidsecondarySubAppend(ILoggingEventeventObject,Connectionconnection,longeventId)throwsThrowable{ } }
3、修改logback日志文件,引用自定义的LogDBAppender类
com.mysql.cj.jdbc.Driver jdbc:mysql://127.0.0.1:3306/logdb?serverTimezone=Asia/Shanghai root admin
4、测试运行
1)编写测试代码
@Test publicvoidcontextLoads(){ logger.info("-数据库日志info"); logger.error("-数据库日志error"); logger.info("一条不带‘-'的日志,看会不会记录如数据库"); }
2)运行结果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。