一个注解搞定日志的组件,减少到处编写日志的烦恼,还可定位代码哟
依赖spring-boot-starter-aop
AOP + Reflect
任意由spring调用的方法
mvn clean install
<dependency> <groupId>wiki.xsx</groupId> <artifactId>slf4j-spring-boot-starter</artifactId> <version>1.2.0</version> </dependency>
yml方式:
logging: level: wiki.xsx.core: 对应级别
properties方式:
logging.level.wiki.xsx.core=对应级别
@ParamLog注解示例:
@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; } }
// 加入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()+"方法的回调函数执行成功"); } }
@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); } }
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注解示例:
@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; } }
// 加入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()+"方法的回调函数执行成功"); } }
@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); } }
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注解示例:
@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; } }
// 加入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()+"方法的回调函数执行成功"); } }
@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) { } } }
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注解示例:
@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; } }
// 加入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()+"方法的回调函数执行成功"); } }
@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); } }
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方法的回调函数执行成功
public interface LogCallback { /** * 回调方法 * @param annotation 当前使用注解 * @param methodInfo 方法信息 * @param paramMap 参数字典 * @param result 方法调用结果 */ void callback( Annotation annotation, MethodInfo methodInfo, Map<String, Object> paramMap, Object result ); }
背景 项目使用@slf4j注解,注入日志组件进行日志打印。POM中引入了spring-boot-starter-logging、spring-boot-starter-log4j2、log4j2、slf4j、logback等多种日志组件。 某次修改业务代码后,系统无法启动,并报错log4j-slf4j-impl cannot be present with log4j-to-slf4j。 SLF4
地址 dynamic-datasource码云地址 简介 主要的功能有: 数据源分组,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。 内置敏感参数加密和启动初始化表结构schema数据库database。 提供对Druid,Mybatis-Plus,P6sy,Jndi的快速集成。 简化Druid和HikariCp配置,提供全局参数配置。 提供自定义数据源来源接口(默认使用yml或prop
背景介绍 Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。DruidDataSource支持的数据库。 理论上说,支持所有有jdbc驱动的数据库。 1.在不使用druid-spring-boot-starter的时候,我们是通过导入druid依赖 上两篇博客 已经记录了 druid依赖 配置各种依赖 相对使用 起来还是比较麻烦的 有了 druid-spring
错误: SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/D:/environment/maven/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.17.1/log4j-slf4j-impl-2.17.1.jar!
环境 <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>com.baomido
我的代码中有以下日志记录语句。 这将打印我的日志,如下所示, 2019-02-25 16:27:45,460调试[fileTaskExecutor-2][A.abc.MySampleApp.Handlers.UserRecordHandler][MY_SAMPLE_APP][Vijay-20190225-162738.Trigger][]userRuntimeId=3051AA39-2E0A-11
我在Spring MVC应用程序中实现了一个类,它为我扩展了HandlerInterceptorAdapter,以便在执行任何控制器之前在preHandle、postHandle和afterCompletion中执行一些操作。下面是我正在观察的情况。 预处理日志记录的日志条目AppTime:00:30:01.230线程:[http-nio-8080-exec-1]级别:INFO Class:Hel
例如,在包括Spring Cloud Sleuth之前,人们会在他们的日志中得到这样的东西 在应用程序名称附近有2个逗号(即traceID和spanID将显示的位置)。但我的日志最初看起来像这样 为了在日志中获取应用程序名称,我在application.properties中编写了以下代码 现在,我的日志看起来是这样的(如果您观察到,它在应用程序名称旁边没有2个逗号) 即使包括了Sleuth,我的
我使用本教程使用SLF4J设置log4j2。这是我的全部pom.xml:
我们正在开发一个多租户应用程序。我想在每个日志消息之前添加租户名称 null 这都是spring boot的一部分,它使用默认的logback日志记录。 干杯,罗希特
主要内容:日志记录框架概述,记录器对象,严重程度在编程中的日志是指记录活动/事件。通常,应用程序开发人员应该负责日志记录。 为了使日志记录更容易,Java提供了各种框架 - log4J,java.util.logging(JUL), tiny log,logback等。 日志记录框架概述 日志框架通常包含三个元素 - 记录仪 - 捕获消息和元数据。 格式化 - 格式化记录器捕获的消息。 处理器 - 或最终通过在控制台上打印或通过存储在数据库中或