CustomOneLineExceptionConverter.java 5.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package com.hz3r.config.log.pattern.converters;
  2. import ch.qos.logback.classic.pattern.ClassicConverter;
  3. import ch.qos.logback.classic.spi.ILoggingEvent;
  4. import ch.qos.logback.classic.spi.LoggingEvent;
  5. import ch.qos.logback.classic.spi.ThrowableProxy;
  6. import ch.qos.logback.classic.spi.ThrowableProxyVO;
  7. import cn.hutool.core.exceptions.ExceptionUtil;
  8. import cn.hutool.core.text.StrFormatter;
  9. import cn.hutool.core.util.NumberUtil;
  10. import com.hz3r.infrastructure.park.domain.constant.share.SystemCacheType;
  11. import com.hz3r.infrastructure.park.service.share.SystemCacheService;
  12. import com.hz3r.utils.MyStrUtils;
  13. import com.hz3r.utils.SpringBeanUtils;
  14. import java.util.ArrayList;
  15. import java.util.Arrays;
  16. import java.util.List;
  17. /**
  18. * 自定义异常堆栈合并成行转换器
  19. *
  20. * 用法:在 PatternLayout 中使用 %ctx 来引用此转换器
  21. */
  22. public class CustomOneLineExceptionConverter extends ClassicConverter {
  23. @Override
  24. public String convert(ILoggingEvent event) {
  25. // 异常栈合并成一行输出。
  26. String oneLineMessage = MyStrUtils.EMPTY;
  27. SystemCacheService SCService = SpringBeanUtils.getBean(SystemCacheService.class);
  28. Boolean oneLineExceptionCallStack = SCService.describeAll().stream()
  29. .filter(e -> e.getKey() == SystemCacheType.LOG_OUT_ONE_LINE_EXCEPTION)
  30. .map(e -> MyStrUtils.equalsIgnoreCase(MyStrUtils.defaultString(e.getValue()), "true"))
  31. .findFirst().orElse(Boolean.TRUE);
  32. // 默认行长度
  33. final Integer defaultLineSize = 2000;
  34. int oneLineMessageSize = SCService.describeAll().stream()
  35. .filter(e -> e.getKey() == SystemCacheType.LOG_OUT_ONE_LINE_SIZE)
  36. .map(e -> NumberUtil.parseInt(MyStrUtils.defaultIfBlank(e.getValue(), String.valueOf(defaultLineSize))))
  37. .findFirst().orElse(defaultLineSize);
  38. if ((oneLineExceptionCallStack) && (event.getCallerData() != null && event.getCallerData().length > 0)) {
  39. //if (event.getThrowableProxy() instanceof ThrowableProxy) {
  40. // ThrowableProxy throwableProxy = ((ThrowableProxy) event.getThrowableProxy());
  41. // oneLineMessage = ExceptionUtil.stacktraceToOneLineString(throwableProxy.getThrowable(), oneLineMessageSize * 3);
  42. //} else if (event.getThrowableProxy() instanceof Throwable) {
  43. // Throwable throwable = ((Throwable) event.getThrowableProxy());
  44. // oneLineMessage = ExceptionUtil.stacktraceToOneLineString(throwable, oneLineMessageSize * 3);
  45. //}
  46. String hz3rRootPackageSearch = ".hz3r.";
  47. String hz3rRootPackage = MyStrUtils.substring(this.getClass().getPackageName(),
  48. 0, this.getClass().getPackageName().indexOf(hz3rRootPackageSearch) + hz3rRootPackageSearch.length());
  49. List<String> busCodeStack = new ArrayList<>(100);
  50. String splitDelimiter = ",";
  51. String[] packageFilters = SCService.describeAll().stream()
  52. .filter(e -> e.getKey() == SystemCacheType.LOG_OUT_ONE_LINE_PACKAGES)
  53. .map(e -> {
  54. String value = MyStrUtils.replace(MyStrUtils.defaultString(e.getValue()), ",", splitDelimiter);
  55. value = StrFormatter.format("{},{}", hz3rRootPackage, value);
  56. value = MyStrUtils.replace(value, ",,", splitDelimiter);
  57. return MyStrUtils.split(value, splitDelimiter);
  58. })
  59. .findFirst().orElse(new String[] { hz3rRootPackage, "org.springframework.web.servlet.mvc."});
  60. Arrays.stream(event.getThrowableProxy().getStackTraceElementProxyArray())
  61. .forEach(e -> {
  62. if (MyStrUtils.startsWithAny(e.getStackTraceElement().getClassName(), packageFilters)) {
  63. busCodeStack.add(e.getSTEAsString());
  64. }
  65. });
  66. oneLineMessage = MyStrUtils.join(busCodeStack, "\\n\t");
  67. // 缩减长度,只留指定长度的字符串。
  68. if (oneLineMessage.length() > oneLineMessageSize) {
  69. int startSize = oneLineMessageSize / 2;
  70. startSize = startSize <= 0 ? oneLineMessageSize : startSize;
  71. int endSize = oneLineMessageSize - startSize;
  72. oneLineMessage = StrFormatter.format("{}\\n...\\n{}",
  73. MyStrUtils.substring(oneLineMessage, 0, startSize),
  74. MyStrUtils.substring(oneLineMessage, -(endSize), oneLineMessage.length()));
  75. }
  76. // ch.qos.logback.classic.spi.LoggingEvent
  77. if (event instanceof LoggingEvent) {
  78. LoggingEvent loggingEvent = LoggingEvent.class.cast(event);
  79. //loggingEvent.setCallerData(null);
  80. //loggingEvent.setThrowableProxy(null);
  81. //(ThrowableProxyVO.class.cast(loggingEvent.getThrowableProxy())).set()
  82. }
  83. }
  84. final String specHead = ",#!!///ole";
  85. return MyStrUtils.isBlank(oneLineMessage) ? oneLineMessage : StrFormatter.format("{} at{}", specHead, oneLineMessage);
  86. }
  87. }