前言

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

1.logback自定义日志

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

1.1 自定义日志代码

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration>
  3. <!-- 日志存放路径 -->
  4.  
  5. <property name="log.path" value="H:/logs/com/ku/wo/logs" />
  6. <!--<property name="log.path" value="/home/com/ku/logs" />-->
  7. <!-- 日志输出格式 -->
  8. <!--<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />-->
  9. <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{20}) : %msg%n" />
  10.  
  11. <!-- 控制台输出 -->
  12. <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
  13. <!--<immediateFlush>true</immediateFlush>-->
  14. <encoder>
  15. <!-- %msg:日志打印详情 -->
  16. <!-- %n:换行符 -->
  17. <!-- %highlight():转换说明符以粗体红色显示其级别为ERROR的事件,红色为WARN,BLUE为INFO,以及其他级别的默认颜色。 -->
  18. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{20})) : %msg%n</pattern>
  19. <!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
  20. <charset>UTF-8</charset>
  21. </encoder>
  22. </appender>
  23.  
  24. <!-- info 日志-->
  25. <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
  26. <!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_info.log -->
  27. <!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
  28. <appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
  29. <!--日志文件路径和名称-->
  30. <File>${log.path}/project_info.log</File>
  31. <!--是否追加到文件末尾,默认为true-->
  32. <append>true</append>
  33. <filter class="ch.qos.logback.classic.filter.LevelFilter">
  34. <level>ERROR</level>
  35. <onMatch>DENY</onMatch><!-- 如果命中ERROR就禁止这条日志 -->
  36. <onMismatch>ACCEPT</onMismatch><!-- 如果没有命中就使用这条规则 -->
  37. </filter>
  38. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  39. <!-- 日志文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
  40. <!-- 文件名:logs/project_info.2017-12-05.0.log -->
  41. <!-- 注意:TimeBasedRollingPolicy中 %d令牌是强制性的,必须存在,要不会报错 -->
  42. <fileNamePattern>${log.path}/project_info.%d{yyyy-MM-dd}.log</fileNamePattern>
  43. <!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天
  44. 如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
  45. <maxHistory>30</maxHistory>
  46. <!-- 每个日志文件到10mb的时候开始切分,最多保留30天,但最大到20GB,哪怕没到30天也要删除多余的日志 -->
  47. <totalSizeCap>20GB</totalSizeCap>
  48. </rollingPolicy>
  49. <!--编码器-->
  50. <encoder>
  51. <!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
  52. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{20}) : %msg%n</pattern>
  53. <!-- 记录日志的编码:此处设置字符集 - -->
  54. <charset>UTF-8</charset>
  55. </encoder>
  56. </appender>
  57.  
  58. <!-- error 日志-->
  59. <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
  60. <!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_error.log -->
  61. <!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
  62. <appender name="error_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
  63. <!--日志文件路径和名称-->
  64. <File>${log.path}/project_error.log</File>
  65. <!--是否追加到文件末尾,默认为true-->
  66. <append>true</append>
  67. <!-- ThresholdFilter过滤低于指定阈值的事件。 对于等于或高于阈值的事件,ThresholdFilter将在调用其decision()方法时响应NEUTRAL。 但是,将拒绝级别低于阈值的事件 -->
  68. <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  69. <level>ERROR</level><!-- 低于ERROR级别的日志(debug,info)将被拒绝,等于或者高于ERROR的级别将相应NEUTRAL -->
  70. </filter>
  71. <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
  72. <!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
  73. <!-- 文件名:logs/project_error.2017-12-05.0.log -->
  74. <!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 -->
  75. <fileNamePattern>logs/project_error.%d.%i.log</fileNamePattern>
  76. <maxHistory>30</maxHistory>
  77. <totalSizeCap>20GB</totalSizeCap>
  78. <maxFileSize>5KB</maxFileSize>
  79. </rollingPolicy>
  80. <!--编码器-->
  81. <encoder>
  82. <!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
  83. <pattern>${log.pattern}</pattern>
  84. <!-- 记录日志的编码:此处设置字符集 - -->
  85. <charset>UTF-8</charset>
  86. </encoder>
  87. </appender>
  88.  
  89. <root level="INFO">
  90. <!--控制台只有info及以上的才打印-->
  91. <appender-ref ref="STDOUT" />
  92. </root>
  93.  
  94. <!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
  95. <!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
  96. <logger name="com.ku.wo" level="INFO">
  97. <appender-ref ref="info_log" />
  98. <appender-ref ref="error_log" />
  99. </logger>
  100.  
  101. <!-- 利用logback输入WomApplicationTests的sql日志,
  102. 注意:如果不加 additivity="false" 则此logger会将输出转发到自身以及祖先的logger中,就会出现日志文件中sql重复打印-->
  103. <!--additivity="false"-->
  104. <logger name="com.ku.wo.WomApplicationTests" level="DEBUG" additivity="false">
  105. <appender-ref ref="info_log" />
  106. <appender-ref ref="error_log" />
  107. </logger>
  108.  
  109. <!-- Spring日志级别控制 -->
  110. <logger name="org.springframework" level="warn" />
  111.  
  112. </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 参考链接(讲解非常详细)

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

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

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

