slf4j-spring-boot-starter减少编写日志的组件

联合创作 · 2023-09-29 23:58

一个注解搞定日志的组件,减少到处编写日志的烦恼,还可定位代码哟


软件架构


依赖spring-boot-starter-aop


原理说明


AOP + Reflect


作用范围


任意由spring调用的方法


安装教程




mvn clean install



使用说明


一、准备工作



  1. 添加依赖:




<dependency>
<groupId>wiki.xsx</groupId>
<artifactId>slf4j-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>




  1. 开启日志:


yml方式:




logging:
level:
wiki.xsx.core: 对应级别



properties方式:




logging.level.wiki.xsx.core=对应级别



二、开始使用(使用DEBUG模式)


@ParamLog注解示例:



  1. 日志注解标记:




@RestController
public class TestParamLogController {

@ParamLog(value = "ParamLog-test1")
@GetMapping("/paramLogTest1")
public Map<String, Object> logTest1(HttpServletRequest request, Map<String, Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", param);
return result;
}

@ParamLog(value = "ParamLog-test2", paramFilter = {"request"})
@GetMapping("/paramLogTest2")
public Map<String, Object> logTest2(HttpServletRequest request, Map<String, Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", param);
return result;
}

@ParamLog(value = "ParamLog-test3", paramFilter = {"request"}, callback = LogTestCallback.class)
@GetMapping("/paramLogTest3")
public Map<String, Object> logTest3(HttpServletRequest request, List<Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", param);
return result;
}
}




  1. 日志回调声明(实现wiki.xsx.core.log.LogCallback接口):




// 加入IOC容器,否则调用失败
@Component
@Slf4j
public class LogTestCallback implements LogCallback {
@Override
public void callback(Annotation annotation, MethodInfo methodInfo, Map<String, Object> paramMap, Object result) {
log.info(methodInfo.getClassAllName()+"."+methodInfo.getMethodName()+"方法的回调函数执行成功");
}
}




  1. 测试:




@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestParamLogControllerTest {

@Autowired
private TestParamLogController testParamLogController;

@Test
public void test() {
List<Object> list = new ArrayList<>(2);
list.add("test-list");
Map<String, Object> paramMap = new LinkedHashMap<>(5);
paramMap.put("key1", "hello-world");
paramMap.put("key2", 11);
paramMap.put("key3", 11.11D);
paramMap.put("key4", new String[]{"hello", "world"});
paramMap.put("key5", new Number[]{111, 112, 113});
list.add(paramMap);
this.testParamLogController.logTest1(null, paramMap);
this.testParamLogController.logTest2(null, paramMap);
this.testParamLogController.logTest3(null, list);
}
}




  1. 日志打印效果:




2020-01-16 21:51:11.932 DEBUG 27340 --- [           main] wiki.xsx.core.log.LogProcessor           : 调用方法:【wiki.xsx.log.controller.TestParamLogController.logTest1(TestParamLogController.java:23)】,业务名称:【ParamLog-test1】,接收参数:【{request=null, param={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}}】
2020-01-16 21:51:11.939 DEBUG 27340 --- [ main] wiki.xsx.core.log.LogProcessor : 调用方法:【wiki.xsx.log.controller.TestParamLogController.logTest2(TestParamLogController.java:33)】,业务名称:【ParamLog-test2】,接收参数:【{param={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}}】
2020-01-16 21:51:11.940 DEBUG 27340 --- [ main] wiki.xsx.core.log.LogProcessor : 调用方法:【wiki.xsx.log.controller.TestParamLogController.logTest3(TestParamLogController.java:43)】,业务名称:【ParamLog-test3】,接收参数:【{param=[test-list, {key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}]}】
2020-01-16 21:51:11.941 INFO 27340 --- [ main] wiki.xsx.log.controller.LogTestCallback : wiki.xsx.log.controller.TestParamLogController.logTest3方法的回调函数执行成功



@ResultLog注解示例:



  1. 日志注解标记:




@RestController
public class TestResultLogController {

@ResultLog(value = "ResultLog-test1")
@GetMapping("/resultLogTest1")
public Map<String, Object> logTest1(HttpServletRequest request, Map<String, Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", param);
return result;
}

@ResultLog(value = "ResultLog-test2", callback = LogTestCallback.class)
@GetMapping("/resultLogTest2")
public Map<String, Object> logTest2(HttpServletRequest request, List<Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", param);
return result;
}
}




  1. 日志回调声明(实现wiki.xsx.core.log.LogCallback接口):




// 加入IOC容器,否则调用失败
@Component
@Slf4j
public class LogTestCallback implements LogCallback {
@Override
public void callback(Annotation annotation, MethodInfo methodInfo, Map<String, Object> paramMap, Object result) {
log.info(methodInfo.getClassAllName()+"."+methodInfo.getMethodName()+"方法的回调函数执行成功");
}
}




  1. 测试:




