String[]与List的相互转换 1.0 String[]与List的相互转换
1 2 |
String[] arr = new String[]{"s1","s2","s3"}; List<String> list = Arrays.asList(arr); |
1.2 List转String[]
1 2 3 4 5 |
List<String> list = new ArrayList<String>(); list.add("s1"); list.add("s2"); list.add("s3"); String[] arr = list.toArray(new String[list.size()]); |
字符数组char[]和字符串String之间的转换 2.0 使用String.valueOf()将字符数组转换成字符串
1 2 3 4 5 6 7 |
void (){ char[] s={'A','G','C','T'}; String st=String.valueOf(s); System.out.println("This is : "+st); } >> This is : AGCT |
2.1使用.toCharArray()将字符串转换成字符数组
1 2 3 4 5 6 7 8 9 10 |
String str="AGCT"; char[] s=str.toCharArray(); for (int i=0;i<str.length();i++){ System.out.println("This s[i] "+i+s[i]); } This s[i] 0 A This s[i] 1 G This s[i] 2 C This s[i] 3 T |
from:https://blog.csdn.net/qq_41076577/article/details/106909006
View Details工作中需要根据身份证获取性别、出生日期及年龄,且要还要支持15位长度的身份证号码,网上搜索了一下,经过测试好像多少存在点问题,干脆自已写一个。 CertificateNo.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package com.bijian.study; import java.util.Calendar; import java.util.regex.Pattern; /** * 根据身份证获取性别、出生日期、年龄,支持15、18位身份证 */ public class CertificateNo { public ResultDTO parseCertificateNo(String certificateNo) { ResultDTO resultDTO = new ResultDTO(); String myRegExpIDCardNo = "^\\d{6}(((19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}([0-9]|x|X))|(\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}))$"; boolean valid=Pattern.matches(myRegExpIDCardNo,certificateNo)||(certificateNo.length() == 17 && Pattern.matches(myRegExpIDCardNo,certificateNo.substring(0,15))); if(!valid){ resultDTO.setStatueMessage("证件号码不规范!"); return resultDTO; } int idxSexStart = 16; int birthYearSpan = 4; //如果是15位的证件号码 if(certificateNo.length() == 15) { idxSexStart = 14; birthYearSpan = 2; } //性别 String idxSexStr = certificateNo.substring(idxSexStart, idxSexStart + 1); int idxSex = Integer.parseInt(idxSexStr) % 2; String sex = (idxSex == 1) ? "M" : "F"; resultDTO.setSex(sex); //出生日期 String year = (birthYearSpan == 2 ? "19" : "") + certificateNo.substring(6, 6 + birthYearSpan); String month = certificateNo.substring(6 + birthYearSpan, 6 + birthYearSpan + 2); String day = certificateNo.substring(8 + birthYearSpan, 8 + birthYearSpan + 2); String birthday = year + '-' + month + '-' + day; resultDTO.setBirthday(birthday); //年龄 Calendar certificateCal = Calendar.getInstance(); Calendar currentTimeCal = Calendar.getInstance(); certificateCal.set(Integer.parseInt(year), Integer.parseInt(month)-1, Integer.parseInt(day)); int yearAge = (currentTimeCal.get(currentTimeCal.YEAR)) - (certificateCal.get(certificateCal.YEAR)); certificateCal.set(currentTimeCal.get(Calendar.YEAR), Integer.parseInt(month)-1, Integer.parseInt(day)); int monthFloor = (currentTimeCal.before(certificateCal) ? 1 : 0); resultDTO.setAge(yearAge - monthFloor); return resultDTO; } } |
ResultDTO.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.bijian.study; public class ResultDTO { private String statueMessage; private String sex; private String birthday; private int age; public String getStatueMessage() { return statueMessage; } public void setStatueMessage(String statueMessage) { this.statueMessage = statueMessage; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { String res = ""; if(this.statueMessage != null) { res += this.statueMessage; }else { res += "sex:" + this.sex + ",birthday:" + this.birthday + ",age:" + this.age; } return res; } } |
CertificateNoTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
package com.bijian.test; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; import com.bijian.study.CertificateNo; import com.bijian.study.ResultDTO; /** * 说明: * 1.身份证信息完全是测试时随便写的,如有雷同,纯属巧合 * 2.写此测试案例的日期是2015-02-08,有测生日当天及前后的案例,后续再运行需更改 */ public class CertificateNoTest { private CertificateNo certificateNo; private ResultDTO resultDTO; @Before public void setUp() throws Exception { certificateNo = new CertificateNo(); } @Test public void test_abnormality_certificateNo_of_18_digit_430522199812623535() { resultDTO = certificateNo.parseCertificateNo("430522199812623535"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_abnormality_certificateNo_of_18_digit_430522198813013210() { resultDTO = certificateNo.parseCertificateNo("430522198813013210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101515() { resultDTO = certificateNo.parseCertificateNo("430522199812101515"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101595() { resultDTO = certificateNo.parseCertificateNo("430522199812101595"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522199812101585() { resultDTO = certificateNo.parseCertificateNo("430522199812101585"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1998-12-10", resultDTO.getBirthday()); Assert.assertEquals(16, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_430522198810103212() { resultDTO = certificateNo.parseCertificateNo("430522198810103212"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-10-10", resultDTO.getBirthday()); Assert.assertEquals(26, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_before_birthday() { //测试的时间是2015-02-08,表明昨天刚过生日 resultDTO = certificateNo.parseCertificateNo("430522198802073210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-07", resultDTO.getBirthday()); Assert.assertEquals(27, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_birthday() { //测试的时间是2015-02-08,表明当天正好生日 resultDTO = certificateNo.parseCertificateNo("430522198802083210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-08", resultDTO.getBirthday()); Assert.assertEquals(27, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_18_digit_after_birthday() { //测试的时间是2015-02-08,表明第二天才过生日 resultDTO = certificateNo.parseCertificateNo("430522198802093210"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1988-02-09", resultDTO.getBirthday()); Assert.assertEquals(26, resultDTO.getAge()); } @Test public void test_abnormality_certificateNo_of_15_digit_130503671401001() { resultDTO = certificateNo.parseCertificateNo("130503671401001"); Assert.assertNotNull(resultDTO); Assert.assertEquals("证件号码不规范!", resultDTO.getStatueMessage()); } @Test public void test_normality_certificateNo_of_15_digit_430522760201356() { resultDTO = certificateNo.parseCertificateNo("430522760201356"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1976-02-01", resultDTO.getBirthday()); Assert.assertEquals(39, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_130503670401001() { resultDTO = certificateNo.parseCertificateNo("130503670401001"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1967-04-01", resultDTO.getBirthday()); Assert.assertEquals(47, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_370802940221002() { resultDTO = certificateNo.parseCertificateNo("370802940221002"); Assert.assertNotNull(resultDTO); Assert.assertEquals("F", resultDTO.getSex()); Assert.assertEquals("1994-02-21", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_370802941031331() { resultDTO = certificateNo.parseCertificateNo("370802941031331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-10-31", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_before_birthday() { //测试的时间是2015-02-08,表明昨天刚过生日 resultDTO = certificateNo.parseCertificateNo("370802940207331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-07", resultDTO.getBirthday()); Assert.assertEquals(21, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_birthday() { //测试的时间是2015-02-08,表明当天正好生日 resultDTO = certificateNo.parseCertificateNo("370802940208331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-08", resultDTO.getBirthday()); Assert.assertEquals(21, resultDTO.getAge()); } @Test public void test_normality_certificateNo_of_15_digit_after_birthday() { //测试的时间是2015-02-08,表明第二天才过生日 resultDTO = certificateNo.parseCertificateNo("370802940209331"); Assert.assertNotNull(resultDTO); Assert.assertEquals("M", resultDTO.getSex()); Assert.assertEquals("1994-02-09", resultDTO.getBirthday()); Assert.assertEquals(20, resultDTO.getAge()); } } |
from:https://www.iteye.com/blog/bijian1013-2184409
View Details为什么要做性能调优? 一款线上产品如果没有经过性能测试,那它就好比是一颗定时炸弹,你不知道它什么时候会出现问题,你也不清楚它能承受的极限在哪儿。 所以,要不要做性能调优,这个问题其实很好回答。所有的系统在开发完之后,多多少少都会有性能问题,我们首先要做的就是想办法把问题暴露出来,例如进行压力测试、模拟可能的操作场景等等,再通过性能调优去解决这些问题。 好的系统性能调优不仅仅可以提高系统的性能,还能为公司节省资源。这也是我们做性能调优的最直接的目的!所以,接下来我就给大家带来了一份“阿里巴巴lava性能调优实战(2021华山版)”想要学习的朋友们,我们就先来看看文章大概内容:(同时在文末会有笔记领取方式!大家自行解决) 主要内容 模块一 概述 为你建立两个标准。-个是性能调优标准,告诉你可以通过哪些参数去衡量系统性能;另-一个是调优过程标准,带你了解通过哪些严格的调优策略,我们可以排查性能问题,从而解决问题。 模块二 Java 编程性能调优 JDK是Java语言的基础库,熟悉JDK中各个包中的工具类,可以帮助你编写出高性能代码。这里我会从基础的数据类型讲起,涉及容器在实际应用场景中的调优,还有现在互联网系统架构中比较重要的网络通信调优。 03.字符串性能优化不容小觑,百M内存轻松存储几十G数据 05.ArrayList还是LinkedList?使用不当性能差千倍 06.Stream如何提高遍历集合效率? 10.网络通信优化之通信协议:如何优化RPC网络通信? 11.推荐几款常用的性能测试工具 模块三 多线程性能调优 目前大部分服务器都是多核处理器,多线程编程的应用广泛。为了保证线程的安全性,通常会用到同步锁,这会为系统埋下很多隐患;除此之外,还有多线程高并发带来的性能问题,这些都会在这个模块重点讲解。 12.多线程之锁优化(上):深入了解Synchronized同步锁的优化方法 13.多线程之锁优化(中):深入了解Lock 同步锁的优化方法 15.多线程调优(上):哪些操作导致了上下文切换? 17.并发容器的使用:识别不同场景下最优容器 模块四 JVM性能监测及调优 Java 应用程序是运行在JVM之上的,对JVM进行调优可以提升系统性能。这里重点讲解Java对象的创建和回收、内存分配等。 20. 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型 21.深入JVM即时编译器JIT,优化Java编译 22.如何优化垃圾回收机制? 模块五 设计模式调优 在架构设计中,我们经常会用到-一些设计模式来优化架构设计。这里我将结合一-些复 杂的应用场景,分享设计优化案例。 29.生产者消费者模式:电商库存设计优化 30. 装饰器模式:如何优化电商系统中复杂的商品价格策略? 模块六 数据库性能调优 数据库最容易成为整个系统的性能瓶颈,这里我会重点解析-一些数据库的常用调优方法。 33.MySQL调优之事务:高并发场景下的数据库事务调优 35.记一次线上SQL死锁事故:如何避免死锁? 38.数据库参数设置优化,失之毫厘差之千里 模块七 实战演练场 以上六个模块的内容,都是基于某个点的调优,现在是时候把你前面所学都调动起来了,这里我将带你进入综合性能问题高频出现的应用场景,学习整体调优方法。 41.如何设计更优的分布式锁? 43.如何使用缓存优化系统性能? 最后 作者:努力向上的小芷 链接:https://juejin.cn/post/6920124384027885581 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
View DetailsDevTools的检测时间和idea的编译所需时间存在差异。在idea还没完成编译工作前,DevTools就开始进行重启和加载,导致@RequestMapping没有被全部正常处理。其他方法没试,就直接用了看起来最简单的方法:牺牲一点时间,去加长devtools的轮询时间,增大等待时间。 解决方案如下: spring.devtools.restart.poll-interval=3000ms spring.devtools.restart.quiet-period=2999ms from:https://www.cnblogs.com/yxfcnbg/p/11510426.html
View Details把object转成JSONObject JSON.toJSON public void onNext(Object o) { LogUtil.i("getFavorites", "json=" + o.toString()); JSONObject json = JSON.parseObject(o.toString()); // JSONObject json = JSON.parseObject("{\"code\":1001,\"timestamp\":\"2018-11-05 03:40:54\"}"); LogUtil 的可以打印o.toString() 出来,直接传字符串解析json可以获得属性值,为什么JSONObject json = JSON.parseObject(o.toString()); 就报错了?强制转换也报错,把object转成JSONObject 这种要怎么用的? 或者怎么把Object o 这个对象里面的属性值读出来的? 怎么变成字符串的? public interface ObserverResponseListener<T> { void onNext(T t); 传进来的Object是个泛型的 JSONObject json = (JSONObject) JSON.toJSON(o); 用这样可以了 from:https://www.cnblogs.com/zdz8207/p/java-object-JSONObject.html
View Details1.for循环,最常见 2.利用foreach 3.利用jdk自带的方法 --> java.util.Arrays.toString() from:https://www.cnblogs.com/baiaixing/p/11369514.html
View Details本文介绍非spring项目中利用Lombok + Logback + Slf4j记录日志,并附上所有的踩坑记录 本文环境 macos Idea2019.2 配置过程 首先在idea中下载lombok插件 在pom.xml文件中引入Lombok,Logback,Slf4j依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> |
在项目中的resources文件夹中添加logback.xml配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <property name="LOG_HOME" value="/logs" /> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <!-- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %boldMagenta(%-5level %logger{50}) : %msg%n</pattern>--> <pattern>%d{yyyy-MM-dd HH:mm:ss:SS} %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{50}) - %cyan(%msg%n)</pattern> </encoder> </appender> <!-- 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/provider.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <FileNamePattern>${LOG_HOME}/provider.log.%d{yyyy-MM-dd}.log</FileNamePattern> <!--日志文件保留天数--> <MaxHistory>30</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!-- 日志输出级别 --> <root level="INFO"> <appender-ref ref="STDOUT" /> </root> </configuration> |
编写代码测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import lombok.extern.slf4j.Slf4j; @Slf4j public class ProviderStart { public static void main(String[] args) { log.debug("输出DEBUG级别日志"); log.info("输出INFO级别日志"); log.warn("输出WARN级别日志"); log.error("输出ERROR级别日志"); } } |
输出为 踩过的坑 看上去简简单单几步就完成了,然后并不是,接下来附上踩过的坑以及解决方法 idea中plugins的marketplace直接打不开 在idea中使用lombok需要在plugins中的marketplace中下载插件,然而我下载时marketplace迟迟无法连接上 我们需要在设置中的Appearance & Behavior --> System Settings --> Http Proxy中选择Auto-detect proxy settings勾选Automatic proxy configuration URL选项并填写url为http://127.0.0.1:1080,重启idea 代码运行成功,但是不显示日志信息 也是很邪门的一种情况,代码没错,但是不显示log打印的信息。 解决方案为,在Build,Execution,Deployment–>compiler–>Annotation Processors中勾选Enable annotation processing,重启idea 多个Slf4j冲突 报错信息如下
1 2 |
SLF4J Warning: Class Path Contains Multiple SLF4J Bindings ..... |
说明是jar包冲突了,maven仓库中可能同时包含了log4j,logback,然后slf4j在程序运行时,不知道binding哪一个jar包。 解决方案为:在maven仓库中删除其中一个jar包,只保留一个即可。 from:https://blog.csdn.net/jerseywwwwei/article/details/105871320
View Details
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" debug="false"> <springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/> <!--日志存放路径--> <property name="PATH" value="logs"/> <property name="FILE_NAME" value="${spring.application.name}"/> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <withJansi>true</withJansi> <encoder> <charset>UTF-8</charset> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta([PID:${PID:-}]) %green([%15.15thread]) %cyan(%40.40logger:%-5.5L):%msg%n</pattern> </encoder> </appender> <!--trace--> <appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${PATH}/${FILE_NAME}_trace.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>${PATH}/${FILE_NAME}_trace.%d{yyyy-MM-dd}.log</FileNamePattern> <maxHistory>60</maxHistory> <totalSizeCap>1GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %highlight([%-5level]) %green([%15.15thread]) %cyan([%logger:%line])--%mdc{client} %msg%n</pattern> </encoder> </appender> <!--error--> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${PATH}/${FILE_NAME}_error.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>${PATH}/${FILE_NAME}_error.%d{yyyy-MM-dd}.log</FileNamePattern> <maxHistory>60</maxHistory> <totalSizeCap>1GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %highlight([%-5level]) %green([%15.15thread]) %cyan([%logger:%line])--%mdc{client} %msg%n</pattern> </encoder> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> </appender> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="TRACE_FILE" /> <appender-ref ref="ERROR_FILE" /> </root> </configuration> |
from:https://my.oschina.net/haopeng/blog/3065616
View Details参考官方网址: https://logging.apache.org/log4j/2.x 一、log4j日志级别配置说明
1 2 3 4 5 6 7 8 9 10 11 12 13 |
log4j提供了4种日志级别和2个日志开关。 DEBUG:输出调试信息;指出细粒度信息事件对调试应用程序是非常有帮助的。 INFO: 输出提示信息;消息在粗粒度级别上突出强调应用程序的运行过程。 WARN: 输出警告信息;表明会出现潜在错误的情形。 ERROR:输出错误信息;指出虽然发生错误事件,但仍然不影响系统的继续运行。 FATAL: 输出致命错误;指出每个严重的错误事件将会导致应用程序的退出。 ALL level:打开所有日志记录开关;是最低等级的,用于打开所有日志记录。 OFF level:关闭所有日志记录开关;是最高等级的,用于关闭所有日志记录。 按照范围从小到大排序:OFF level > FATAL > ERROR > WARN > INFO > DEBUG > ALL level;范围大的会包含范围小的,例如日志设置为INFO级别的话则FATAL、ERROR、WARN、INFO的日志开关都是打开的,而DEBUG的日志开关将是关闭的。 Log4j建议只使用四个级别,优先级从高到低分别是 ERROR、WARN、INFO、DEBUG。 |
二、logback-spring.xml配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
<?xml version="1.0" encoding="UTF-8"?> <!-- 说明: 1、日志级别及文件 日志记录采用分级记录,级别与日志文件名相对应,不同级别的日志信息记录到不同的日志文件中。 2、日志级别可以根据开发环境进行配置,为方便统一管理查看日志,日志文件路径统一由LOG_PATH:-.配置在/home/项目名称/logs --> <configuration> <!-- 引入默认设置 --> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <!-- 编码格式设置 --> <property name="ENCODING" value="UTF-8" /> <!-- 日志文件的存储地址,由application.yml中的logging.path配置,根路径默认同项目路径 --> <property name="LOG_HOME" value="${LOG_PATH:-.}" /> <!-- 常规输出格式:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 --> <property name="NORMAL_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}.%method@%line - %msg%n"/> <!-- 彩色输出格式:magenta:洋红,boldMagenta:粗红,yan:青色,·#══> --> <property name="CONSOLE_LOG_PATTERN" value="%boldMagenta([%d{yyyy-MM-dd HH:mm:ss.SSS}]) %red([%thread]) %boldMagenta(%-5level) %blue(%logger{20}.%method@%line) %magenta(·#═>) %cyan(%msg%n)"/> <!-- ==========================控制台输出设置========================== --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> <charset>${ENCODING}</charset> </encoder> </appender> <!-- ==========================按天输出日志设置========================== --> <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/system-info.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <FileNamePattern>${LOG_HOME}/system-info.%d{yyyy-MM-dd}.log</FileNamePattern> <!-- 日志文件保留天数 --> <MaxHistory>30</MaxHistory> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <!-- 设置拦截的对象为INFO级别日志 --> <onMatch>ACCEPT</onMatch> <!-- 当遇到了INFO级别时,启用该段配置 --> <onMismatch>DENY</onMismatch> <!-- 没有遇到INFO级别日志时,屏蔽该段配置 --> </filter> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${NORMAL_LOG_PATTERN}</pattern> <charset>${ENCODING}</charset> </encoder> <!-- 日志文件最大的大小 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!-- ==========================按天输出ERROR级别日志设置========================== --> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/system-error.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <FileNamePattern>${LOG_HOME}/system-error.%d{yyyy-MM-dd}.log</FileNamePattern> <!-- 日志文件保留天数 --> <MaxHistory>30</MaxHistory> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <!-- 设置拦截的对象为ERROR级别日志 --> <onMatch>ACCEPT</onMatch> <!-- 当遇到了ERROR级别时,启用该段配置 --> <onMismatch>DENY</onMismatch> <!-- 没有遇到ERROR级别日志时,屏蔽该段配置 --> </filter> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${NORMAL_LOG_PATTERN}</pattern> <charset>${ENCODING}</charset> </encoder> <!-- 日志文件最大的大小 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!-- ==========================用户登录日志设置========================== --> <appender name="USER_LOGIN" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/user-login.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 按天回滚 daily --> <fileNamePattern>${LOG_HOME}/auth-user.%d{yyyy-MM-dd}.log</fileNamePattern> <!-- 日志最大的历史 30天 --> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>${NORMAL_LOG_PATTERN}</pattern> <charset>${ENCODING}</charset> </encoder> </appender> <!-- ===日志输出级别,OFF level > FATAL > ERROR > WARN > INFO > DEBUG > ALL level=== --> <logger name="com.sand" level="INFO"/> <logger name="com.apache.ibatis" level="INFO"/> <logger name="java.sql.Statement" level="INFO"/> <logger name="java.sql.Connection" level="INFO"/> <logger name="java.sql.PreparedStatement" level="INFO"/> <logger name="org.springframework" level="WARN"/> <logger name="com.baomidou.mybatisplus" level="WARN"/> <!-- 用户登录日志 --> <logger name="user-login" level="INFO"> <appender-ref ref="USER_LOGIN"/> </logger> <!-- ======开发环境:打印控制台和输出到文件====== --> <springProfile name="dev"><!-- 由application.yml中的spring.profiles.active配置 --> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="INFO_FILE"/> <appender-ref ref="ERROR_FILE"/> </root> </springProfile> <!-- ======测试环境:打印控制台和输出到文件====== --> <springProfile name="test"><!-- 由application.yml中的spring.profiles.active配置 --> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="INFO_FILE"/> <appender-ref ref="ERROR_FILE"/> </root> </springProfile> <!-- ======生产环境:打印控制台和输出到文件====== --> <springProfile name="prod"><!-- 由application.yml中的spring.profiles.active配置 --> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="INFO_FILE"/> <appender-ref ref="ERROR_FILE"/> </root> </springProfile> </configuration> |
注意:登录日志的记录还需进行以下配置,用lombok的话直接使用注解即可 @Slf4j(topic = "user-login") 配置效果如下: from:https://www.cnblogs.com/54hsh/p/12684241.html
View Details