2.1 实现代码

  1. package com.ku.wo.timer;
  2.  
  3. import com.ku.wo.entity.WorkOrder;
  4. import com.ku.wo.mapper.WorkOrderMapper;
  5. import com.ku.wo.service.impl.WorkOrderServiceImpl;
  6. import com.ku.wo.utils.GetBeanUtil;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.stereotype.Component;
  11.  
  12. import java.util.List;
  13.  
  14. /*
  15. 想法是每天将每过6小时将工单推送给uid为1的人,即管理者,如果使用spring task其实很容易就可以实现,当然tread也可以
  16. 只不过是改参数的问题;消息推送应该要用到文websocket,暂时自己还不会,所以先就做每隔几秒钟获取全部工单信息把
  17. */
  18. @Component//这个地方的注入还是可能存在问题
  19. public class WorkOrderTimer {
  20. //通过接口调用自定义logback日志
  21. Logger logger = LoggerFactory.getLogger(WorkOrderTimer.class);
  22. @Autowired//通过该注解实现对象注入
  23. private WorkOrderServiceImpl workOrderService;
  24. public WorkOrderTimer(){
  25. getAllWorkOrders();
  26. }
  27.  
  28. public void getAllWorkOrders(){
  29.  
  30. new Thread(() -> {
  31. while(true){
  32. synchronized (WorkOrderServiceImpl.class){
  33. Integer uid = 9;
  34. String username = "xiaoku";
  35. List<WorkOrder> allWorkOrder = workOrderService.getAllWorkOrder(uid, username);
  36. try {
  37. Thread.sleep(3000);//休眠三秒再次查询
  38. } catch (InterruptedException e) {
  39. e.printStackTrace();
  40. }
  41. //System.out.println(allWorkOrder);
  42. logger.info("result :{}", allWorkOrder);
  43. }
  44. }
  45. },"t1").start();
  46. }
  47.  
  48. }

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

2.2 运行结果

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

