spring boot 日志记录

前言:

        关于项目生产中产生的日志有很多种处理方式,有些小伙伴习惯放在数据库中,有些小伙伴习惯放在日志文件中等等,笔者觉得日志应该分类处理,比如像 error 这种日志应该放在数据库中便于查看,而普通日志 info 这些应该在日志文件中记录(当然这只是笔者个人的处理方式而已 0_0)。

环境:

        spring boot:2.2.1

        jdk:1.8

        log4j:2.11.1

        项目源码:https://github.com/XGLLHZ/springboot-frame.git

正文:

1、创建日志实体:

@Data
@Accessors(chain = true)
@TableName("sys_log")
public class LogEntity extends BaseEntityUtil {

    @TableId(type = IdType.AUTO)
    private Integer id;   //主键

    private String className;   //类名称

    private String methodName;   //方法名称

    private String exceptionName;   //异常类型

    private String errorMsg;   //错误信息

    private String stackTrace;   //堆栈跟踪信息

    private Integer deleteFlag;   //删除状态:0:未删除;1:已删除

    private Timestamp createTime;   //创建时间

    private Timestamp updateTime;   //修改时间

}

        然创建对应的日志记录表。

2、编写日志记录处理类:       

@Component
public class LogAppenderConfig extends UnsynchronizedAppenderBase<ILoggingEvent> {

    private static final Logger log = LoggerFactory.getLogger(LogAppenderConfig.class);

    @Autowired
    LogMapper logMapper;

    /**
     * LogAppenderConfig 初始化(服务启动时初始化)
     */
    @PostConstruct
    public void init() {
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();

        ThresholdFilter filter = new ThresholdFilter();
        filter.setLevel("ERROR");
        filter.setContext(context);
        filter.start();
        this.addFilter(filter);
        this.setContext(context);

        context.getLogger("ROOT").addAppender(LogAppenderConfig.this);

        super.start();
    }

    /**
     * error 日志写入数据库
     * @param iLoggingEvent
     */
    @Override
    protected void append(ILoggingEvent iLoggingEvent) {
        IThrowableProxy iThrowableProxy = iLoggingEvent.getThrowableProxy();
        LogEntity logEntity = new LogEntity();
        //异常信息
        logEntity.setErrorMsg(iLoggingEvent.getMessage());
        //异常产生时间
        logEntity.setCreateTime(new Timestamp(iLoggingEvent.getTimeStamp()));
        if (iLoggingEvent.getCallerData() != null && iLoggingEvent.getCallerData().length > 0) {
            StackTraceElement stackTraceElement = iLoggingEvent.getCallerData()[0];
            //异常产生类名称
            logEntity.setClassName(stackTraceElement.getClassName());
            //异常产生方法名
            logEntity.setMethodName(stackTraceElement.getMethodName());
        }
        if (iThrowableProxy != null) {
            //异常类型
            logEntity.setExceptionName(iThrowableProxy.getClassName());
            //异常堆栈跟踪信息
            logEntity.setStackTrace(Arrays.toString(iThrowableProxy.getStackTraceElementProxyArray()));
        }
        try {
            logMapper.insert(logEntity);
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
    }

}

         这个类是我们自己定义的负责记录日志事件工具类,相当于 logback 中的 Appender,ILoggingEvent 可以从堆栈信息中取到文件名、类名、时间等信息,它是可以序列化的对象。我们可以从这个类中拿到关于异常的类名、异常类型、时间等信息。然后创建初始化 LogAppenderConfig 的方法 init(),加上 @PostConstruct 注解,意为在服务启动时执行此方法,也就是在服务启动时初始化 LogAppenderConfig 实例。然后实现 UnsynchronizedAppenderBase 接口中的 append() 方法, 在这个方法中将日志写入数据库(异常日志)。

3、日志收集:

@RestController
@RequestMapping("/web")
public class WebTestController {

    private static final Logger log = LoggerFactory.getLogger(WebTestController.class);

    @RequestMapping("/test")
    public String test() {
        String s = null;
        try {
            s.charAt(0);   //在搞一个空指针异常
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return "Hello Web!";
    }

}

        我们可以创建一个接口自定义一个异常来测试。在实际开发中,我们在会产生异常的地方加入日志记录,如果产生异常,则会将异常信息记录到数据库。 实际上正确的做法是利用切面编程来统一管理日志,然后在放入数据库。

4、测试:

        通过测试我们发现在控制已经出现了空指针异常,查看数据库,异常信息已经被记录。

        注:关于 info 等小级别的日志,我们可以将其记录在日志文件中,比如在项目部署时将日志挂载到宿主机的文件中即可。

 

 

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值