多线程结合自定义logback日志实现简单的工单日志输出
前言
这周学习了logback自定义日志格式、多线程基础、以及常见的定时器,本篇博客主要是结合以上知识实现一个简单的定时全部工单输出任务,再通过自定义的日志打印输出到控制台。
1.logback自定义日志
再说到logback自定义日志的时候,我们首先得了解它的三个主要类Logger(记录器)、Appender(附加器)、Layout(布局),首先Logger定义了我们的日志可以输出到哪几个地方,例如控制台、文件。appender是附加到记录器上面的,用来定义记录器的输出格式,例如输出到控制台的日志等级颜色,输出到硬盘的日志命名。Layout是将日志时间打印成字符串的组建。
1.1 自定义日志代码

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志存放路径 --> <property name="log.path" value="H:/logs/com/ku/wo/logs" />
<!--<property name="log.path" value="/home/com/ku/logs" />-->
<!-- 日志输出格式 -->
<!--<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />-->
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{20}) : %msg%n" /> <!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--<immediateFlush>true</immediateFlush>-->
<encoder>
<!-- %msg:日志打印详情 -->
<!-- %n:换行符 -->
<!-- %highlight():转换说明符以粗体红色显示其级别为ERROR的事件,红色为WARN,BLUE为INFO,以及其他级别的默认颜色。 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{20})) : %msg%n</pattern>
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
<charset>UTF-8</charset>
</encoder>
</appender> <!-- info 日志-->
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_info.log -->
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
<appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志文件路径和名称-->
<File>${log.path}/project_info.log</File>
<!--是否追加到文件末尾,默认为true-->
<append>true</append>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch><!-- 如果命中ERROR就禁止这条日志 -->
<onMismatch>ACCEPT</onMismatch><!-- 如果没有命中就使用这条规则 -->
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
<!-- 文件名:logs/project_info.2017-12-05.0.log -->
<!-- 注意:TimeBasedRollingPolicy中 %d令牌是强制性的,必须存在,要不会报错 -->
<fileNamePattern>${log.path}/project_info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天
如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
<maxHistory>30</maxHistory>
<!-- 每个日志文件到10mb的时候开始切分,最多保留30天,但最大到20GB,哪怕没到30天也要删除多余的日志 -->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!--编码器-->
<encoder>
<!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{20}) : %msg%n</pattern>
<!-- 记录日志的编码:此处设置字符集 - -->
<charset>UTF-8</charset>
</encoder>
</appender> <!-- error 日志-->
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_error.log -->
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
<appender name="error_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志文件路径和名称-->
<File>${log.path}/project_error.log</File>
<!--是否追加到文件末尾,默认为true-->
<append>true</append>
<!-- ThresholdFilter过滤低于指定阈值的事件。 对于等于或高于阈值的事件,ThresholdFilter将在调用其decision()方法时响应NEUTRAL。 但是,将拒绝级别低于阈值的事件 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level><!-- 低于ERROR级别的日志(debug,info)将被拒绝,等于或者高于ERROR的级别将相应NEUTRAL -->
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
<!-- 文件名:logs/project_error.2017-12-05.0.log -->
<!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 -->
<fileNamePattern>logs/project_error.%d.%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
<maxFileSize>5KB</maxFileSize>
</rollingPolicy>
<!--编码器-->
<encoder>
<!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
<pattern>${log.pattern}</pattern>
<!-- 记录日志的编码:此处设置字符集 - -->
<charset>UTF-8</charset>
</encoder>
</appender> <root level="INFO">
<!--控制台只有info及以上的才打印-->
<appender-ref ref="STDOUT" />
</root> <!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
<logger name="com.ku.wo" level="INFO">
<appender-ref ref="info_log" />
<appender-ref ref="error_log" />
</logger> <!-- 利用logback输入WomApplicationTests的sql日志,
注意:如果不加 additivity="false" 则此logger会将输出转发到自身以及祖先的logger中,就会出现日志文件中sql重复打印-->
<!--additivity="false"-->
<logger name="com.ku.wo.WomApplicationTests" level="DEBUG" additivity="false">
<appender-ref ref="info_log" />
<appender-ref ref="error_log" />
</logger> <!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" /> </configuration>
logback自定义日志格式
1.2 应用标签讲解
接下来讲解一下我的日志配置,首先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属性来控制是否覆盖祖先日志,避免重复打印。
1.3 参考链接(讲解非常详细)
https://blog.csdn.net/qq_39361915/article/details/117365725
2.多线程实现全部工单输出
在学习了几天时间的多线程基础的时候,我通过创建线程以及sleep函数来实现一个过3秒获取所有工单信息打印在控制台的小作业,主要是通过sleep函数使我创建的当前线程休眠三秒,再使用使用synchronize锁锁住共享资源类,实现共享资源互斥访问。
2.1 实现代码

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();
} }
多线程结合自定义日志实现定时器控制台打印
2.2 运行结果
上面的日志打印了输出时间,以及对应的线程名和该程序所在的包下面的类名,以及最后输出的所有工单信息。
多线程结合自定义logback日志实现简单的工单日志输出的更多相关文章
- Log4net创建日志及简单扩展
转:http://blog.csdn.net/CHENFEIYANG2009/article/details/5397342 1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log ...
- 使用Log4net创建日志及简单扩展
如何使用Log4net创建日志及简单扩展 1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的 ...
- iOS开发多线程篇—自定义NSOperation
iOS开发多线程篇—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UI ...
- 简单好用的日志管理工具 Logrotate
前言 日志就像程序的生命记录仪,详细记录下了程序运行的点点滴滴. 慎重的选择记录哪些日志:在茫茫日志海中寻找真正记录问题的日志,你是不想经历的: 精心的定时压缩转移日志:故障发生了,日志却丢了,此时的 ...
- centos shell编程6一些工作中实践脚本 nagios监控脚本 自定义zabbix脚本 mysql备份脚本 zabbix错误日志 直接送给bc做计算 gzip innobackupex/Xtrabackup 第四十节课
centos shell编程6一些工作中实践脚本 nagios监控脚本 自定义zabbix脚本 mysql备份脚本 zabbix错误日志 直接送给bc做计算 gzip innobacku ...
- 自定义日志注解 + AOP实现记录操作日志
需求:系统中经常需要记录员工的操作日志和用户的活动日志,简单的做法在每个需要的方法中进行日志保存操作, 但这样对业务代码入侵性太大,下面就结合AOP和自定义日志注解实现更方便的日志记录 首先看 ...
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
本文转自 :http://www.cnblogs.com/wendingding/p/3761730.html ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布 ...
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局 一.项目文件结构和plist文件 二.实现效果 三.代码示例 1.没有使用配套的类,而是直接使用xib文 ...
- 发布时去掉 debug 和 提醒日志,简单无侵入
在 proguard 文件中加入下面代码,让发布时去掉 debug 和 提醒日志,简单无侵入! -assumenosideeffects class android.util.Log { public ...
- LogCook 一个简单实用的Android日志管理工具
众所周知,日志的管理是软件系统很重要的一部分,千万不可忽略其重要性.完整的日志将会在系统维护中起着异常重要的作用,就好像磨刀不误砍柴工一样,日志就像对系统进行分析的工具,工具便捷了,对系统分析起来就能 ...
随机推荐
- Windows修改用户名
修改用户名 右键此电脑>>管理>>本地用户和组>>用户,找到要修改的用户,重命名 修改用户home目录名 1.激活管理员账号 右键此电脑>>管理> ...
- Layui分页与springboots
service.java public List<Menu> listAllMenuPage(PageData pd) throws Exception{ List<Menu> ...
- Vue router前端路由配置以及实现tab切换
vue router 安装:npm install vue-router或cnpm install vue-router或yarn add vue-router. 安装完成之后会在package.js ...
- char *setlocale(int category, const char *locale)
category -- 这是一个已命名的常量,指定了受区域设置影响的函数类别. LC_ALL 包括下面的所有选项. LC_COLLATE 字符串比较.参见 strcoll(). LC_CTYPE 字符 ...
- opened by another process write access was denied sourceinsight
Ubuntu 16.04 安装Samba 和 windows 安装Source Insight weixin_43764544 2021-01-07 15:23:03 23 收藏 文章标签: linu ...
- jmeter性能测试学习1_配置oracl jdbc连接
1.导入orcle驱动的jar包 2.添加配置元件选择 JDBC连接配置 3.添加取样器 JDBCrequest 4.添加观察树,运行 配好密码 OK
- java注解-最通俗易懂的讲解
来源:秒懂,Java 注解 (Annotation)你可以这样学 Annotation 中文译过来就是注解.标释的意思,在 Java 中注解是一个很重要的知识点,但经常还是有点让新手不容易理解. 我个 ...
- OSIDP-I/O管理和磁盘调度-11
I/O设备 I/O设备分类:人可读.机器可读和远程通信三类. I/O设备之间的差别: 1.数据传送速率 2.应用领域 3.控制的复杂性 4.传送单位 5.数据表示形式 6.错误条件 I/O功能的组织 ...
- spring管理配置文件实现注入
创建配置文件 写入以下内容: 创建配置文件的bean: <bean id="configProperties" class="org.springframework ...
- 《JavaScript高级程序设计》Chapter04 变量,作用域,内存
原始值&引用值 原始值(primitive value):Undefined, Null, Boolean, Number, String, Symbol 按值访问,直接操作存储在变量中的实际 ...