多线程结合自定义logback日志实现简单的工单日志输出的更多相关文章

  1. Log4net创建日志及简单扩展

    转:http://blog.csdn.net/CHENFEIYANG2009/article/details/5397342 1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log ...

  2. 使用Log4net创建日志及简单扩展

    如何使用Log4net创建日志及简单扩展 1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的 ...

  3. iOS开发多线程篇—自定义NSOperation

    iOS开发多线程篇—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UI ...

  4. 简单好用的日志管理工具 Logrotate

    前言 日志就像程序的生命记录仪,详细记录下了程序运行的点点滴滴. 慎重的选择记录哪些日志:在茫茫日志海中寻找真正记录问题的日志,你是不想经历的: 精心的定时压缩转移日志:故障发生了,日志却丢了,此时的 ...

  5. centos shell编程6一些工作中实践脚本 nagios监控脚本 自定义zabbix脚本 mysql备份脚本 zabbix错误日志 直接送给bc做计算 gzip innobackupex/Xtrabackup 第四十节课

    centos   shell编程6一些工作中实践脚本   nagios监控脚本 自定义zabbix脚本 mysql备份脚本 zabbix错误日志  直接送给bc做计算  gzip  innobacku ...

  6. 自定义日志注解 + AOP实现记录操作日志

      需求:系统中经常需要记录员工的操作日志和用户的活动日志,简单的做法在每个需要的方法中进行日志保存操作, 但这样对业务代码入侵性太大,下面就结合AOP和自定义日志注解实现更方便的日志记录   首先看 ...

  7. ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局

    本文转自 :http://www.cnblogs.com/wendingding/p/3761730.html ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布 ...

  8. iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局

    iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局 一.项目文件结构和plist文件 二.实现效果 三.代码示例 1.没有使用配套的类,而是直接使用xib文 ...

  9. 发布时去掉 debug 和 提醒日志,简单无侵入

    在 proguard 文件中加入下面代码,让发布时去掉 debug 和 提醒日志,简单无侵入! -assumenosideeffects class android.util.Log { public ...

  10. LogCook 一个简单实用的Android日志管理工具

    众所周知,日志的管理是软件系统很重要的一部分,千万不可忽略其重要性.完整的日志将会在系统维护中起着异常重要的作用,就好像磨刀不误砍柴工一样,日志就像对系统进行分析的工具,工具便捷了,对系统分析起来就能 ...

随机推荐

  1. 消息队列 RocketMQ4.x介绍和新概念讲解

    消息队列 RocketMQ4.x介绍和新概念讲解 Apache RocketMQ作为阿里开源的一款高性能.高吞吐量的分布式消息中间件 RocketMQ4.x特点 支持Broker和Consumer端消 ...

  2. 2022-03-02英语精读(Returning Youths)

    今天早上没写代码,记录一下英语学习吧~ flee to sw/ from sb(sth)----coastal city-----get one's break----clinch a job/ de ...

  3. 12.20linux学习第十九天

    今天老刘开始讲第17章 使用iSCSI服务部署网络存储.第18章 使用MariaDB数据库管理系统和第19章 使用PXE+Kickstart无人值守安装服务,内容有点多. 7.1 iSCSI技术介绍 ...

  4. 乘积小于K的子数组

    乘积小于K的子数组 给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目. 示例 1: 输入:nums = [10,5,2,6], k = 10 ...

  5. git的基础指令练习

    #版本回退 git reset commitId --hard

  6. DNS服务学习笔记

    1.基本概念 ​ DNS(Domain Name System)域名系统,在TCP/IP网络中有非常重要的地位,能够提供域名与IP地址的解析服务. ​ DNS是一个分布式数据库,命名系统采用层次的逻辑 ...

  7. Using Semaphores in Delphi, Part 2: The Connection Pool

    Abstract: Semaphores are used to coordinate multiple threads and processes. That semaphores provide ...

  8. nodejs 反单引号用法(·)

    这个反单引号就是数字1旁边(~)下面的那个符号,平时用得很少,虽然单引号和双引号是使用较多的,但我们还有第三个方案,就是ES6中的模板字符串(反引号). 在nodejs中用反单引号(·)主要基于以下作 ...

  9. shell命令查找文件

    1.find命令的参数下面是find命令一些常用参数的例子,有用到的时候查查就行了,像上面前几个贴子,都用到了其中的的一些参数,也可以用man或查看论坛里其它贴子有find命令手册使用name选项文件 ...

  10. 通过cpolar内网穿透 https://blog.csdn.net/CpolarLisa/article/details/128148698

    远程办公:通过cpolar内网穿透,远程桌面控制家里公司内网电脑_Cpolar Lisa的博客-CSDN博客 https://blog.csdn.net/CpolarLisa/article/deta ...