多线程结合自定义logback日志实现简单的工单日志输出
阅读原文时间:2023年07月09日阅读:1

前言

  这周学习了logback自定义日志格式、多线程基础、以及常见的定时器,本篇博客主要是结合以上知识实现一个简单的定时全部工单输出任务,再通过自定义的日志打印输出到控制台。

1.logback自定义日志

  再说到logback自定义日志的时候,我们首先得了解它的三个主要类Logger(记录器)、Appender(附加器)、Layout(布局),首先Logger定义了我们的日志可以输出到哪几个地方,例如控制台、文件。appender是附加到记录器上面的,用来定义记录器的输出格式,例如输出到控制台的日志等级颜色,输出到硬盘的日志命名。Layout是将日志时间打印成字符串的组建。




%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{20})) : %msg%n UTF-8


${log.path}/project_info.log true ERROR DENY ACCEPT ${log.path}/project_info.%d{yyyy-MM-dd}.log 30 20GB %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{20}) : %msg%n UTF-8


${log.path}/project_error.log true ERROR logs/project_error.%d.%i.log 30 20GB 5KB ${log.pattern} UTF-8




logback自定义日志格式

  接下来讲解一下我的日志配置,首先configuration标签概括logger和appender标签,以及一些properties标签。设置一些properties标签来赋值我们的日志输出路径、日志打印格式等等。

appender标签。

  在输出日志中,我们主要使用appender的class指明RollingFileAppender来实现文件日志,它是FileAppender的子类,RollingFileAppender有两个重要的子组件,分别是RollingPolicy、TriggerPolicy,前者负责翻滚所需操作,后者负责啥时候翻滚所需操作。在文件日志中,RollingFileAppender需要同时设置RollingPolicy和TriggerPolicy。如果RollingPolicy中设置了TriggerPolicy,只需实现前者就行。

  在滚动策略中,因为堆日志文档需求不同,延伸出了两种滚动策略分别是按天或月翻滚的TimeBaseRollingPolicy和按日期和限制文件大小的SizeAndTimeBaseRollingPolicy,两者都实现了RollingPolicy和TriggerPolicy。

  • 其中appender标签包含name以及class属性,后者决定他属于哪种输出,如控制台输出、日志文件输出,前者是它的别名,用于后面附加给logger。
  • encoder标签决定你打印的日志的输出格式以及编码,例如pattern标签是用来指明你的日志输出格式,chartset决定你的编码。
  • File人标签指明你的日志文件存储路径以及名字
  • append指明是否将新的日志内容追加到文件末尾,Ture表示追加,false则相反。
  • filter标签可以用来过滤输出日志级别,当在该日志级别及以上就输出,在该日志级别以下就不输出。
  • fileNamePattern为防止之前的文件日志被当前文件日志所覆盖所创建的标签,主要通过通过设置日期以及%d来表示使用每天日期进行命名。
  • maxHistory表示文件日志存储最长时间
  • totalSizeCap表示存储所有文件日志的大小总和。
  • maxFileSize表示单个文件日志的最大存储内存。
  • root表示根路径,可以将控制台附加器添加进去用于输出控制器日志。
  • logger标签就是用来输出日志的,可以添加additivity属性来控制是否覆盖祖先日志,避免重复打印。

https://blog.csdn.net/qq_39361915/article/details/117365725

2.多线程实现全部工单输出

  在学习了几天时间的多线程基础的时候,我通过创建线程以及sleep函数来实现一个过3秒获取所有工单信息打印在控制台的小作业,主要是通过sleep函数使我创建的当前线程休眠三秒,再使用使用synchronize锁锁住共享资源类,实现共享资源互斥访问。

package com.ku.wo.timer;

import com.ku.wo.entity.WorkOrder;
import com.ku.wo.mapper.WorkOrderMapper;
import com.ku.wo.service.impl.WorkOrderServiceImpl;
import com.ku.wo.utils.GetBeanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/*
想法是每天将每过6小时将工单推送给uid为1的人,即管理者,如果使用spring task其实很容易就可以实现,当然tread也可以
只不过是改参数的问题;消息推送应该要用到文websocket,暂时自己还不会,所以先就做每隔几秒钟获取全部工单信息把
*/
@Component//这个地方的注入还是可能存在问题
public class WorkOrderTimer {
//通过接口调用自定义logback日志
Logger logger = LoggerFactory.getLogger(WorkOrderTimer.class);
@Autowired//通过该注解实现对象注入
private WorkOrderServiceImpl workOrderService;
public WorkOrderTimer(){
getAllWorkOrders();
}

public void getAllWorkOrders(){

    new Thread(() -> {  
        while(true){  
            synchronized (WorkOrderServiceImpl.class){  
                Integer uid = 9;  
                String username = "xiaoku";  
                List<WorkOrder> allWorkOrder = workOrderService.getAllWorkOrder(uid, username);  
                try {  
                    Thread.sleep(3000);//休眠三秒再次查询  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                //System.out.println(allWorkOrder);  
                logger.info("result :{}", allWorkOrder);  
            }  
        }  
    },"t1").start();  
}

}

多线程结合自定义日志实现定时器控制台打印

  上面的日志打印了输出时间,以及对应的线程名和该程序所在的包下面的类名,以及最后输出的所有工单信息。