@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestResultLogControllerTest {

@Autowired
private TestResultLogController testResultLogController;

@Test
public void test() {
List<Object> list = new ArrayList<>(2);
list.add("test-list");
Map<String, Object> paramMap = new LinkedHashMap<>(5);
paramMap.put("key1", "hello-world");
paramMap.put("key2", 11);
paramMap.put("key3", 11.11D);
paramMap.put("key4", new String[]{"hello", "world"});
paramMap.put("key5", new Number[]{111, 112, 113});
list.add(paramMap);
this.testResultLogController.logTest1(null, paramMap);
this.testResultLogController.logTest2(null, list);
}
}




  1. 日志打印效果:




2020-01-16 22:09:15.873 DEBUG 9280 --- [           main] wiki.xsx.core.log.LogProcessor           : 调用方法:【wiki.xsx.log.controller.TestResultLogController.logTest1(TestResultLogController.java:23)】,业务名称:【ResultLog-test1】,返回结果:【{msg=success, data={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}, code=200}】
2020-01-16 22:09:15.874 DEBUG 9280 --- [ main] wiki.xsx.core.log.LogProcessor : 调用方法:【wiki.xsx.log.controller.TestResultLogController.logTest2(TestResultLogController.java:33)】,业务名称:【ResultLog-test2】,返回结果:【{msg=success, data=[test-list, {key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}], code=200}】
2020-01-16 22:09:15.874 INFO 9280 --- [ main] wiki.xsx.log.controller.LogTestCallback : wiki.xsx.log.controller.TestResultLogController.logTest2方法的回调函数执行成功



@ThrowingLog注解示例:



  1. 日志注解标记:




@RestController
public class TestThrowingLogController {

@ThrowingLog(value = "ThrowingLog-test1")
@GetMapping("/throwingLogTest1")
public Map<String, Object> logTest1(HttpServletRequest request, Map<String, Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", 1/0);
return result;
}

@ThrowingLog(value = "ThrowingLog-test2", callback = LogTestCallback.class)
@GetMapping("/throwingLogTest2")
public Map<String, Object> logTest2(HttpServletRequest request, Map<String, Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", 1/0);
return result;
}
}




  1. 日志回调声明(实现wiki.xsx.core.log.LogCallback接口):




// 加入IOC容器,否则调用失败
@Component
@Slf4j
public class LogTestCallback implements LogCallback {
@Override
public void callback(Annotation annotation, MethodInfo methodInfo, Map<String, Object> paramMap, Object result) {
log.info(methodInfo.getClassAllName()+"."+methodInfo.getMethodName()+"方法的回调函数执行成功");
}
}




  1. 测试:




@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestThrowingLogControllerTest {

@Autowired
private TestThrowingLogController testThrowingLogController;

@Test
public void test() {
List<Object> list = new ArrayList<>(2);
list.add("test-list");
Map<String, Object> paramMap = new LinkedHashMap<>(5);
paramMap.put("key1", "hello-world");
paramMap.put("key2", 11);
paramMap.put("key3", 11.11D);
paramMap.put("key4", new String[]{"hello", "world"});
paramMap.put("key5", new Number[]{111, 112, 113});
list.add(paramMap);
try {
this.testThrowingLogController.logTest1(null, paramMap);
}catch (Exception e) {

}
try {
this.testThrowingLogController.logTest2(null, paramMap);
}catch (Exception e) {

}
}
}




  1. 日志打印效果:




2020-01-16 22:13:58.226 ERROR 22184 --- [           main] wiki.xsx.core.log.LogProcessor           : 调用方法:【wiki.xsx.log.controller.TestThrowingLogController.logTest1】,业务名称:【ThrowingLog-test1】,异常信息:

java.lang.ArithmeticException: / by zero
...
2020-01-16 22:13:58.227 ERROR 22184 --- [ main] wiki.xsx.core.log.LogProcessor : 调用方法:【wiki.xsx.log.controller.TestThrowingLogController.logTest2】,业务名称:【ThrowingLog-test2】,异常信息:

java.lang.ArithmeticException: / by zero
...
2020-01-16 22:13:58.228 INFO 22184 --- [ main] wiki.xsx.log.controller.LogTestCallback : wiki.xsx.log.controller.TestThrowingLogController.logTest2方法的回调函数执行成功



@Log注解示例:



  1. 日志注解标记:




@RestController
public class TestLogController {

@Log(value = "Log-test1")
@GetMapping("/logTest1")
public Map<String, Object> logTest1(HttpServletRequest request, Map<String, Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", param);
return result;
}

@Log(value = "Log-test2", paramFilter = {"request"})
@GetMapping("/logTest2")
public Map<String, Object> logTest2(HttpServletRequest request, Map<String, Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", param);
return result;
}

@Log(value = "Log-test3", paramFilter = {"request"}, callback = LogTestCallback.class)
@GetMapping("/logTest3")
public Map<String, Object> logTest3(HttpServletRequest request, List<Object> param) {
Map<String, Object> result = new HashMap<>(3);
result.put("code", 200);
result.put("msg", "success");
result.put("data", param);
return result;
}
}




  1. 日志回调声明(实现wiki.xsx.core.log.LogCallback接口):




