logback实时记录日志 保存入库
Posted 独行侠飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了logback实时记录日志 保存入库相关的知识,希望对你有一定的参考价值。
需求:收集系统中打印的日志,例如 log.info(), log.warn(),log.infor(),log.debug()等等,并且做入库处理。
public static void main(String[] args) {
System.setProperty("es.set.netty.runtime.available.processors", "false");
SpringApplication.run(DelayqueuetestApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
log.info("哈哈哈哈哈哈info");
log.warn("哈哈哈哈哈哈warn");
log.debug("哈哈哈哈哈哈debug");
log.error("哈哈哈哈哈哈error");
}
方案具体实现:利用logback自带的appender
logback自带的appender
ConsoleAppender 将日志输出到控制台
FileAppender 将日志输出到文件
RollingFileAppender 滚动文件生成,按条件生成不同文件,配合TriggeringPolicy使用
SocketAppender 输出日志到远程实例中,明文传输
SSLSocketAppender 输出日志到远程实例中,密文传输
SMTPAppender 将日志输出到邮件
DBAppender 日志事件插入数据库中,需要提前创建表
SyslogAppender 是一个SocketAppender,将日志输出到远程系统日志
SiftingAppender 可基于任何给定的实时属性分开(或者筛选)日志,如基于用户会话分开日志事件
AmqpAppender 将日志输出到MQ服务中
xml配置中其中class指定为logAd的类全路径
<appender name="STDOUT" class="com.example.delayqueuetest.log.LogAd">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
让其继承ConsoleAppender类,重写append()方法,这样系统运行后,
如果遇到打印log.info类似语句 就会执行append()方法。
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.ConsoleAppender;
import com.alibaba.fastjson.JSON;
import com.example.delayqueuetest.model.Log;
/**
* 继承ConsoleAppender 重写append方法
* 收集系统中所有的 log.info error warn debug 等打印语句 然后入库
* @date 2019年5月9日
* @author dongzhuo
*/
public class LogAd extends ConsoleAppender<ILoggingEvent> {
@Override
protected void append(ILoggingEvent eventObject) {
Log log = new Log(eventObject.getLoggerName(), eventObject.getMessage(), eventObject.getThreadName(), String.valueOf(eventObject.getTimeStamp()),eventObject.getLevel().toString());
//添加到阻塞队列
DataContext.tempLogQueue.add(log) ;
System.err.println(JSON.toJSONString(log,true));
}
}
其中IloggingEvent类详细参数如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package ch.qos.logback.classic.spi;
import ch.qos.logback.classic.Level;
import ch.qos.logback.core.spi.DeferredProcessingAware;
import java.util.Map;
import org.slf4j.Marker;
public interface ILoggingEvent extends DeferredProcessingAware {
String getThreadName();
Level getLevel();
String getMessage();
Object[] getArgumentArray();
String getFormattedMessage();
String getLoggerName();
LoggerContextVO getLoggerContextVO();
IThrowableProxy getThrowableProxy();
StackTraceElement[] getCallerData();
boolean hasCallerData();
Marker getMarker();
Map<String, String> getMDCPropertyMap();
/** @deprecated */
Map<String, String> getMdc();
long getTimeStamp();
void prepareForDeferredProcessing();
}
Log类如下:
@Data
@AllArgsConstructor
public class Log {
/**
* 类的全路径名称
*/
private String loggerName;
/**
* 打印的消息
*/
private String message;
/**
* 线程名称
*/
private String threadName;
/**
* 时间戳 日志打印的时间
*/
private String timeStamp;
/**
* 日志打印级别
*/
private String level;
}
控制台打印如下
{
"level":"INFO",
"loggerName":"com.example.delayqueuetest.DelayqueuetestApplication",
"message":"哈哈哈哈哈哈info",
"threadName":"main",
"timeStamp":"1557389007586"
}
{
"level":"WARN",
"loggerName":"com.example.delayqueuetest.DelayqueuetestApplication",
"message":"哈哈哈哈哈哈warn",
"threadName":"main",
"timeStamp":"1557389007586"
}
{
"level":"ERROR",
"loggerName":"com.example.delayqueuetest.DelayqueuetestApplication",
"message":"哈哈哈哈哈哈error",
"threadName":"main",
"timeStamp":"1557389007586"
}
知道以上信息,就可以做后续的操作了,保存数据库即可,数据库设计省略。目前线上系统 是拿到日志实体 放入一个阻塞队列,然后开启定时器 对这个队列做take操作,take()自带阻塞功能,很好的实现异步保存日志功能。
@Configuration
@EnableScheduling
public class LogTask {
@Autowired
private LogRepository logRes;
/**
* 接着上一次程序跑完后的5秒后执行
*/
@Scheduled(fixedDelay= 5000)
public void log(){
/**
* 日志处理
*/
Log log = null ;
while((log = DataContext.tempLogQueue.poll()) != null){
SystemConfig systemConfig = UKTools.getSystemConfig();
if(systemConfig!=null && systemConfig.isSavelog()) {
logRes.save(log) ;
}
}
}
}
其中队列为:在DataContext类中定义了阻塞队列。
public static BlockingQueue<Log> tempLogQueue = new LinkedBlockingQueue<>();
文章参考
https://www.cnblogs.com/warking/p/5710303.html
以上是关于logback实时记录日志 保存入库的主要内容,如果未能解决你的问题,请参考以下文章