SpringBoot(三) - Slf4j+logback 日志,异步请求,定时任务
1、Slf4j+logback 日志
SpringBoot框架的默认日志实现:slf4j + logback;
默认日志级别:info,对应了实际生产环境日志级别;
1.1 日志级别
# 常见的日志框架中,日志级别都包含五种,优先级从低到高:
trace < debug < info < warn < error
#日志输出规则是:
自动设置的日志级及更高级别,进行日志输出;
比如当前日志级别是info,那么日志输出的级别包含:info,warn,error,凡是业务的这三个级别,都会输出到日志文件
1.1.1 trace 日志级别
trace 日志级别,了解,实际开发中,几乎不会使用此级别;(配置文件指定为 trace 级别才会输出);
logger.trace("------------ trace 日志级别,了解,实际开发中,几乎不会使用此级别 ------------------");
1.1.2 debug 日志级别
- debug 日志级别,掌握,实际开发中,此日志级别作为调试日志使用,是线上调试问题定位的有效手段;
- 强调:线上一般默认是不开debug日志,因此日志级别记录的日志极为详情,会产生大量的日志内容及文件;
- 发现线上问题,不好定位时,临时开启debug;
logger.debug("------------ {} 日志级别,{},实际开发中,此日志级别作为调试日志使用,是线上调试问题定位的有效手段 ------------------","debug","掌握");
1.1.3 info 日志级别
info 日志级别,掌握,实际开发中,此日志级别是核心业务环境日志,不需要记录特别详细,一般都是接口 入和出,方便版本上线查看业务是否正常使用;
logger.info("------------ {} 日志级别,{},实际开发中,此日志级别时核心业务环境日志,不需要记录特别详细 ------------","info","掌握");
1.1.4 warn 日志级别
warn 日志级别,掌握,实际开发中,此日志级别是业务警告日志,警告日志不一定是错误,可能业务异常流程,或者数据错误判断;
logger.warn("------------ {} 日志级别,{},实际开发中,此日志级别时业务警告日志 ------------","warn","掌握");
1.1.5 error 日志级别
error 日志级别,掌握,实际开发中,此日志级别是核心业务错误,凡是系统中出现了异常或者程序错误,都必须使用error日志,级别最高,确保必须输出,可以有效的记录线上业务的错误;
logger.error("------------ {} 日志级别,{},实际开发中,此日志级别是核心业务错误 ------------","error","掌握");
1.2 日志使用
1.2.1 创建日志对象
//创建日志对象
Logger logger = LoggerFactory.getLogger(getClass());
logger.trace("");
logger.debug("");
logger.info("");
logger.warn("");
logger.error("");
1.2.2 @Slf4j 注解
@Slf4j
public class ChargeResultNotifySchedule{
log.trace("");
log.debug("");
log.info("");
log.warn("");
log.error("");
}
1.3 配置文件配置日志 信息
1.3.1 测试默认日志级别
1.3.1.1 直接运行测试类
1.3.1.2 测试类增加 @RunWith(SpringRunner.class) 注解
测试类增加 @RunWith(SpringRunner.class) 注解 运行的是SpringBoot项目测试,会读取到配置文件;
1.3.2 修改配置文件信息
1.3.2.1 修改默认日志级别为 debug
# 默认日志级别为 info ,更改默认日志级别debug
logging:
level:
com:
kgc:
sbt: debug
1.4 指定日志输出
1.4.1 指定日志输出到指定文件
- 默认日志只输出到控制台;
- 指定输出到指定文件,默认会加载到根路径下;
- 所有的日志,都是追加记录,不会执行覆盖;
logging:
file: kh96-logging.log
日志输出到根目录下的指定文件名下:
1.4.2 指定日志输入到指定目录下
不指定文件名,SpringBoot中的logback会由默认的日志名spring.log;
logging:
path: D:/KEGONGCHANG/DaiMa/IDEA/KH96/SpringBoot/SpringBoot/TempFile/kh96-logging2
默认名:
输出文件:
1.4.3 指定输出格式
# 了解 %d日期,%thread 线程名称,%-5leavel 日志级别 %logger{50} 日志类路径 %msg 日志内容
logging:
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} +++ [%thread] +++ %-5level +++ %logger{100} +++ %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss} +++ [%thread] +++ %-5level +++ %logger{100} +++ %msg%n
1.4.4 指定输入格式文件
网上由很多;
<?xml version="1.0" encoding="UTF-8"?>
<!--
scan:配置文件发生改变,是否被重新加载,默认值为true。
scanPeriod:设置监测配置文件是否有修改的时间间隔,当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:是否打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志的根目录,可以自动创建log目录,一般公司都是统一的日志目录,不能乱写 -->
<property name="LOG_HOME" value="D:/KEGONGCHANG/DaiMa/IDEA/KH96/SpringBoot/SpringBoot/TempFile/log" />
<!-- 日志文件名称 -->
<property name="appName" value="log-sbt-kh96"/>
<!-- 控制台输出 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<!--
日志输出格式:
%d{日期时间格式},
%thread:线程名,
%-5level:级别从左显示5个字符宽度
%logger{60} 表示logger名字最长60个字符,否则按照句点分割。
%msg:记录的日志消息,
%n是换行符
-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{60} - %msg%n</pattern>
</layout>
</appender>
<!-- 滚动文件记录,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
<appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 指定服务器记录日志文件的名称 -->
<file>${LOG_HOME}/${appName}.log</file>
<!--
当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名
TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责触发滚动。
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--
滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动
%i:当文件大小超过maxFileSize时,按照i进行文件滚动
-->
<fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!--
可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,
且maxHistory是30,则只保存最近30天的文件,删除之前的旧文件。注意,删除旧文件时,
那些为了归档而创建的目录也会被删除。
-->
<MaxHistory>30</MaxHistory>
<!--
当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy
-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>30MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 日志输出格式: -->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{60} : %line ] - %msg%n</pattern>
</layout>
</appender>
<!--
logger主要用于存放日志对象,也可以定义日志类型、级别
name:表示匹配的logger类型前缀,也就是包的前半部分
level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR
additivity:作用在于当前logger配置是否使用 rootLogger配置的appender进行输出,即此logger的打印信息是否向上级传递
false:表示只用当前logger的appender-ref
true:表示当前logger的appender-ref和rootLogger的appender-ref都有效
-->
<!-- 此种没有指定自己的appender-ref,所以直接使用root标签的配置 -->
<logger name="com.kgc.sbt" level="debug" />
<logger name="org.springframework" level="debug"/>
<!--
root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,
要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。
-->
<root level="debug">
<appender-ref ref="stdout" />
<appender-ref ref="appLogAppender" />
</root>
</configuration>
2、异步请求
2.1 异步请求处理实现类
@Service
@Slf4j
public class ChargeServiceImpl implements ChargeService{
@Override
@Async
//开启异步线程注解,如果是同一个类中的其他方法,添加此异步处理注解,异步是不生效的
//使用的是Spring内置的线程池
public void executesAsynCharge(String chargeTel, Double chargeMoney) {
try {
TimeUnit.MILLISECONDS.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}
log.info("********* 异步渠道 充值成功,充值手机号:{},充值金额:{} ************",chargeTel,chargeMoney);
}
}
2.2 主启动类
主启动类上必须增加@EnableAsync 注解,开启异步处理功能;
@SpringBootApplication
@EnableAsync //开启异步处理功能
public class Springboot03AsyztimerApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot03AsyzyimerApplication.class, args);
}
}
2.3 请求调用异步处理方法
@RestController
@Slf4j
public class ChargeController {
@Autowired
ChargeService chargeService;
@GetMapping("/asyncCharge")
public String asyncCharge(@RequestParam("chargeTel") String chargeTel,@RequestParam("chargeMoney") Double chargeMoney){
log.info("------ 开始充值,充值手机号:{},充值金额:{} 开始调用充值渠道充值 --------- ",chargeTel,chargeMoney);
// log startTimeMillis = System.currentTimeMillis(); //旧的获取当前时间毫秒数
long startTimeMillis = Instant.now().toEpochMilli();
//调用充值渠道 异步 充值
chargeService.executesAsynCharge(chargeTel,chargeMoney);
long finishTimeMillis = Instant.now().toEpochMilli();
log.info("------ 结束充值,充值手机号:{},充值金额:{} ,充值总耗时:{}-----------",chargeTel,chargeMoney,finishTimeMillis-startTimeMillis);
return String.format("%s充值%s成功!",chargeTel,chargeMoney);
}
}
3、定时任务
3.1 场景
异步充值结果,定时批量回调订单;
public void chargeResultNotifyMethodOne(){
//模拟从数据库获取5笔需要回调的充值订单,进行批量回调结果
List<String> chargeOrderList = Arrays.asList("KH001","KH002","KH003","KH004","KH005");
//循环处理需要回调的5笔订单
log.info("---------- 开始 执行批量回调充值结果------------");
chargeOrderList.forEach(chargeOrderNo->{
log.info("***** 充值订单:{},回调重接成功! ******");
try{
TimeUnit.MILLISECONDS.sleep(100);
}catch (Exception e){
e.printStackTrace();
}
log.info("---------- 结束 执行批量回调充值结果 ------------");
});
}
3.2 注解
3.2.1 @Scheduled(fixedDelay = 5 * 1000)
fixedDelay :计时规则: 从上一次执行结束 开始计时 到 下一次定时任务开始 ,不关心前一次定时任务耗时多久;
3.2.2 @Scheduled(fixedRate = 5 * 1000)
fixedRate: 计时规则:从上一次定时任务执行开始 开始计时 到 下一次定时任务开始,如果上一次定时任务 超过定时,上一次执行完后,下一次立即执行;
3.2.3 @Scheduled(cron = "*/5 * * * * ?")
cron表达式:既可以是实现循环时间间隔,执行定时任务,也可以执行某个时刻的定时任务,通过指定表达式实现的,灵活度是三种最高的
1)循环定时: 每次执行的定时任务时间点,是由cron表达是决定的,其实都是预置好的;比如5秒,5秒执行一次定时
2)定点定时:在指定的某个时刻,执行一次定时任务
秒 分 时 日 月 周
@Scheduled(cron = "*/5 * * * * ?")
3.2.4 @EnableScheduling
@SpringBootApplication
@EnableScheduling //开启定时任务功能
public class Springboot03AsyztimerApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot03AsyzyimerApplication.class, args);
}
}
SpringBoot(三) - Slf4j+logback 日志,异步请求,定时任务的更多相关文章
- SpringBoot整合Slf4j+logback日志框架
一.Slf4j简单介绍与优势 1.介绍 Slf4j的全称是Simple Loging Facade For Java(Java简单日志门面),它仅仅是一个为Java程序提供日志输出的统一接口,并不是一 ...
- springboot项目配置logback日志系统
记录springboot项目配置logback日志文件管理: logback依赖jar包 SpringBoot项目配置logback理论上需要添加logback-classic依赖jar包: < ...
- springboot通过slf4j配置日志
原因:SpringBoot默认使用slf4j日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉: 而我今天想引入log4j的时候,pom文件一直报错,显示找不到log4j的jar包,应当是 ...
- 在SpringBoot中添加Logback日志处理
前言 SpringBoot项目中在官方文档中说明,默认已经依赖了一些日志框架.而其中推荐使用的就是Logback,所以这一次我将在我的模版中加入Logback日志的配置,说明一下,SpringBoot ...
- logback日志异步打印
最近碰到一个问题:客户的服务器程序偶尔出现请求响应过慢的情况,通过查看日志发现RSA验证签名的代码执行超过20秒,而正常情况下只需要16毫秒. RSA证书是服务器启动就加载好的,不存在读文件慢的问题. ...
- 【SpringBoot】13. logback日志记录
logback日志记录 Spring Boot 1.5.19.RELEASE 1.导入相关jar包 在spring-boot-starter-web 中已经包含 2.添加logback.xml配置文件 ...
- slf4j+logback日志框架 的具体使用操作【spring boot自带的默认日志框架】
1.前言 是不是还在使用System.out.println()打印数据到控制台看? 东西少还好,如果多起来,那就看的很烦人了,特别还有加时间等信息. 怎么解决? 可以使用日志框架 ,常见的有 log ...
- 日志框架之2 slf4j+logback实现日志架构 · 远观钱途
如何从缤纷复杂的日志系统世界筛选出适合自己的日志框架以及slf4j+logback的组合美妙之处?此文可能有帮助 logback介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网 ...
- 🔥SpringBoot图文教程2—日志的使用「logback」「log4j」
有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...
随机推荐
- 题解 P1999【覆盖墙壁】
数学题 令 \(A_n\) 为 \(2\times n\) 的墙壁放满块的方案数,考虑递推. 显然 \(A_0=1\),我们令对于 \(k<0\),\(A_k=0\) . 放直线型的块非常好递推 ...
- 算法-买卖股票的最佳时机II
01.题目分析 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格.你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票. ...
- tcp协议传输中的粘包问题
什么是粘包问题 tcp是流体协议. 其nagle算法会将数据量较小. 并且发送间隔时间较短的多个数据包合并为一个发送. 网络传输的时候是一段一段字节流的发送. 在接收方看来根本不知道字节流从何开始. ...
- PHP memcache add replace set的区别和其他用法收集
add replace set的区别 最近在面试时遇到一个问题 memcache 的add replace set的区别,故在此进行加强 add 是向服务器添加一个缓存的数据,当该键已存在会返回一个f ...
- PHP小工具
防SQL注入 function clean($input) { if (is_array($input)) { foreach ($input as $key => $val) { $outpu ...
- 60行从零开始自己动手写FutureTask是什么体验?
前言 在并发编程当中我们最常见的需求就是启动一个线程执行一个函数去完成我们的需求,而在这种需求当中,我们常常需要函数有返回值.比如我们需要同一个非常大的数组当中数据的和,让每一个线程求某一个区间内部的 ...
- Python 爬取汽车之家口碑数据
本文仅供学习交流使用,如侵立删!联系方式见文末 汽车之家口碑数据 2021.8.3 更新 增加用户信息参数.认证车辆信息等 2021.3.24 更新 更新最新数据接口 2020.12.25 更新 添加 ...
- Luogu1601 A+B Problem (高精度加法)
蒟蒻复习了下高精 #include <iostream> #include <cstdio> #include <cstring> #include <alg ...
- 基于vue的脚手架开发与发布到npm仓库
什么是脚手架 在项目比较多而且杂的环境下,有时候我们想统一一下各个项目技术栈或者一些插件/组件的封装习惯,但是每次从零开发一个新项目的时候,总是会重复做一些类似于复制粘贴的工作,这是一个很头疼的事情, ...
- df空间满,du找不到文件的问题
最近看了一下问题: df -h Filesystem Size Used Avail Use% Mounted on rootfs 271G 267G 2.2G 100% / 根分区满了,du 找不到 ...