// 加入IOC容器,否则调用失败
@Component
@Slf4j
public class LogTestCallback implements LogCallback {
@Override
public void callback(Annotation annotation, MethodInfo methodInfo, Map<String, Object> paramMap, Object result) {
log.info(methodInfo.getClassAllName()+"."+methodInfo.getMethodName()+"方法的回调函数执行成功");
}
}




  1. 测试:




@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestLogControllerTest {

@Autowired
private TestLogController testLogController;

@Test
public void test() {
List<Object> list = new ArrayList<>(2);
list.add("test-list");
Map<String, Object> paramMap = new LinkedHashMap<>(5);
paramMap.put("key1", "hello-world");
paramMap.put("key2", 11);
paramMap.put("key3", 11.11D);
paramMap.put("key4", new String[]{"hello", "world"});
paramMap.put("key5", new Number[]{111, 112, 113});
list.add(paramMap);
this.testLogController.logTest1(null, paramMap);
this.testLogController.logTest2(null, paramMap);
this.testLogController.logTest3(null, list);
}
}




  1. 日志打印效果:




2020-01-16 22:16:25.736 DEBUG 8304 --- [           main] wiki.xsx.core.log.LogProcessor           : 调用方法:【wiki.xsx.log.controller.TestLogController.logTest1(TestLogController.java:23)】,业务名称:【Log-test1】,接收参数:【{request=null, param={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}}】
2020-01-16 22:16:25.743 DEBUG 8304 --- [ main] wiki.xsx.core.log.LogProcessor : 调用方法:【wiki.xsx.log.controller.TestLogController.logTest1(TestLogController.java:23)】,业务名称:【Log-test1】,返回结果:【{msg=success, data={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}, code=200}】
2020-01-16 22:16:25.744 DEBUG 8304 --- [ main] wiki.xsx.core.log.LogProcessor : 调用方法:【wiki.xsx.log.controller.TestLogController.logTest2(TestLogController.java:33)】,业务名称:【Log-test2】,接收参数:【{param={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}}】
2020-01-16 22:16:25.744 DEBUG 8304 --- [ main] wiki.xsx.core.log.LogProcessor : 调用方法:【wiki.xsx.log.controller.TestLogController.logTest2(TestLogController.java:33)】,业务名称:【Log-test2】,返回结果:【{msg=success, data={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}, code=200}】
2020-01-16 22:16:25.744 DEBUG 8304 --- [ main] wiki.xsx.core.log.LogProcessor : 调用方法:【wiki.xsx.log.controller.TestLogController.logTest3(TestLogController.java:43)】,业务名称:【Log-test3】,接收参数:【{param=[test-list, {key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}]}】
2020-01-16 22:16:25.744 DEBUG 8304 --- [ main] wiki.xsx.core.log.LogProcessor : 调用方法:【wiki.xsx.log.controller.TestLogController.logTest3(TestLogController.java:43)】,业务名称:【Log-test3】,返回结果:【{msg=success, data=[test-list, {key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}], code=200}】
2020-01-16 22:16:25.744 INFO 8304 --- [ main] wiki.xsx.log.controller.LogTestCallback : wiki.xsx.log.controller.TestLogController.logTest3方法的回调函数执行成功



其他说明


日志类型



  1. @ParamLog:参数类型,仅打印参数

  2. @ResultLog:结果类型,仅打印结果

  3. @ThrowingLog:异常类型,仅打印异常

  4. @Log:综合类型,打印参数+结果+异常


日志参数



  1. value:业务名称

  2. level:日志级别,默认DEBUG

  3. position:代码定位,默认DEFAULT

  4. paramFilter:参数名过滤,默认{}

  5. callback:日志回调,默认VoidLogCallback.class(实现wiki.xsx.core.log.LogCallback接口,且需放入IOC容器中)


日志级别



  1. DEBUG(默认): 调试级别

  2. INFO: 信息级别

  3. WARN: 警告级别

  4. ERROR: 错误级别


回调接口说明




public interface LogCallback {

/**
* 回调方法
* @param annotation 当前使用注解
* @param methodInfo 方法信息
* @param paramMap 参数字典
* @param result 方法调用结果
*/
void callback(
Annotation annotation,
MethodInfo methodInfo,
Map<String, Object> paramMap,
Object result
);
}



特别说明



  1. 日志级别为DEBUG时,默认开启代码定位,方便调试

  2. 其他级别默认关闭代码定位,减少不必要的开支,如需要可手动开启(position=Position.ENABLED)

浏览 18
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

编辑 分享
举报