代码拉取完成,页面将自动刷新
一个注解搞定日志的组件,减少到处编写日志的烦恼,还可定位代码哟
依赖spring-boot-starter-aop
AOP + Reflect
任意由spring调用的方法
1.4.10
mvn clean install
<dependency>
<groupId>wiki.xsx</groupId>
<artifactId>slf4j-spring-boot-starter</artifactId>
<version>1.4.10</version>
</dependency>
yml方式:
logging:
level:
wiki.xsx.core: 对应级别
# 日志组件配置(按需配置)
slf4j:
# 全局综合日志级别
global-log-level: debug
# 全局综合日志代码定位
global-log-position: unknown
# 全局综合日志格式化
global-log-formatter: wiki.xsx.core.log.DefaultLogFormatter
# 全局综合日志回调
global-log-callback: wiki.xsx.core.log.VoidLogCallback
# 全局参数日志级别
global-param-log-level: debug
# 全局参数日志代码定位
global-param-log-position: unknown
# 全局参数日志格式化
global-param-log-formatter: wiki.xsx.core.log.DefaultParamLogFormatter
# 全局参数日志回调
global-param-log-callback: wiki.xsx.core.log.VoidLogCallback
# 全局结果日志级别
global-result-log-level: debug
# 全局结果日志代码定位
global-result-log-position: unknown
# 全局结果日志格式化
global-result-log-formatter: wiki.xsx.core.log.DefaultResultLogFormatter
# 全局结果日志回调
global-result-log-callback: wiki.xsx.core.log.VoidLogCallback
# 全局异常日志回调
global-throwing-log-callback: wiki.xsx.core.log.VoidLogCallback
properties方式:
logging.level.wiki.xsx.core=对应级别
# 日志组件配置(按需配置)
# 全局综合日志级别
logging.slf4j.global-log-level=debug
# 全局综合日志代码定位
logging.slf4j.global-log-position=unknown
# 全局综合日志格式化
logging.slf4j.global-log-formatter=wiki.xsx.core.log.DefaultLogFormatter
# 全局综合日志回调
logging.slf4j.global-log-callback=wiki.xsx.core.log.VoidLogCallback
# 全局参数日志级别
logging.slf4j.global-param-log-level=debug
# 全局参数日志代码定位
logging.slf4j.global-param-log-position=unknown
# 全局参数日志格式化
logging.slf4j.global-param-log-formatter=wiki.xsx.core.log.DefaultParamLogFormatter
# 全局参数日志回调
logging.slf4j.global-param-log-callback=wiki.xsx.core.log.VoidLogCallback
# 全局结果日志级别
logging.slf4j.global-result-log-level=debug
# 全局结果日志代码定位
logging.slf4j.global-result-log-position=unknown
# 全局结果日志格式化
logging.slf4j.global-result-log-formatter=wiki.xsx.core.log.DefaultResultLogFormatter
# 全局结果日志回调
logging.slf4j.global-result-log-callback=wiki.xsx.core.log.VoidLogCallback
# 全局异常日志回调
logging.slf4j.global-throwing-log-callback=wiki.xsx.core.log.VoidLogCallback
@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方法的回调函数执行成功
@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方法的回调函数执行成功
@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方法的回调函数执行成功
@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]}}】,返回结果:【{msg=success, data={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}, code=200}】,耗时:50ms
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]}}】,返回结果:【{msg=success, data={key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}, code=200}】,耗时:30ms
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]}]}】,返回结果:【{msg=success, data=[test-list, {key1=hello-world, key2=11, key3=11.11, key4=[hello, world], key5=[111, 112, 113]}], code=200}】,耗时:40ms
2020-01-16 22:16:25.744 INFO 8304 --- [ main] wiki.xsx.log.controller.LogTestCallback : wiki.xsx.log.controller.TestLogController.logTest3方法的回调函数执行成功
public interface LogFormatter {
/**
* 格式化
* @param log 日志对象
* @param level 日志级别
* @param busName 业务名称
* @param methodInfo 方法信息
* @param args 参数列表
* @param filterParamNames 参数过滤列表
* @param result 返回结果
*/
void format(
Logger log,
Level level,
String busName,
MethodInfo methodInfo,
Object[] args,
String[] filterParamNames,
Object result
);
}
public interface ParamLogFormatter {
/**
* 格式化
* @param log 日志对象
* @param level 日志级别
* @param busName 业务名称
* @param methodInfo 方法信息
* @param args 参数列表
* @param filterParamNames 参数过滤列表
*/
void format(
Logger log,
Level level,
String busName,
MethodInfo methodInfo,
Object[] args,
String[] filterParamNames
);
}
public interface ResultLogFormatter {
/**
* 格式化
* @param log 日志对象
* @param level 日志级别
* @param busName 业务名称
* @param methodInfo 方法信息
* @param result 返回结果
*/
void format(
Logger log,
Level level,
String busName,
MethodInfo methodInfo,
Object result
);
}
public interface LogCallback {
/**
* 回调方法
* @param annotation 当前使用注解
* @param methodInfo 方法信息
* @param paramMap 参数字典
* @param result 方法调用结果
*/
void callback(
Annotation annotation,
MethodInfo methodInfo,
Map<String, Object> paramMap,
Object result
);
}
CPU | AMD Athlon(tm) II X4 640 Processor(3000 Mhz) |
内存 | 8.00 GB (1333 MHz) |
硬盘 | Apacer A S510S 128GB SATA Disk Device |
测试工具 | Apache JMeter 5.1.1 |
测试方式 | http请求测试日志打印,循环5次取最后1次 |
加入代码定位功能:
日志类型 | 并发数 | 单次平均耗时(毫秒) | 吞吐量(请求次数/每秒) |
---|---|---|---|
@ParamLog | 1000 | 136 | 484 |
@ResultLog | 1000 | 86 | 417 |
@Log | 1000 | 29 | 425 |
取消代码定位功能:
日志类型 | 并发数 | 单次平均耗时(毫秒) | 吞吐量(请求次数/每秒) |
---|---|---|---|
@ParamLog | 1000 | 274 | 491 |
@ResultLog | 1000 | 66 | 519 |
@Log | 1000 | 108 | 483 |
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型