init commit

This commit is contained in:
YEYE 2026-04-03 17:43:57 +08:00
commit 4ffd2436ba
44 changed files with 6584 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf

35
.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
HELP.md
target/
.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
.env

3
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.14/apache-maven-3.9.14-bin.zip

View File

@ -0,0 +1,334 @@
# 日志规范完善版 (By ChatGPT)
> 基于现有 `日志规范说明.md` 整理,目标是把“什么时候记、谁来记、记什么、记到什么程度”说清楚,便于后续统一埋点和排查问题。
## 1. 文档目标
日志的核心目标不是“尽可能多地打印”,而是为了后续能够:
- 快速定位问题发生在哪一层
- 还原一次请求的完整链路
- 区分业务异常、参数异常和系统异常
- 追踪核心业务动作是否执行成功
- 在网络调用、数据库调用、SDK 调用等场景下,快速确认耗时和返回状态
## 2. 总体原则
### 2.1 谁负责记录谁的日志
- **Controller**:负责接口入口层的访问日志和兜底异常日志
- **Service**:负责业务里程碑日志
- **Utils / RPC / HTTP / Redis / DB / SDK**:负责外部依赖调用的前后日志
- **下游异常**:由下游自己记录,不在上游重复记录
### 2.2 日志要满足的最小信息
一条可用日志,至少应能回答以下问题:
- 谁发起的:`uid`、`traceId`
- 调了什么:类名、方法名、接口 URI、目标服务名
- 做了多久:`durationMs`、耗时统计
- 结果如何成功、失败、HTTP 状态码、业务状态码
- 为什么失败:异常类型、必要的错误摘要
### 2.3 避免重复记录
当异常已经在下游被明确处理并记录时,上游不要再重复打 ERROR
- 下游负责记录:具体依赖失败、远程超时、数据库异常等
- 上游负责感知:把异常继续抛出,或转换为统一业务异常
- 上游只保留必要的上下文日志,不重复打印同一条堆栈
## 3. Controller 层日志规范
Controller 是接口入口层,重点关注“请求进来了、请求结果是什么、是否发生兜底异常”。
### 3.1 必须记录的内容
`@DefaultControllerLog` 统一记录:
- 接口描述 `desc`
- 类名 `className`
- 方法名 `methodName`
- 请求 URI `uri`
- 用户标识 `uid`
- 耗时 `durationMs`
- 响应状态 `status`
- 异常类型 `exception`
### 3.2 记录方式
Controller 推荐只保留一层统一切面:
- 请求进入时开始计时
- 方法正常返回后记录成功日志
- 方法抛出异常后记录失败日志
- 在 `finally` 中完成统一输出,保证无论成功失败都能落日志
### 3.3 Controller 的异常处理原则
- Controller 内部应有 **try-catch 兜底** 的意识,但不要吞掉异常
- 如果异常来自下游服务、数据库、SDK 等,应该继续向上抛出,由对应下游层自己先记录
- 如果是 Controller 自身拼装、参数转换、分支判断等导致的异常,可以记录兜底日志
- 参数解析失败、JSON 反序列化失败等客户端问题,优先作为 **400 类问题** 处理,不应误报成系统故障
### 3.4 建议记录示例
- 成功请求:记录 `INFO`
- 业务异常:记录 `WARN``INFO`,视业务重要程度决定
- 未预期异常:记录 `ERROR`
### 3.5 当前项目中的对应实现
项目里已有:
- `DefaultControllerLogAspect`
- `ControllerLogBO`
- `BusinessControllerExceptionHandler`
- `TraceContextUtil`
这套实现已经具备 Controller 统一记录的基础,后续建议补齐:
- `uid` 的获取逻辑
- `traceId` / `spanId` 在日志中的统一输出
- 对不同异常类型的日志级别区分
## 4. Service 层日志规范
Service 层是业务核心,不负责“每一步都打日志”,而是负责记录对业务有里程碑意义的节点。
### 4.1 应记录的场景
建议在以下场景记录业务日志:
- 核心对象创建
- 核心对象删除
- 业务状态变化
- 数据同步完成
- 流程节点切换
- 核心任务开始与结束
- 影响用户结果的关键决策点
### 4.2 不建议记录的场景
以下情况一般不应在 Service 层重复记录:
- 下游抛出的异常已经在下游记录过
- 单纯的参数透传
- 没有业务意义的中间变量变化
- 每次循环都打印相同信息
### 4.3 Service 层建议关注的日志内容
一条好的业务日志通常包含:
- 业务对象 ID
- 业务动作
- 状态前后变化
- 处理结果
- 关键条件分支
示例字段:
- `orderId`
- `userId`
- `beforeStatus`
- `afterStatus`
- `action`
- `result`
### 4.4 异常处理原则
- Service 层可对业务异常做转换,但不要重复打印同一个下游异常堆栈
- 如果 Service 自己发现业务不成立,应抛出明确的业务异常
- 如果是资源、网络、数据库等问题,交给下游或统一异常处理层记录
## 5. Utils 与跨服务调用日志规范
Utils、RPC、HTTP Client、Redis、DB、SDK 等调用是最容易出现网络波动和性能问题的区域,因此必须前后成对记录。
### 5.1 调用前必须记录
调用发起前,应记录以下信息:
- 目标名称服务名、库名、SDK 名称、URL、Redis Key 前缀等
- 请求摘要:请求参数的关键字段,避免打印敏感数据
- 调用目的:本次调用是为了什么业务动作
- 关联链路:`traceId`、`spanId`
### 5.2 调用后必须记录
调用返回后,应记录:
- 耗时 `durationMs`
- 返回结果摘要
- 对方状态码或业务状态码
- 是否超时
- 是否重试
### 5.3 建议关注的日志内容
对于外部依赖,重点不是“全量打印响应”,而是以下信息:
- 请求目标
- 请求关键参数
- 返回耗时
- 返回状态
- 失败原因
### 5.4 不应记录的内容
- 密码、令牌、密钥、身份证号等敏感信息
- 过大的请求/响应全文
- 无法脱敏的用户隐私数据
- 已知会产生大量噪音的调试级细节
### 5.5 异常处理原则
- 下游调用失败,由下游先记录
- 上游只做必要的异常转换或透传
- 若需要重试,应记录每次重试的次数和最终结果
## 6. 日志字段建议
建议统一使用以下基础字段:
- `traceId`:一次请求链路的全局标识
- `spanId`:当前调用点标识
- `uid`:用户标识
- `className`:类名
- `methodName`:方法名
- `uri`:请求路径或目标路径
- `durationMs`:耗时
- `status`HTTP 状态或调用状态
- `exception`:异常类型或摘要
- `desc`:业务描述
### 6.1 字段使用建议
- `traceId`:用于串联一次请求的完整链路
- `spanId`:用于区分同一请求内的不同调用点
- `uid`:用于追踪用户行为
- `durationMs`:用于性能分析
- `status`:用于快速判断结果是否成功
- `exception`:用于快速定位失败类型
## 7. 日志级别建议
### 7.1 INFO
适用于:
- 请求正常完成
- 核心业务动作成功
- 外部调用成功且有分析价值
### 7.2 WARN
适用于:
- 客户端参数错误
- 可预期的业务失败
- 可恢复的下游失败
- 需要关注但不一定影响主流程的异常
### 7.3 ERROR
适用于:
- 未预期系统异常
- 无法恢复的故障
- 需要立即排查的严重错误
## 8. 推荐的统一输出格式
建议日志内容尽量结构化,方便后续检索和分析。
示例结构:
```text
{"traceId":"...","spanId":"...","uid":"...","className":"...","methodName":"...","uri":"...","durationMs":123,"status":"OK","exception":null,"desc":"..."}
```
对于外部调用,可再补充:
- `target`
- `requestSummary`
- `responseSummary`
- `retryCount`
- `remoteCode`
## 9. 常见误区
### 9.1 过度记录
问题表现:
- 一个方法内打印很多行
- 同一异常被多层重复打印
- 每个中间步骤都记日志
后果:
- 日志噪音过大
- 关键问题被淹没
- 排障效率下降
### 9.2 只记异常,不记上下文
问题表现:
- 只有 `NullPointerException`
- 没有用户、接口、调用目标、耗时
后果:
- 无法快速定位具体链路
### 9.3 打印敏感信息
问题表现:
- 直接打印完整请求体
- 直接打印密码或 token
后果:
- 安全风险
- 合规风险
## 10. 新增接口或调用点时的检查清单
新增代码前,建议逐项确认:
- [ ] 这段代码属于 Controller、Service 还是 Utils/外部调用
- [ ] 是否已经有统一切面或统一处理器
- [ ] 是否只记录了应该记录的那一层
- [ ] 是否避免了重复打印下游异常
- [ ] 是否包含 `traceId` / `spanId`
- [ ] 是否包含业务关键字段
- [ ] 是否脱敏了敏感数据
- [ ] 是否记录了耗时和结果状态
- [ ] 是否对异常级别做了合理区分
## 11. 建议落地顺序
如果要逐步完善当前项目,建议按下面顺序推进:
1. 统一 `traceId` / `spanId` 输出
2. 补齐 `uid` 获取逻辑
3. 完善 Controller 统一访问日志
4. 补充 Service 业务里程碑日志
5. 为外部调用增加前后日志模板
6. 统一异常分类与日志级别
## 12. 总结
这份规范的核心只有三句话:
- **Controller 记录入口和兜底异常**
- **Service 记录业务里程碑**
- **Utils / 跨服务调用记录前后摘要、耗时和状态**
如果所有日志都遵守“谁负责谁记录、下游异常不重复记、日志只保留关键上下文”这三个原则,后续排障和审计都会轻松很多。

View File

@ -0,0 +1,19 @@
# 记录位置
## Controller
Controller使用`@DefaultControllerLog`切面统一记录访问日志, 并且实现接口大面积失效报警功能;
需要一个 try-catch 块来捕获 Controller 内部的所有异常, 并在 catch 块中记录**兜底**异常日志, 如果是下游抛出的异常, 则交给下游记录日志;
## Service
Service层是业务核心, 需要在**核心对象创建/删除**, **状态变化**, **数据同步与核心流程结束**, 等具有业务里程碑意义的场景记录日志, 以便于事后追踪用户行为和系统状态;
同样, 如果是下游抛出的异常, 则由下游处理, 不应该在 Service 层重复记录日志;
## Utils & 跨服务调用 (RPC/HttpClient/Redis/DB/SDK)
Utils 和跨服务调用是网络波动极其多发的灾区, 需要在**调用前切面/钩子**记录发起目的地名称和请求摘要, 在**调用返回**时必须记录耗时(ms)以及对方返回的关键状态(如 HTTP Code 或三方的业务状态码), 以便于事后追踪网络问题和性能瓶颈;
同样, 如果是下游抛出的异常, 则由下游处理, 不应该在 Utils 层重复记录日志;

View File

@ -0,0 +1,434 @@
{"time":"2026-03-31 16:31:56.881","level":"WARN","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext","msg":Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'businessControllerExceptionHandler' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\handler\BusinessControllerExceptionHandler.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logPushService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogPushService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed,"exception":""}
{"time":"2026-03-31 16:31:56.906","level":"ERROR","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.SpringApplication","msg":Application run failed,"exception":"org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'businessControllerExceptionHandler' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\handler\BusinessControllerExceptionHandler.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logPushService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogPushService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1228)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1130)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:990)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
at cc.evil.logtest1.LogTest1Application.main(LogTest1Application.java:14)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'logService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logPushService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogPushService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1708)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1653)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
... 21 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'logPushService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogPushService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1708)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1653)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
... 34 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:515)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1459)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:606)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1708)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1653)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
... 47 common frames omitted
Caused by: org.springframework.util.PlaceholderResolutionException: Could not resolve placeholder 'log.push.mail.to' in value "${log.push.mail.to}"
at org.springframework.util.PlaceholderResolutionException.withValue(PlaceholderResolutionException.java:81)
at org.springframework.util.PlaceholderParser$ParsedValue.resolve(PlaceholderParser.java:298)
at org.springframework.util.PlaceholderParser.replacePlaceholders(PlaceholderParser.java:131)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:114)
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:293)
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:264)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:186)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:970)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1675)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1653)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:784)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:767)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:146)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:509)
... 58 common frames omitted
"}
{"time":"2026-03-31 16:35:21.137","level":"WARN","traceId":"2a57b2401411485d8019b9177c67c983","uid":"","thread":"http-nio-8080-exec-4","logger":"org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver","msg":Failure in @ExceptionHandler cc.evil.logtest1.handler.BusinessControllerExceptionHandler#handleClientException(ClientException),"exception":"java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.ConcurrentLinkedDeque.peekFirst()" is null
at cc.evil.logtest1.service.log.LogService$FailureWindow.release(LogService.java:154)
at cc.evil.logtest1.service.log.LogService$FailureWindow.push_back(LogService.java:146)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:80)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:51)
at cc.evil.logtest1.handler.BusinessControllerExceptionHandler.handleClientException(BusinessControllerExceptionHandler.java:41)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:471)
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:73)
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:182)
at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:80)
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1360)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1161)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at cc.evil.logtest1.filters.TraceIdFilter.doFilter(TraceIdFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1774)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:35:21.137","level":"WARN","traceId":"0496b5c3279f4c168fe51260636332c4","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver","msg":Failure in @ExceptionHandler cc.evil.logtest1.handler.BusinessControllerExceptionHandler#handleClientException(ClientException),"exception":"java.lang.NullPointerException: Cannot read the array length because "<local3>" is null
at cc.evil.logtest1.service.log.LogPushService.stackTraceToString(LogPushService.java:35)
at cc.evil.logtest1.service.log.LogPushService.push(LogPushService.java:29)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:83)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:51)
at cc.evil.logtest1.handler.BusinessControllerExceptionHandler.handleClientException(BusinessControllerExceptionHandler.java:41)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:471)
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:73)
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:182)
at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:80)
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1360)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1161)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at cc.evil.logtest1.filters.TraceIdFilter.doFilter(TraceIdFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1774)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:35:21.144","level":"ERROR","traceId":"","uid":"","thread":"http-nio-8080-exec-4","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]","msg":Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: cc.evil.logtest1.exception.ClientException: 未授权访问] with root cause,"exception":"cc.evil.logtest1.exception.ClientException: 未授权访问
at cc.evil.logtest1.controller.TestController.testNormalException(TestController.java:36)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:728)
at cc.evil.logtest1.controller.TestController$$SpringCGLIB$$0.testNormalException(<generated>)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:991)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:896)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at cc.evil.logtest1.filters.TraceIdFilter.doFilter(TraceIdFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1774)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:35:21.145","level":"ERROR","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]","msg":Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: cc.evil.logtest1.exception.ClientException: 未授权访问] with root cause,"exception":"cc.evil.logtest1.exception.ClientException: 未授权访问
at cc.evil.logtest1.controller.TestController.testNormalException(TestController.java:36)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:728)
at cc.evil.logtest1.controller.TestController$$SpringCGLIB$$0.testNormalException(<generated>)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:991)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:896)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at cc.evil.logtest1.filters.TraceIdFilter.doFilter(TraceIdFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1774)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:40:51.182","level":"ERROR","traceId":"057234bb1a6b471094c51620400b2bd7","uid":"","thread":"trace-exec-4","logger":"org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler","msg":Unexpected exception occurred invoking async method: public void cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(cc.evil.logtest1.exception.EvilBaseException),"exception":"java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.ConcurrentLinkedDeque.peekFirst()" is null
at cc.evil.logtest1.service.log.LogService$FailureWindow.release(LogService.java:157)
at cc.evil.logtest1.service.log.LogService$FailureWindow.push_back(LogService.java:149)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:83)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:53)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:114)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:317)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at cc.evil.logtest1.config.AsyncConfig.lambda$traceableExecutor$0(AsyncConfig.java:34)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:45:42.013","level":"ERROR","traceId":"02cfc3affc7f4ec0b4db470bd403356c","uid":"","thread":"trace-exec-1","logger":"org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler","msg":Unexpected exception occurred invoking async method: public void cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(cc.evil.logtest1.exception.EvilBaseException),"exception":"org.springframework.mail.MailSendException: Failed messages: jakarta.mail.SendFailedException: No recipient addresses; message exceptions (1) are:
Failed message 1: jakarta.mail.SendFailedException: No recipient addresses
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:453)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:317)
at org.springframework.mail.MailSender.send(MailSender.java:42)
at cc.evil.logtest1.service.log.MailPushService.pushToAll(MailPushService.java:32)
at cc.evil.logtest1.service.log.LogPushService.push(LogPushService.java:30)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:49)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:114)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at cc.evil.logtest1.config.AsyncConfig.lambda$traceableExecutor$0(AsyncConfig.java:34)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 17:47:53.992","level":"ERROR","traceId":"","uid":"","thread":"scheduling-1","logger":"org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler","msg":Unexpected error occurred in scheduled task,"exception":"java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.ConcurrentLinkedDeque.peekFirst()" is null
at cc.evil.logtest1.service.log.LogService$FailureWindow.release(LogService.java:154)
at cc.evil.logtest1.service.log.LogService.lambda$cleanupIdleWindows$1(LogService.java:102)
at java.base/java.util.concurrent.ConcurrentHashMap.forEach(ConcurrentHashMap.java:1603)
at cc.evil.logtest1.service.log.LogService.cleanupIdleWindows(LogService.java:101)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:724)
at cc.evil.logtest1.service.log.LogService$$SpringCGLIB$$0.cleanupIdleWindows(<generated>)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130)
at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124)
at io.micrometer.observation.Observation.observe(Observation.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124)
at org.springframework.scheduling.config.Task$OutcomeTrackingRunnable.run(Task.java:87)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:358)
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 17:47:54.986","level":"ERROR","traceId":"10f1707cf8f44670bd621a9a1bfccc55","uid":"","thread":"trace-exec-2","logger":"org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler","msg":Unexpected exception occurred invoking async method: public void cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(cc.evil.logtest1.exception.EvilBaseException),"exception":"java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.ConcurrentLinkedDeque.peekFirst()" is null
at cc.evil.logtest1.service.log.LogService$FailureWindow.release(LogService.java:154)
at cc.evil.logtest1.service.log.LogService$FailureWindow.push_back(LogService.java:146)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:85)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:53)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:114)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:317)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at cc.evil.logtest1.config.AsyncConfig.lambda$traceableExecutor$0(AsyncConfig.java:34)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 17:56:56.090","level":"ERROR","traceId":"f41acda7730c4bbfb969dffccc29d7ef","uid":"","thread":"trace-exec-5","logger":"org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler","msg":Unexpected exception occurred invoking async method: public void cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(cc.evil.logtest1.exception.EvilBaseException),"exception":"java.lang.NullPointerException: Cannot read the array length because "<local3>" is null
at cc.evil.logtest1.service.log.LogPushService.stackTraceToString(LogPushService.java:35)
at cc.evil.logtest1.service.log.LogPushService.push(LogPushService.java:29)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:90)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:53)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:114)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at cc.evil.logtest1.config.AsyncConfig.lambda$traceableExecutor$0(AsyncConfig.java:34)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}

View File

@ -0,0 +1,677 @@
{"time":"2026-03-31 14:38:17.866","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Starting LogTest1ApplicationTests using Java 21.0.3 with PID 45964 (started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 14:38:17.867","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 14:38:19.255","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Started LogTest1ApplicationTests in 1.769 seconds (process running for 2.586),"exception":""}
{"time":"2026-03-31 14:47:21.502","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Starting LogTest1ApplicationTests using Java 21.0.3 with PID 43576 (started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 14:47:21.503","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 14:47:22.862","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Started LogTest1ApplicationTests in 1.661 seconds (process running for 2.335),"exception":""}
{"time":"2026-03-31 15:50:43.267","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Starting LogTest1ApplicationTests using Java 21.0.3 with PID 50404 (started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 15:50:43.268","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 15:50:44.823","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Started LogTest1ApplicationTests in 2.016 seconds (process running for 3.01),"exception":""}
{"time":"2026-03-31 15:53:07.115","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Starting LogTest1ApplicationTests using Java 21.0.3 with PID 41924 (started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 15:53:07.116","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 15:53:08.409","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Started LogTest1ApplicationTests in 1.635 seconds (process running for 2.444),"exception":""}
{"time":"2026-03-31 15:56:21.270","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Starting LogTest1ApplicationTests using Java 21.0.3 with PID 50548 (started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 15:56:21.271","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 15:56:22.559","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Started LogTest1ApplicationTests in 1.607 seconds (process running for 2.42),"exception":""}
{"time":"2026-03-31 16:04:09.932","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Starting LogTest1ApplicationTests using Java 21.0.3 with PID 46504 (started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 16:04:09.933","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 16:04:11.343","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Started LogTest1ApplicationTests in 1.822 seconds (process running for 2.745),"exception":""}
{"time":"2026-03-31 16:31:55.796","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 50420 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 16:31:55.797","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 16:31:56.713","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 16:31:56.723","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:31:56.724","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 16:31:56.724","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 16:31:56.772","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 16:31:56.772","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 940 ms,"exception":""}
{"time":"2026-03-31 16:31:56.881","level":"WARN","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext","msg":Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'businessControllerExceptionHandler' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\handler\BusinessControllerExceptionHandler.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logPushService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogPushService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed,"exception":""}
{"time":"2026-03-31 16:31:56.883","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Stopping service [Tomcat],"exception":""}
{"time":"2026-03-31 16:31:56.891","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLogger","msg":
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.,"exception":""}
{"time":"2026-03-31 16:31:56.906","level":"ERROR","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.SpringApplication","msg":Application run failed,"exception":"org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'businessControllerExceptionHandler' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\handler\BusinessControllerExceptionHandler.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logPushService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogPushService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1228)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1130)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:990)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
at cc.evil.logtest1.LogTest1Application.main(LogTest1Application.java:14)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'logService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'logPushService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogPushService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1708)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1653)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
... 21 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'logPushService' defined in file [D:\Evil.cc\LogTest1\target\classes\cc\evil\logtest1\service\log\LogPushService.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1708)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1653)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
... 34 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mailPushService': Injection of autowired dependencies failed
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:515)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1459)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:606)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1708)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1653)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
... 47 common frames omitted
Caused by: org.springframework.util.PlaceholderResolutionException: Could not resolve placeholder 'log.push.mail.to' in value "${log.push.mail.to}"
at org.springframework.util.PlaceholderResolutionException.withValue(PlaceholderResolutionException.java:81)
at org.springframework.util.PlaceholderParser$ParsedValue.resolve(PlaceholderParser.java:298)
at org.springframework.util.PlaceholderParser.replacePlaceholders(PlaceholderParser.java:131)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:114)
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:293)
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:264)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:186)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:970)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1675)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1653)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:784)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:767)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:146)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:509)
... 58 common frames omitted
"}
{"time":"2026-03-31 16:33:43.492","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 51016 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 16:33:43.493","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 16:33:44.187","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 16:33:44.194","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:33:44.195","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 16:33:44.195","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 16:33:44.225","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 16:33:44.225","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 705 ms,"exception":""}
{"time":"2026-03-31 16:33:44.615","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:33:44.631","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 16:33:44.638","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.527 seconds (process running for 1.876),"exception":""}
{"time":"2026-03-31 16:34:17.520","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:34:17.520","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:34:17.521","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 1 ms,"exception":""}
{"time":"2026-03-31 16:35:21.137","level":"WARN","traceId":"2a57b2401411485d8019b9177c67c983","uid":"","thread":"http-nio-8080-exec-4","logger":"org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver","msg":Failure in @ExceptionHandler cc.evil.logtest1.handler.BusinessControllerExceptionHandler#handleClientException(ClientException),"exception":"java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.ConcurrentLinkedDeque.peekFirst()" is null
at cc.evil.logtest1.service.log.LogService$FailureWindow.release(LogService.java:154)
at cc.evil.logtest1.service.log.LogService$FailureWindow.push_back(LogService.java:146)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:80)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:51)
at cc.evil.logtest1.handler.BusinessControllerExceptionHandler.handleClientException(BusinessControllerExceptionHandler.java:41)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:471)
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:73)
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:182)
at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:80)
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1360)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1161)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at cc.evil.logtest1.filters.TraceIdFilter.doFilter(TraceIdFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1774)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:35:21.137","level":"WARN","traceId":"0496b5c3279f4c168fe51260636332c4","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver","msg":Failure in @ExceptionHandler cc.evil.logtest1.handler.BusinessControllerExceptionHandler#handleClientException(ClientException),"exception":"java.lang.NullPointerException: Cannot read the array length because "<local3>" is null
at cc.evil.logtest1.service.log.LogPushService.stackTraceToString(LogPushService.java:35)
at cc.evil.logtest1.service.log.LogPushService.push(LogPushService.java:29)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:83)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:51)
at cc.evil.logtest1.handler.BusinessControllerExceptionHandler.handleClientException(BusinessControllerExceptionHandler.java:41)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:471)
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:73)
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:182)
at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:80)
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1360)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1161)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1106)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at cc.evil.logtest1.filters.TraceIdFilter.doFilter(TraceIdFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1774)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:35:21.144","level":"ERROR","traceId":"","uid":"","thread":"http-nio-8080-exec-4","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]","msg":Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: cc.evil.logtest1.exception.ClientException: 未授权访问] with root cause,"exception":"cc.evil.logtest1.exception.ClientException: 未授权访问
at cc.evil.logtest1.controller.TestController.testNormalException(TestController.java:36)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:728)
at cc.evil.logtest1.controller.TestController$$SpringCGLIB$$0.testNormalException(<generated>)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:991)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:896)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at cc.evil.logtest1.filters.TraceIdFilter.doFilter(TraceIdFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1774)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:35:21.145","level":"ERROR","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]","msg":Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: cc.evil.logtest1.exception.ClientException: 未授权访问] with root cause,"exception":"cc.evil.logtest1.exception.ClientException: 未授权访问
at cc.evil.logtest1.controller.TestController.testNormalException(TestController.java:36)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:728)
at cc.evil.logtest1.controller.TestController$$SpringCGLIB$$0.testNormalException(<generated>)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:991)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:896)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at cc.evil.logtest1.filters.TraceIdFilter.doFilter(TraceIdFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:138)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:88)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:113)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:83)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:72)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1774)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:973)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:491)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:37:38.941","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 16:37:48.867","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 52044 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 16:37:48.868","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 16:37:49.607","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 16:37:49.619","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:37:49.620","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 16:37:49.620","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 16:37:49.674","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 16:37:49.674","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 777 ms,"exception":""}
{"time":"2026-03-31 16:37:49.997","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:37:50.011","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 16:37:50.016","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.55 seconds (process running for 1.949),"exception":""}
{"time":"2026-03-31 16:37:55.949","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-7","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:37:55.949","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-7","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:37:55.950","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-7","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 0 ms,"exception":""}
{"time":"2026-03-31 16:38:41.669","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 16:38:41.677","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 16:38:54.143","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 51516 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 16:38:54.144","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 16:38:54.881","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 16:38:54.891","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:38:54.892","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 16:38:54.893","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 16:38:54.933","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 16:38:54.933","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 754 ms,"exception":""}
{"time":"2026-03-31 16:38:55.269","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:38:55.283","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 16:38:55.295","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.63 seconds (process running for 2.515),"exception":""}
{"time":"2026-03-31 16:39:03.257","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:39:03.257","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:39:03.258","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 0 ms,"exception":""}
{"time":"2026-03-31 16:40:51.182","level":"ERROR","traceId":"057234bb1a6b471094c51620400b2bd7","uid":"","thread":"trace-exec-4","logger":"org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler","msg":Unexpected exception occurred invoking async method: public void cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(cc.evil.logtest1.exception.EvilBaseException),"exception":"java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.ConcurrentLinkedDeque.peekFirst()" is null
at cc.evil.logtest1.service.log.LogService$FailureWindow.release(LogService.java:157)
at cc.evil.logtest1.service.log.LogService$FailureWindow.push_back(LogService.java:149)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:83)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:53)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:114)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:317)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at cc.evil.logtest1.config.AsyncConfig.lambda$traceableExecutor$0(AsyncConfig.java:34)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:42:49.556","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 16:42:49.569","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 16:43:02.801","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 52368 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 16:43:02.802","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 16:43:03.537","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 16:43:03.546","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:43:03.547","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 16:43:03.547","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 16:43:03.581","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 16:43:03.581","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 748 ms,"exception":""}
{"time":"2026-03-31 16:43:03.913","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:43:03.926","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 16:43:03.932","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.569 seconds (process running for 2.128),"exception":""}
{"time":"2026-03-31 16:43:08.452","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:43:08.452","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:43:08.454","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 2 ms,"exception":""}
{"time":"2026-03-31 16:43:47.835","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 16:43:47.845","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 16:45:34.983","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 45428 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 16:45:34.984","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 16:45:35.596","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 16:45:35.604","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:45:35.605","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 16:45:35.605","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 16:45:35.634","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 16:45:35.634","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 623 ms,"exception":""}
{"time":"2026-03-31 16:45:35.911","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:45:35.922","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 16:45:35.927","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.297 seconds (process running for 1.613),"exception":""}
{"time":"2026-03-31 16:45:41.299","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:45:41.299","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:45:41.300","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 1 ms,"exception":""}
{"time":"2026-03-31 16:45:42.013","level":"ERROR","traceId":"02cfc3affc7f4ec0b4db470bd403356c","uid":"","thread":"trace-exec-1","logger":"org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler","msg":Unexpected exception occurred invoking async method: public void cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(cc.evil.logtest1.exception.EvilBaseException),"exception":"org.springframework.mail.MailSendException: Failed messages: jakarta.mail.SendFailedException: No recipient addresses; message exceptions (1) are:
Failed message 1: jakarta.mail.SendFailedException: No recipient addresses
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:453)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:317)
at org.springframework.mail.MailSender.send(MailSender.java:42)
at cc.evil.logtest1.service.log.MailPushService.pushToAll(MailPushService.java:32)
at cc.evil.logtest1.service.log.LogPushService.push(LogPushService.java:30)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:49)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:114)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at cc.evil.logtest1.config.AsyncConfig.lambda$traceableExecutor$0(AsyncConfig.java:34)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 16:46:22.784","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 16:46:22.789","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 16:46:26.416","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 47860 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 16:46:26.417","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 16:46:27.065","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 16:46:27.072","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:46:27.074","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 16:46:27.074","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 16:46:27.105","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 16:46:27.106","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 664 ms,"exception":""}
{"time":"2026-03-31 16:46:27.404","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 16:46:27.416","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 16:46:27.421","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.364 seconds (process running for 1.678),"exception":""}
{"time":"2026-03-31 16:46:30.314","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:46:30.315","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 16:46:30.316","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 1 ms,"exception":""}
{"time":"2026-03-31 17:13:18.543","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 17:13:18.551","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 17:19:36.567","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 53768 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 17:19:36.567","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 17:19:37.307","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 17:19:37.317","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:19:37.318","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 17:19:37.319","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 17:19:37.373","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 17:19:37.373","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 779 ms,"exception":""}
{"time":"2026-03-31 17:19:37.699","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:19:37.718","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 17:19:37.724","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.566 seconds (process running for 2.068),"exception":""}
{"time":"2026-03-31 17:40:08.330","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 17:40:08.339","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 17:40:14.381","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 53524 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 17:40:14.382","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 17:40:15.156","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 17:40:15.169","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:40:15.170","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 17:40:15.170","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 17:40:15.210","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 17:40:15.210","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 795 ms,"exception":""}
{"time":"2026-03-31 17:40:15.515","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:40:15.528","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 17:40:15.533","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.58 seconds (process running for 2.005),"exception":""}
{"time":"2026-03-31 17:40:20.248","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:40:20.248","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:40:20.248","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-1","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 0 ms,"exception":""}
{"time":"2026-03-31 17:40:20.274","level":"INFO","traceId":"57e2e79407a34af88bdf2733877883da","uid":"","thread":"trace-exec-1","logger":"cc.evil.logtest1.service.log.LogService","msg":Push now because setting in exception pushed log for exception: cc.evil.logtest1.exception.ClientException, ruleKey: cc.evil.logtest1.controller.TestController#testNormalException.,"exception":""}
{"time":"2026-03-31 17:40:21.458","level":"INFO","traceId":"57e2e79407a34af88bdf2733877883da","uid":"","thread":"trace-exec-1","logger":"cc.evil.logtest1.service.log.MailPushService","msg":Successfully sent log email to 2207086349@qq.com.,"exception":""}
{"time":"2026-03-31 17:43:11.586","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 17:43:11.598","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 17:43:19.925","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 54216 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 17:43:19.926","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 17:43:20.895","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 17:43:20.908","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:43:20.910","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 17:43:20.910","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 17:43:20.955","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 17:43:20.956","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 994 ms,"exception":""}
{"time":"2026-03-31 17:43:21.351","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:43:21.364","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 17:43:21.372","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.973 seconds (process running for 2.622),"exception":""}
{"time":"2026-03-31 17:43:23.803","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:43:23.803","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:43:23.804","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 1 ms,"exception":""}
{"time":"2026-03-31 17:43:43.419","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 17:43:43.430","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 17:43:56.982","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 47560 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 17:43:56.983","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 17:43:57.695","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 17:43:57.703","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:43:57.704","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 17:43:57.705","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 17:43:57.736","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 17:43:57.736","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 718 ms,"exception":""}
{"time":"2026-03-31 17:43:58.038","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:43:58.050","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 17:43:58.055","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.534 seconds (process running for 1.95),"exception":""}
{"time":"2026-03-31 17:44:01.072","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:44:01.073","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:44:01.074","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 1 ms,"exception":""}
{"time":"2026-03-31 17:44:49.635","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 17:44:49.647","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 17:44:52.897","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 44484 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 17:44:52.898","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 17:44:53.737","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 17:44:53.747","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:44:53.748","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 17:44:53.748","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 17:44:53.789","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 17:44:53.789","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 862 ms,"exception":""}
{"time":"2026-03-31 17:44:54.147","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:44:54.159","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 17:44:54.165","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.725 seconds (process running for 2.242),"exception":""}
{"time":"2026-03-31 17:44:58.145","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:44:58.145","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:44:58.146","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 1 ms,"exception":""}
{"time":"2026-03-31 17:47:53.992","level":"ERROR","traceId":"","uid":"","thread":"scheduling-1","logger":"org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler","msg":Unexpected error occurred in scheduled task,"exception":"java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.ConcurrentLinkedDeque.peekFirst()" is null
at cc.evil.logtest1.service.log.LogService$FailureWindow.release(LogService.java:154)
at cc.evil.logtest1.service.log.LogService.lambda$cleanupIdleWindows$1(LogService.java:102)
at java.base/java.util.concurrent.ConcurrentHashMap.forEach(ConcurrentHashMap.java:1603)
at cc.evil.logtest1.service.log.LogService.cleanupIdleWindows(LogService.java:101)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:724)
at cc.evil.logtest1.service.log.LogService$$SpringCGLIB$$0.cleanupIdleWindows(<generated>)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130)
at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124)
at io.micrometer.observation.Observation.observe(Observation.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124)
at org.springframework.scheduling.config.Task$OutcomeTrackingRunnable.run(Task.java:87)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.runAndReset$$$capture(FutureTask.java:358)
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 17:47:54.986","level":"ERROR","traceId":"10f1707cf8f44670bd621a9a1bfccc55","uid":"","thread":"trace-exec-2","logger":"org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler","msg":Unexpected exception occurred invoking async method: public void cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(cc.evil.logtest1.exception.EvilBaseException),"exception":"java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because the return value of "java.util.concurrent.ConcurrentLinkedDeque.peekFirst()" is null
at cc.evil.logtest1.service.log.LogService$FailureWindow.release(LogService.java:154)
at cc.evil.logtest1.service.log.LogService$FailureWindow.push_back(LogService.java:146)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:85)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:53)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:114)
at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:317)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
at cc.evil.logtest1.config.AsyncConfig.lambda$traceableExecutor$0(AsyncConfig.java:34)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 17:56:45.115","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 17:56:45.122","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 17:56:50.205","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 45240 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 17:56:50.205","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 17:56:50.855","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 17:56:50.864","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:56:50.865","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 17:56:50.865","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 17:56:50.899","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 17:56:50.899","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 663 ms,"exception":""}
{"time":"2026-03-31 17:56:51.193","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:56:51.204","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 17:56:51.209","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.381 seconds (process running for 1.733),"exception":""}
{"time":"2026-03-31 17:56:52.949","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:56:52.949","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:56:52.950","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 1 ms,"exception":""}
{"time":"2026-03-31 17:56:56.088","level":"INFO","traceId":"f41acda7730c4bbfb969dffccc29d7ef","uid":"","thread":"trace-exec-5","logger":"cc.evil.logtest1.service.log.LogService","msg":Push because threshold reached for exception: cc.evil.logtest1.exception.InternalServerException, ruleKey: cc.evil.logtest1.controller.TestController#testNormalException1, cnt: 5.,"exception":""}
{"time":"2026-03-31 17:56:56.090","level":"ERROR","traceId":"f41acda7730c4bbfb969dffccc29d7ef","uid":"","thread":"trace-exec-5","logger":"org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler","msg":Unexpected exception occurred invoking async method: public void cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(cc.evil.logtest1.exception.EvilBaseException),"exception":"java.lang.NullPointerException: Cannot read the array length because "<local3>" is null
at cc.evil.logtest1.service.log.LogPushService.stackTraceToString(LogPushService.java:35)
at cc.evil.logtest1.service.log.LogPushService.push(LogPushService.java:29)
at cc.evil.logtest1.service.log.LogService.evaluateThresholdPolicy(LogService.java:90)
at cc.evil.logtest1.service.log.LogService.pushLogWithDefaultPolicy(LogService.java:53)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:360)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:114)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at cc.evil.logtest1.config.AsyncConfig.lambda$traceableExecutor$0(AsyncConfig.java:34)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
"}
{"time":"2026-03-31 17:57:51.223","level":"INFO","traceId":"","uid":"","thread":"scheduling-1","logger":"cc.evil.logtest1.service.log.LogService","msg":Remove idle window for ruleKey: cc.evil.logtest1.controller.TestController#testNormalException1, because cleanup schedule.,"exception":""}
{"time":"2026-03-31 17:58:11.570","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 17:58:11.575","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 17:58:15.134","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.3 with PID 54892 (D:\Evil.cc\LogTest1\target\classes started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 17:58:15.134","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 17:58:15.823","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-03-31 17:58:15.832","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:58:15.833","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-03-31 17:58:15.834","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-03-31 17:58:15.865","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-03-31 17:58:15.866","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 703 ms,"exception":""}
{"time":"2026-03-31 17:58:16.183","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-03-31 17:58:16.195","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-03-31 17:58:16.200","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.445 seconds (process running for 1.78),"exception":""}
{"time":"2026-03-31 17:58:22.791","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring DispatcherServlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:58:22.791","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Initializing Servlet 'dispatcherServlet',"exception":""}
{"time":"2026-03-31 17:58:22.791","level":"INFO","traceId":"","uid":"","thread":"http-nio-8080-exec-2","logger":"org.springframework.web.servlet.DispatcherServlet","msg":Completed initialization in 0 ms,"exception":""}
{"time":"2026-03-31 17:58:25.568","level":"INFO","traceId":"1505ae3f6ed849958b3641ff31c4e206","uid":"","thread":"trace-exec-5","logger":"cc.evil.logtest1.service.log.LogService","msg":Push because threshold reached for exception: cc.evil.logtest1.exception.InternalServerException, ruleKey: cc.evil.logtest1.controller.TestController#testNormalException1, cnt: 5.,"exception":""}
{"time":"2026-03-31 17:58:26.539","level":"INFO","traceId":"1505ae3f6ed849958b3641ff31c4e206","uid":"","thread":"trace-exec-5","logger":"cc.evil.logtest1.service.log.MailPushService","msg":Successfully sent log email to 2207086349@qq.com.,"exception":""}
{"time":"2026-03-31 18:04:11.560","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-03-31 18:04:11.566","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-03-31 21:12:52.035","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Starting LogTest1ApplicationTests using Java 21.0.3 with PID 38364 (started by Admin in D:\Evil.cc\LogTest1),"exception":""}
{"time":"2026-03-31 21:12:52.037","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-03-31 21:12:53.539","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1ApplicationTests","msg":Started LogTest1ApplicationTests in 1.917 seconds (process running for 2.735),"exception":""}

File diff suppressed because it is too large Load Diff

0
logs/app-audit.log Normal file
View File

1126
logs/app-error.log Normal file

File diff suppressed because it is too large Load Diff

72
logs/app-info.log Normal file
View File

@ -0,0 +1,72 @@
{"time":"2026-04-03 16:28:19.590","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.10 with PID 26900 (D:\SpringOcean\AgrifeLogTest\target\classes started by y2207 in D:\SpringOcean\AgrifeLogTest),"exception":""}
{"time":"2026-04-03 16:28:19.591","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-04-03 16:28:20.448","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-04-03 16:28:20.472","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 16:28:20.473","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-04-03 16:28:20.475","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-04-03 16:28:20.513","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-04-03 16:28:20.513","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 891 ms,"exception":""}
{"time":"2026-04-03 16:28:20.933","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 16:28:20.947","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-04-03 16:28:20.953","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.831 seconds (process running for 2.326),"exception":""}
{"time":"2026-04-03 16:28:20.956","level":"INFO","traceId":"","uid":"","thread":"scheduling-1","logger":"cc.evil.logtest1.service.log.LogService","msg":Cleanup Idle windows for now.,"exception":""}
{"time":"2026-04-03 16:28:29.516","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-04-03 16:28:29.523","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-04-03 16:28:50.761","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.10 with PID 21608 (D:\SpringOcean\AgrifeLogTest\target\classes started by y2207 in D:\SpringOcean\AgrifeLogTest),"exception":""}
{"time":"2026-04-03 16:28:50.764","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-04-03 16:28:51.695","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-04-03 16:28:51.706","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 16:28:51.707","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-04-03 16:28:51.707","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-04-03 16:28:51.744","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-04-03 16:28:51.744","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 934 ms,"exception":""}
{"time":"2026-04-03 16:28:52.096","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 16:28:52.111","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-04-03 16:28:52.116","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.961 seconds (process running for 2.439),"exception":""}
{"time":"2026-04-03 16:28:52.120","level":"INFO","traceId":"","uid":"","thread":"scheduling-1","logger":"cc.evil.logtest1.service.log.LogService","msg":Cleanup Idle windows for now.,"exception":""}
{"time":"2026-04-03 16:29:04.763","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-04-03 16:29:04.769","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-04-03 16:29:06.573","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.10 with PID 21656 (D:\SpringOcean\AgrifeLogTest\target\classes started by y2207 in D:\SpringOcean\AgrifeLogTest),"exception":""}
{"time":"2026-04-03 16:29:06.574","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-04-03 16:29:07.301","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-04-03 16:29:07.310","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 16:29:07.311","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-04-03 16:29:07.311","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-04-03 16:29:07.342","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-04-03 16:29:07.343","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 740 ms,"exception":""}
{"time":"2026-04-03 16:29:07.698","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 16:29:07.712","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-04-03 16:29:07.717","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.614 seconds (process running for 2.017),"exception":""}
{"time":"2026-04-03 16:29:07.720","level":"INFO","traceId":"","uid":"","thread":"scheduling-1","logger":"cc.evil.logtest1.service.log.LogService","msg":Cleanup Idle windows for now.,"exception":""}
{"time":"2026-04-03 16:30:07.734","level":"INFO","traceId":"","uid":"","thread":"scheduling-1","logger":"cc.evil.logtest1.service.log.LogService","msg":Cleanup Idle windows for now.,"exception":""}
{"time":"2026-04-03 16:31:07.747","level":"INFO","traceId":"","uid":"","thread":"scheduling-1","logger":"cc.evil.logtest1.service.log.LogService","msg":Cleanup Idle windows for now.,"exception":""}
{"time":"2026-04-03 16:31:19.626","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-04-03 16:31:19.633","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-04-03 16:31:22.609","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.10 with PID 9536 (D:\SpringOcean\AgrifeLogTest\target\classes started by y2207 in D:\SpringOcean\AgrifeLogTest),"exception":""}
{"time":"2026-04-03 16:31:22.610","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-04-03 16:31:23.411","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-04-03 16:31:23.419","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 16:31:23.420","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-04-03 16:31:23.421","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-04-03 16:31:23.457","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-04-03 16:31:23.458","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 809 ms,"exception":""}
{"time":"2026-04-03 16:31:23.868","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 16:31:23.881","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-04-03 16:31:23.888","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.789 seconds (process running for 2.189),"exception":""}
{"time":"2026-04-03 16:31:23.894","level":"INFO","traceId":"","uid":"","thread":"scheduling-1","logger":"cc.evil.logtest1.service.log.LogService","msg":Cleanup Idle windows for now.,"exception":""}
{"time":"2026-04-03 16:31:46.564","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-04-03 16:31:46.569","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}
{"time":"2026-04-03 17:18:39.475","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Starting LogTest1Application using Java 21.0.10 with PID 27092 (D:\SpringOcean\AgrifeLogTest\target\classes started by y2207 in D:\SpringOcean\AgrifeLogTest),"exception":""}
{"time":"2026-04-03 17:18:39.476","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":The following 1 profile is active: "dev","exception":""}
{"time":"2026-04-03 17:18:40.405","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat initialized with port 8080 (http),"exception":""}
{"time":"2026-04-03 17:18:40.424","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Initializing ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 17:18:40.426","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardService","msg":Starting service [Tomcat],"exception":""}
{"time":"2026-04-03 17:18:40.427","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.StandardEngine","msg":Starting Servlet engine: [Apache Tomcat/10.1.50],"exception":""}
{"time":"2026-04-03 17:18:40.482","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","msg":Initializing Spring embedded WebApplicationContext,"exception":""}
{"time":"2026-04-03 17:18:40.482","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext","msg":Root WebApplicationContext: initialization completed in 975 ms,"exception":""}
{"time":"2026-04-03 17:18:40.889","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.apache.coyote.http11.Http11NioProtocol","msg":Starting ProtocolHandler ["http-nio-8080"],"exception":""}
{"time":"2026-04-03 17:18:40.901","level":"INFO","traceId":"","uid":"","thread":"main","logger":"org.springframework.boot.web.embedded.tomcat.TomcatWebServer","msg":Tomcat started on port 8080 (http) with context path '/',"exception":""}
{"time":"2026-04-03 17:18:40.907","level":"INFO","traceId":"","uid":"","thread":"main","logger":"cc.evil.logtest1.LogTest1Application","msg":Started LogTest1Application in 1.918 seconds (process running for 2.401),"exception":""}
{"time":"2026-04-03 17:18:40.911","level":"INFO","traceId":"","uid":"","thread":"scheduling-1","logger":"cc.evil.logtest1.service.log.LogService","msg":Cleanup Idle windows for now.,"exception":""}
{"time":"2026-04-03 17:18:43.880","level":"INFO","traceId":"","uid":"","thread":"SpringApplicationShutdownHook","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Commencing graceful shutdown. Waiting for active requests to complete,"exception":""}
{"time":"2026-04-03 17:18:43.885","level":"INFO","traceId":"","uid":"","thread":"tomcat-shutdown","logger":"org.springframework.boot.web.embedded.tomcat.GracefulShutdown","msg":Graceful shutdown complete,"exception":""}

15
logs/app.log Normal file
View File

@ -0,0 +1,15 @@
{"timestamp":"2026-03-30 16:23:55.786","thread":"main","traceId":"","level":"INFO","logger":"cc.evil.logtest1.LogTest1Application","message":"Starting LogTest1Application using Java 21.0.10 with PID 5372 (D:\workspace\evil.cc\LogTest1\target\classes started by y2207 in D:\workspace\evil.cc\LogTest1)"},
{"timestamp":"2026-03-30 16:23:55.787","thread":"main","traceId":"","level":"INFO","logger":"cc.evil.logtest1.LogTest1Application","message":"The following 1 profile is active: "dev""},
{"timestamp":"2026-03-30 16:23:56.427","thread":"main","traceId":"","level":"INFO","logger":"org.springframework.boot.tomcat.TomcatWebServer","message":"Tomcat initialized with port 8080 (http)"},
{"timestamp":"2026-03-30 16:23:56.435","thread":"main","traceId":"","level":"INFO","logger":"org.apache.coyote.http11.Http11NioProtocol","message":"Initializing ProtocolHandler ["http-nio-8080"]"},
{"timestamp":"2026-03-30 16:23:56.438","thread":"main","traceId":"","level":"INFO","logger":"org.apache.catalina.core.StandardService","message":"Starting service [Tomcat]"},
{"timestamp":"2026-03-30 16:23:56.438","thread":"main","traceId":"","level":"INFO","logger":"org.apache.catalina.core.StandardEngine","message":"Starting Servlet engine: [Apache Tomcat/11.0.20]"},
{"timestamp":"2026-03-30 16:23:56.489","thread":"main","traceId":"","level":"INFO","logger":"org.springframework.boot.web.context.servlet.WebApplicationContextInitializer","message":"Root WebApplicationContext: initialization completed in 671 ms"},
{"timestamp":"2026-03-30 16:23:56.854","thread":"main","traceId":"","level":"INFO","logger":"org.apache.coyote.http11.Http11NioProtocol","message":"Starting ProtocolHandler ["http-nio-8080"]"},
{"timestamp":"2026-03-30 16:23:56.870","thread":"main","traceId":"","level":"INFO","logger":"org.springframework.boot.tomcat.TomcatWebServer","message":"Tomcat started on port 8080 (http) with context path '/'"},
{"timestamp":"2026-03-30 16:23:56.874","thread":"main","traceId":"","level":"INFO","logger":"cc.evil.logtest1.LogTest1Application","message":"Started LogTest1Application in 1.591 seconds (process running for 2.108)"},
{"timestamp":"2026-03-30 16:24:06.130","thread":"SpringApplicationShutdownHook","traceId":"","level":"INFO","logger":"org.springframework.boot.tomcat.GracefulShutdown","message":"Commencing graceful shutdown. Waiting for active requests to complete"},
{"timestamp":"2026-03-30 16:24:06.135","thread":"tomcat-shutdown","traceId":"","level":"INFO","logger":"org.springframework.boot.tomcat.GracefulShutdown","message":"Graceful shutdown complete"},
{"timestamp":"2026-03-30 16:24:38.365","thread":"main","traceId":"","level":"INFO","logger":"cc.evil.logtest1.LogTest1ApplicationTests","message":"Starting LogTest1ApplicationTests using Java 21.0.10 with PID 18384 (started by y2207 in D:\workspace\evil.cc\LogTest1)"},
{"timestamp":"2026-03-30 16:24:38.369","thread":"main","traceId":"","level":"INFO","logger":"cc.evil.logtest1.LogTest1ApplicationTests","message":"The following 1 profile is active: "dev""},
{"timestamp":"2026-03-30 16:24:39.343","thread":"main","traceId":"","level":"INFO","logger":"cc.evil.logtest1.LogTest1ApplicationTests","message":"Started LogTest1ApplicationTests in 1.31 seconds (process running for 3.932)"},

295
mvnw vendored Normal file
View File

@ -0,0 +1,295 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.3.4
#
# Optional ENV vars
# -----------------
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
if [ -n "${JAVA_HOME-}" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
printf %s\\n "$1" >&2
exit 1
}
trim() {
# MWRAPPER-139:
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
# Needed for removing poorly interpreted newline sequences when running in more
# exotic environments such as mingw bash on Windows.
printf "%s" "${1}" | tr -d '[:space:]'
}
scriptDir="$(dirname "$0")"
scriptName="$(basename "$0")"
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "${key-}" in
distributionUrl) distributionUrl=$(trim "${value-}") ;;
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
esac
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
elif command -v sha256sum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
# Find the actual extracted directory name (handles snapshots where filename != directory name)
actualDistributionDir=""
# First try the expected directory name (for regular distributions)
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
actualDistributionDir="$distributionUrlNameMain"
fi
fi
# If not found, search for any directory with the Maven executable (for snapshots)
if [ -z "$actualDistributionDir" ]; then
# enable globbing to iterate over items
set +f
for dir in "$TMP_DOWNLOAD_DIR"/*; do
if [ -d "$dir" ]; then
if [ -f "$dir/bin/$MVN_CMD" ]; then
actualDistributionDir="$(basename "$dir")"
break
fi
fi
done
set -f
fi
if [ -z "$actualDistributionDir" ]; then
verbose "Contents of $TMP_DOWNLOAD_DIR:"
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
die "Could not find Maven distribution directory in extracted archive"
fi
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
clean || :
exec_maven "$@"

189
mvnw.cmd vendored Normal file
View File

@ -0,0 +1,189 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.3.4
@REM
@REM Optional ENV vars
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_M2_PATH = "$HOME/.m2"
if ($env:MAVEN_USER_HOME) {
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
}
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
}
$MAVEN_WRAPPER_DISTS = $null
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
} else {
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
}
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
# Find the actual extracted directory name (handles snapshots where filename != directory name)
$actualDistributionDir = ""
# First try the expected directory name (for regular distributions)
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
$actualDistributionDir = $distributionUrlNameMain
}
# If not found, search for any directory with the Maven executable (for snapshots)
if (!$actualDistributionDir) {
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
if (Test-Path -Path $testPath -PathType Leaf) {
$actualDistributionDir = $_.Name
}
}
}
if (!$actualDistributionDir) {
Write-Error "Could not find Maven distribution directory in extracted archive"
}
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

161
pom.xml Normal file
View File

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.10</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cc.Evil</groupId>
<artifactId>LogTest1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>LogTest1</name>
<description>LogTest1</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
<mybatis-plus.version>3.5.15</mybatis-plus.version>
<redisson.version>3.39.0</redisson.version>
<java-jwt.version>4.4.0</java-jwt.version>
</properties>
<dependencies>
<!-- Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>${java-jwt.version}</version>
</dependency>
<!-- Jackson Time -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 邮箱服务 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- ================= 测试 ================= -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mariadb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,17 @@
package cc.evil.logtest1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
@ServletComponentScan // 启用 @WebFilter 的注解
@EnableScheduling // 启用定时任务
@SpringBootApplication
public class LogTest1Application {
public static void main(String[] args) {
SpringApplication.run(LogTest1Application.class, args);
}
}

View File

@ -0,0 +1,28 @@
package cc.evil.logtest1.aop.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 一些记录controller日志的配置, 待扩展;
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultControllerLog {
/**
* 功能描述
*/
String desc() default "";
/**
* 是否记录请求参数
*/
boolean recordParams() default false;
/**
* 是否记录响应结果
*/
boolean recordResult() default true;
}

View File

@ -0,0 +1,109 @@
package cc.evil.logtest1.aop.aspcet;
import cc.evil.logtest1.aop.annotation.DefaultControllerLog;
import cc.evil.logtest1.exception.EvilBaseException;
import cc.evil.logtest1.log.ControllerLogBO;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.lang.reflect.Method;
/**
* Controller的AOP类, 用来统计接口信息;
* <p>
* 记录的信息包括:
* - 自定义描述
* - 类名
* - 方法名
* - 请求uri
* - 请求的uid
* - 请求响应时间
* - 异常信息
* - 响应状态码
*/
@Aspect
@Slf4j
@Component
@RequiredArgsConstructor
public class DefaultControllerLogAspect {
// utils
private final ObjectMapper objectMapper;
@Around("@annotation(logconfig)")
public Object aroundController(ProceedingJoinPoint pjp, DefaultControllerLog logconfig) throws Throwable {
// 获取请求上下文
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
return pjp.proceed();
}
HttpServletRequest request = attributes.getRequest();
long startTime = System.currentTimeMillis();
// 获取方法信息
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
String className = pjp.getTarget().getClass().getSimpleName();
String methodName = method.getName();
ControllerLogBO logBo = new ControllerLogBO();
logBo.setDesc(logconfig.desc());
logBo.setClassName(className);
logBo.setMethodName(methodName);
logBo.setUri(request.getRequestURI());
logBo.setUid(getUid(request));
Throwable caught = null;
try {
return pjp.proceed();
} catch (Throwable e) {
caught = e;
throw e;
} finally {
logBo.setDurationMs(System.currentTimeMillis() - startTime);
logBo.setException(caught != null ? caught.getClass().getName() : null);
logBo.setStatus(resolveStatus(attributes, caught));
try {
log.info(objectMapper.writeValueAsString(logBo));
} catch (Exception e) {
log.warn("Failed to serialize ControllerLogBO: {}, error message: {}", logBo, e.getMessage());
}
}
}
private HttpStatus resolveStatus(ServletRequestAttributes attributes, Throwable e) {
if (e != null) {
if (e instanceof EvilBaseException) {
return ((EvilBaseException) e).getErrorCode().getHttpStatus();
}
return HttpStatus.INTERNAL_SERVER_ERROR;
}
HttpServletResponse response = attributes.getResponse();
if (response != null) {
try {
return HttpStatus.valueOf(response.getStatus());
} catch (Exception ex) {
log.warn("Failed to resolve HTTP status from response, error message: {}", ex.getMessage());
}
}
return null;
}
// TODO: 完善获取Uid的逻辑
private String getUid(HttpServletRequest request) {
return "";
}
}

View File

@ -0,0 +1,52 @@
package cc.evil.logtest1.config;
import org.slf4j.MDC;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.Map;
import java.util.concurrent.Executor;
/**
* SpringBoot异步配置类
*/
@EnableAsync
@Configuration
public class AsyncConfig {
/**
* 自定义的异步可追踪日志线程池, 这样异步也能追踪到日志链;
* 只需要标记@Async("traceableExecutor")注解就能够使用;
*/
@Bean("traceableExecutor")
public Executor traceableExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5); // 基础线程数量
executor.setMaxPoolSize(20); // 最大线程数量;
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("trace-exec-");
// 包装任务, 传递 MDC
executor.setTaskDecorator(runnable -> {
// 在提交任务时捕获当前线程的 MDC
Map<String, String> contextMap = MDC.getCopyOfContextMap();
return () -> {
try {
// 在新线程中恢复 MDC
if (contextMap != null) {
MDC.setContextMap(contextMap);
}
runnable.run();
} finally {
// 清理上下文
MDC.clear();
}
};
});
executor.initialize();
return executor;
}
}

View File

@ -0,0 +1,16 @@
package cc.evil.logtest1.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BaseConfig {
/**
* 创建默认的ObjectMapper Bean, 以便在整个应用中使用同一个实例, 不用反复实例化;
*/
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
}

View File

@ -0,0 +1,88 @@
package cc.evil.logtest1.config;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.MailSender;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
/**
* 一些邮箱的配置类, 在这里统一管理配置;
*/
@Configuration
public class MailConfig {
/**
* 邮件服务器配置
*/
@Value("${log.push.mail.username:}")
private String username;
@Value("${log.push.mail.password:}")
private String password;
@Value("${log.push.mail.host:}")
private String host;
@Value("${log.push.mail.port:}")
private int port;
@Value("${log.push.mail.protocol:smtp}")
private String protocol;
/**
* 收发邮箱配置, 默认都为空;
*/
@Getter
@Value("${log.push.mail.from-email:}")
private String fromEmail;
// 列表, 用逗号分隔
@Value("${log.push.mail.to-emails:#{new java.util.ArrayList()}}")
private List<String> toEmails;
@Getter
private Set<String> toEmailsSet = new HashSet<>();
/**
* MailSender配置;
*/
@Bean
public JavaMailSender getMailSender() {
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost(host);
sender.setPort(port);
sender.setUsername(username);
sender.setPassword(password);
sender.setProtocol(protocol);
sender.setDefaultEncoding("UTF-8");
Properties props = new Properties();
props.put("mail.smtp.auth", true);
props.put("mail.smtp.starttls.enable", true);
props.put("mail.smtp.starttls.required", true);
props.put("mail.smtp.timeout", 5000);
sender.setJavaMailProperties(props);
toEmailsSet.addAll(toEmails);
return sender;
}
/**
* 添加和删除发送邮箱;
*/
public void addEmail(List<String> toEmails) {
this.toEmailsSet.addAll(toEmails);
}
public void removeEmail(String toEmail) {
this.toEmailsSet.remove(toEmail);
}
}

View File

@ -0,0 +1,14 @@
package cc.evil.logtest1.constants;
/**
* 日志记录的一些常量设置
*/
public class LogConstants {
public static final String TRACE_ID_HEADER = "X-Trace-Id";
public static final String TRACE_ID_MDC_KEY = "traceId";
public static final String SPAN_ID_MDC_KEY = "spanId";
private LogConstants() {
}
}

View File

@ -0,0 +1,69 @@
package cc.evil.logtest1.controller;
import cc.evil.logtest1.aop.annotation.DefaultControllerLog;
import cc.evil.logtest1.exception.ClientException;
import cc.evil.logtest1.exception.EvilBaseException;
import cc.evil.logtest1.exception.EvilErrorCode;
import cc.evil.logtest1.exception.InternalServerException;
import cc.evil.logtest1.service.TestService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/test")
public class TestController {
// service
private final TestService testService;
@DefaultControllerLog(desc = "获取名字")
@GetMapping("/get-name-reverse/{name}")
public String getNameReverse(@PathVariable String name) {
log.info("getNameReverse called with name: {}", name);
String reversedName = testService.reverseStr(name);
testService.printStr(reversedName, 50);
log.info("Reversed name: {}", reversedName);
return reversedName;
}
@GetMapping("/add/{a}/{b}")
@DefaultControllerLog(desc = "加法运算")
public String add(@PathVariable String a, @PathVariable String b) {
try {
int numa = 0, numb = 0;
try {
numa = Integer.parseInt(a);
numb = Integer.parseInt(b);
} catch (NumberFormatException e) {
throw new EvilBaseException(EvilErrorCode.BAD_REQUEST, "参数必须是整数");
}
return testService.add(numa, numb);
} catch (EvilBaseException ebe) {
throw ebe;
} catch (Exception e) {
throw new InternalServerException(EvilErrorCode.UNEXPECTED_ERROR);
}
}
@GetMapping("/test-normal-exception")
public String testNormalException() {
var a = new ClientException(EvilErrorCode.UNAUTHORIZED, "401错误测试");
a.setPushLogNow(true);
throw a;
}
@GetMapping("/test-normal-exception1")
public String testNormalException1() {
throw new InternalServerException(EvilErrorCode.INTERNAL_SERVER_ERROR, "500错误测试");
}
@GetMapping("/test-unexpected-exception")
public String testUnexpectedException() {
throw new RuntimeException("这是一个未预期的异常");
}
}

View File

@ -0,0 +1,122 @@
package cc.evil.logtest1.controller.logger;
import cc.evil.logtest1.exception.ClientException;
import cc.evil.logtest1.exception.EvilBaseException;
import cc.evil.logtest1.exception.EvilErrorCode;
import cc.evil.logtest1.exception.InternalServerException;
import cc.evil.logtest1.model.dto.EmailListDTO;
import cc.evil.logtest1.model.vo.LogFileNameList;
import cc.evil.logtest1.service.log.LogFileService;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;
/**
* 实现日志的基本功能:
* - 获取日志文件列表, 支持按日期范围过滤;
* - 获取日志文件的尾部内容, 支持指定行数;
* - 下载日志文件, 支持批量下载并打包成zip;
* - 添加和删除发送邮箱;
*/
@RestController
@RequestMapping("/api/logs")
@RequiredArgsConstructor
public class LogsController {
// service
private final LogFileService logFileService;
/**
* 日志日期格式
*/
@Value("${logs.file.date_format:yyyy-MM-dd}")
private final String dateFormat = "yyyy-MM-dd";
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
@GetMapping("/files")
public LogFileNameList getLogsFiles(@RequestParam(value = "startDate", required = false) String startDate, @RequestParam(value = "endDate", required = false) String endDate) {
LocalDate start = null, end = null;
try {
if (startDate != null && !startDate.isBlank())
start = LocalDate.parse(startDate.trim(), formatter);
if (endDate != null && !endDate.isBlank())
end = LocalDate.parse(endDate.trim(), formatter);
if (start != null && end != null && start.isAfter(end))
throw new EvilBaseException(EvilErrorCode.TIME_LOGICAL_ERROR);
if (end != null && end.isAfter(LocalDate.now()))
endDate = LocalDate.now().format(formatter);
return logFileService.getLogFiles(start, end);
} catch (EvilBaseException ebe) {
throw ebe;
} catch (DateTimeParseException e) {
throw new ClientException(EvilErrorCode.BAD_REQUEST, "日期解析错误");
} catch (Exception e) {
throw new InternalServerException(EvilErrorCode.UNEXPECTED_ERROR);
}
}
@GetMapping("/tail")
public List<String> getFileTail(@RequestParam(value = "lines", defaultValue = "200") int lines) {
lines = Math.min(lines, 500);
try {
return logFileService.fileTail(lines);
} catch (EvilBaseException ebe) {
throw ebe;
} catch (Exception e) {
throw new InternalServerException(EvilErrorCode.UNEXPECTED_ERROR);
}
}
@PostMapping("/download")
public void downloadLogs(@RequestBody LogFileNameList logFileNameList, HttpServletResponse response) {
if (logFileNameList == null || logFileNameList.getLogFilesByDate() == null || logFileNameList.getLogFilesByDate().isEmpty()) {
throw new ClientException(EvilErrorCode.BAD_REQUEST, "下载文件列表不能为空");
}
try {
String downloadFileName = "logs-" + LocalDate.now().format(formatter) + ".zip";
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=\"" + downloadFileName + "\"");
logFileService.writeLogsToZip(logFileNameList, response.getOutputStream());
response.flushBuffer();
} catch (EvilBaseException ebe) {
throw ebe;
} catch (IOException e) {
throw new InternalServerException(EvilErrorCode.SERVER_FILE_IO_ERROR, "下载日志压缩包失败");
} catch (Exception e) {
throw new InternalServerException(EvilErrorCode.UNEXPECTED_ERROR);
}
}
@PostMapping("/email")
public void addEmail(@RequestBody EmailListDTO email) {
try {
logFileService.addEmails(email.getEmails());
} catch (EvilBaseException ebe) {
throw ebe;
} catch (Exception e) {
throw new InternalServerException(EvilErrorCode.UNEXPECTED_ERROR);
}
}
@DeleteMapping("/email")
public void delEmail(@RequestBody EmailListDTO email) {
try {
for (var emails : email.getEmails()) {
logFileService.removeEmail(emails);
}
} catch (EvilBaseException ebe) {
throw ebe;
} catch (Exception e) {
throw new InternalServerException(EvilErrorCode.UNEXPECTED_ERROR);
}
}
}

View File

@ -0,0 +1,23 @@
package cc.evil.logtest1.exception;
import lombok.Getter;
/**
* 客户端异常
*/
@Getter
public class ClientException extends EvilBaseException {
private final EvilErrorCode errorCode;
private final String customMsg;
public ClientException(EvilErrorCode errorCode) {
super(errorCode);
this.errorCode = errorCode;
this.customMsg = null;
}
public ClientException(EvilErrorCode errorCode, String message) {
super(errorCode, message);
this.errorCode = errorCode;
this.customMsg = message;
}
}

View File

@ -0,0 +1,31 @@
package cc.evil.logtest1.exception;
import lombok.Getter;
import lombok.Setter;
/**
* 基础异常类, 所有自定义异常都应该继承这个类
* 应该将错误码的消息传给上层异常, 用来返回给前端, 而CustomMsg是用来记录日志的, 可能包含一些敏感信息, 不应该返回给前端
*/
public class EvilBaseException extends RuntimeException {
@Getter
private final EvilErrorCode errorCode;
@Getter
private final String customMsg;
@Getter
@Setter
public boolean pushLogNow = false; // 是否立即推送日志, 而不是等待窗口再推送
public EvilBaseException(EvilErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
this.customMsg = null;
}
public EvilBaseException(EvilErrorCode errorCode, String customMsg) {
super(errorCode.getMessage());
this.errorCode = errorCode;
this.customMsg = customMsg;
}
}

View File

@ -0,0 +1,41 @@
package cc.evil.logtest1.exception;
import lombok.Getter;
import org.springframework.http.HttpStatus;
@Getter
public enum EvilErrorCode {
/**
* 4** 错误
*/
BAD_REQUEST(HttpStatus.BAD_REQUEST, 40001, "请求参数错误"),
TIME_LOGICAL_ERROR(HttpStatus.BAD_REQUEST, 40002, "时间逻辑错误"),
UNAUTHORIZED(HttpStatus.UNAUTHORIZED, 40101, "未授权访问"),
/**
* 5** 错误
*/
UNEXPECTED_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 50000, "未知错误"),
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 50001, "服务器内部错误"),
SERVER_FILE_IO_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 50002, "服务器文件系统错误"),
INTERNAL_PRECONDITION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 50003, "内部参数校验错误")
;
private final HttpStatus httpStatus;
private final int businessCode;
private final String message;
EvilErrorCode(HttpStatus httpStatus, int businessCode, String message) {
this.httpStatus = httpStatus;
this.businessCode = businessCode;
this.message = message;
}
}

View File

@ -0,0 +1,25 @@
package cc.evil.logtest1.exception;
import lombok.Getter;
import lombok.Setter;
/**
* 服务器内部异常
*/
@Getter
public class InternalServerException extends EvilBaseException {
private final EvilErrorCode errorCode;
private final String customMsg;
public InternalServerException(EvilErrorCode errorCode) {
super(errorCode);
this.errorCode = errorCode;
this.customMsg = null;
}
public InternalServerException(EvilErrorCode errorCode, String message) {
super(errorCode, message);
this.errorCode = errorCode;
this.customMsg = message;
}
}

View File

@ -0,0 +1,42 @@
package cc.evil.logtest1.filters;
import cc.evil.logtest1.constants.LogConstants;
import cc.evil.logtest1.utils.TraceContextUtil;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;
import java.io.IOException;
@Order(1)
//@Component -> 不需要这个, 这个会和WebFilter冲突, 导致重复注册Bean
@WebFilter(urlPatterns = "/*", filterName = "traceIdFilter") // 过滤所有请求
public class TraceIdFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
System.out.println("TraceIdFilter doFilter: " + httpRequest.getRequestURI());
try {
// ========== 1. 获取或生成 TraceId ==========
String traceId = httpRequest.getHeader(LogConstants.TRACE_ID_HEADER);
TraceContextUtil.init(traceId);
// ========== 2. 放入请求属性方便后续取用 ==========
httpRequest.setAttribute(LogConstants.TRACE_ID_HEADER, TraceContextUtil.getTraceId());
// ========== 3. 设置到响应头 ==========
httpResponse.setHeader(LogConstants.TRACE_ID_HEADER, TraceContextUtil.getTraceId());
// ========== 4. 放行 ==========
filterChain.doFilter(servletRequest, servletResponse);
} finally {
// ========== 5. 清理 ==========
TraceContextUtil.clear();
}
}
}

View File

@ -0,0 +1,123 @@
package cc.evil.logtest1.handler;
import cc.evil.logtest1.exception.ClientException;
import cc.evil.logtest1.exception.EvilBaseException;
import cc.evil.logtest1.exception.EvilErrorCode;
import cc.evil.logtest1.exception.InternalServerException;
import cc.evil.logtest1.model.vo.EvilResponse;
import cc.evil.logtest1.service.log.LogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
@Slf4j
@RestControllerAdvice(basePackages = "cc.evil.logtest1.controller")
@RequiredArgsConstructor
public class BusinessControllerExceptionHandler {
private final LogService logService;
/**
* 处理服务器内部错误异常
*/
@ExceptionHandler(InternalServerException.class)
public ResponseEntity<EvilResponse<Void>> handleInternalServerError(InternalServerException e) {
// 推送日志到日志系统
logService.pushLogWithDefaultPolicy(e);
// 将错误返回给前端
return ResponseEntity
.status(e.getErrorCode().getHttpStatus())
.body(EvilResponse.error(e.getErrorCode()));
}
/**
* 处理客户端错误
*/
@ExceptionHandler(ClientException.class)
public ResponseEntity<EvilResponse<Void>> handleClientException(ClientException e) {
// 推送日志到日志系统
logService.pushLogWithDefaultPolicy(e);
// 将错误返回给前端
return ResponseEntity
.status(e.getErrorCode().getHttpStatus())
.body(EvilResponse.error(e.getErrorCode()));
}
/**
* 处理泛类
*/
@ExceptionHandler(EvilBaseException.class)
public ResponseEntity<EvilResponse<Void>> handleBaseException(EvilBaseException e) {
// 推送日志到日志系统
logService.pushLogWithDefaultPolicy(e);
// 将错误返回给前端
return ResponseEntity
.status(e.getErrorCode().getHttpStatus())
.body(EvilResponse.error(e.getErrorCode()));
}
/**
* 处理 Controller 参数解析错误
* 这类错误属于客户端请求不合法, 不应按意料之外异常触发邮件告警
*/
// @ExceptionHandler({
// MethodArgumentTypeMismatchException.class,
// MissingServletRequestParameterException.class,
// HttpMessageNotReadableException.class,
// MethodArgumentNotValidException.class,
// BindException.class
// })
// public ResponseEntity<EvilResponse<Void>> handleControllerBadRequest(Exception e) {
// log.warn("Bad request in controller: {}", e.getMessage());
// return ResponseEntity
// .status(HttpStatus.BAD_REQUEST)
// .body(EvilResponse.error(EvilErrorCode.BAD_REQUEST));
// }
/*
HttpMessageNotReadableExceptionJSON 解析失败 返回 400
HttpRequestMethodNotSupportedException方法不支持 返回 405
MissingServletRequestParameterException缺少参数 返回 400
NoHandlerFoundException404 返回 404
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<EvilResponse<Void>> handleHttpMessageNotReadable(
HttpMessageNotReadableException ex) {
// 可选记录日志注意不要记录敏感数据
log.warn("JSON parse error: {}", ex.getMessage());
// 返回 400 Bad Request + 友好的错误信息
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(EvilResponse.error(EvilErrorCode.BAD_REQUEST));
}
/**
* 未捕获的异常 -> 不应该这样做, 太宽泛了
*/
// @ExceptionHandler(Exception.class)
// public ResponseEntity<EvilResponse<Void>> handleException(Exception e) {
// log.error("Unexpected exception caught: ", e);
// // 推送日志到日志系统
// logService.pushLogWithDefaultPolicy(e);
//
// // 将错误返回给前端使用通用的服务器内部错误码
// return ResponseEntity
// .status(HttpStatus.INTERNAL_SERVER_ERROR)
// .body(EvilResponse.error(EvilErrorCode.INTERNAL_SERVER_ERROR));
// }
}

View File

@ -0,0 +1,22 @@
package cc.evil.logtest1.log;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.http.HttpStatus;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ControllerLogBO {
private String desc;
private String className;
private String methodName;
private String uri;
private String uid;
private long durationMs;
private HttpStatus status;
private String exception;
}

View File

@ -0,0 +1,14 @@
package cc.evil.logtest1.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EmailListDTO {
List<String> emails;
}

View File

@ -0,0 +1,14 @@
package cc.evil.logtest1.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FileDownloadDTO {
List<String> files;
}

View File

@ -0,0 +1,40 @@
package cc.evil.logtest1.model.vo;
import cc.evil.logtest1.exception.EvilErrorCode;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class EvilResponse<T> {
private Integer code;
private String message;
private T data;
public static <T> EvilResponse<T> success(T data) {
return EvilResponse.<T>builder()
.code(0)
.message("success")
.data(data)
.build();
}
public static <T> EvilResponse<T> success(T data, String successMsg) {
return EvilResponse.<T>builder()
.code(0)
.message(successMsg)
.data(data)
.build();
}
public static <T> EvilResponse<T> success() {
return success(null);
}
public static <T> EvilResponse<T> error(EvilErrorCode errorCode) {
return EvilResponse.<T>builder()
.code(errorCode.getBusinessCode())
.message(errorCode.getMessage())
.build();
}
}

View File

@ -0,0 +1,17 @@
package cc.evil.logtest1.model.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LogFileNameList {
Map<String, List<String>> logFilesByDate;
}

View File

@ -0,0 +1,35 @@
package cc.evil.logtest1.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class TestService {
public String reverseStr(String str) {
log.info("Start reversing string, str = {}.", str);
var res = new StringBuilder(str).reverse().toString();
log.info("Finished reversing string, res = {}.", res);
return res;
}
public String add(int a, int b) {
String res = String.valueOf(a + b);
log.info("Finished add, res = {}.", res);
return res;
}
@Async("traceableExecutor")
public void printStr(String str, int n) {
for (int i = 1; i <= n; i++) {
log.info("Async print {}: {}", i, str);
try {
Thread.sleep(1000);
} catch (InterruptedException ignore) {
}
}
}
}

View File

@ -0,0 +1,265 @@
package cc.evil.logtest1.service.log;
import cc.evil.logtest1.config.MailConfig;
import cc.evil.logtest1.exception.EvilBaseException;
import cc.evil.logtest1.exception.EvilErrorCode;
import cc.evil.logtest1.exception.InternalServerException;
import cc.evil.logtest1.model.vo.LogFileNameList;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Slf4j
@Service
@RequiredArgsConstructor
public class LogFileService {
// config
private final MailConfig mailConfig;
/**
* 日期基准路径
*/
@Value("${logs.file.base-dir:./logs/}")
private String logsFileBaseDir;
/**
* 日志日期格式
*/
@Value("${logs.file.date_format:yyyy-MM-dd}")
private final String dateFormat = "yyyy-MM-dd";
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
/**
* 日志命名格式
*/
@Value("${logs.file.info_prefix:app-info}")
private String infoLogsFileNamePrefix = "app-info";
/**
* 获取时间范围内所有日志文件
*/
public LogFileNameList getLogFiles(LocalDate startTime, LocalDate endTime) {
if (startTime != null && endTime != null && startTime.isAfter(endTime)) {
throw new InternalServerException(EvilErrorCode.INTERNAL_PRECONDITION_ERROR, "开始时间不能晚于结束时间");
}
var nw = loadAllFiles(startTime, endTime);
return nw != null ? new LogFileNameList(nw) : new LogFileNameList();
}
/**
* 获取日志文件的尾部内容, 支持指定行数;
*/
public List<String> fileTail(int lines) {
var mp = loadAllFiles(null, null);
if (mp == null) return new ArrayList<>();
List<String> res = new ArrayList<>();
List<String> data = loadContentByDate("today", lines, mp);
if (data != null) res.addAll(data);
if (res.size() >= lines) return res;
mp.remove("today");
// 历史日志
while (!mp.isEmpty() && res.size() < lines) {
String mxDate = "";
for (var date : mp.keySet()) {
if (mxDate.isBlank() || mxDate.compareTo(date) <= 0) {
mxDate = date;
}
}
data = loadContentByDate(mxDate, lines - res.size(), mp);
if (data != null) res.addAll(data);
mp.remove(mxDate);
}
return res;
}
/**
* 将日志打包压缩
*/
public void writeLogsToZip(LogFileNameList logFileNameList, OutputStream outputStream) {
Path logsBasePath = Paths.get(logsFileBaseDir).toAbsolutePath().normalize();
Set<String> zipEntryNames = new HashSet<>();
try (ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(outputStream, 8192), StandardCharsets.UTF_8)) {
for (var entry : logFileNameList.getLogFilesByDate().entrySet()) {
String dateKey = normalizeDateKey(entry.getKey());
List<String> fileNames = entry.getValue();
if (fileNames == null || fileNames.isEmpty()) {
continue;
}
for (String rawFileName : fileNames) {
String fileName = normalizeFileName(rawFileName);
Path targetFilePath = "today".equals(dateKey)
? logsBasePath.resolve(fileName)
: logsBasePath.resolve(dateKey).resolve(fileName);
targetFilePath = targetFilePath.toAbsolutePath().normalize();
if (!targetFilePath.startsWith(logsBasePath) || !Files.isRegularFile(targetFilePath)) {
log.warn("尝试访问非法日志文件: {}", targetFilePath);
throw new EvilBaseException(EvilErrorCode.BAD_REQUEST, "日志文件不存在或路径非法: " + fileName);
}
String zipEntryName = dateKey + "/" + fileName;
if (!zipEntryNames.add(zipEntryName)) {
continue;
}
zos.putNextEntry(new ZipEntry(zipEntryName));
Files.copy(targetFilePath, zos);
zos.closeEntry();
}
}
zos.finish();
} catch (IOException e) {
throw new InternalServerException(EvilErrorCode.SERVER_FILE_IO_ERROR, "打包日志压缩包失败");
}
}
/**
* 加载范围内所有的日志名称
*/
private Map<String, List<String>> loadAllFiles(LocalDate startTime, LocalDate endTime) {
File[] files = new File(logsFileBaseDir).listFiles();
if (files == null || files.length == 0) {
return null;
}
LocalDate nowDate = LocalDate.now();
Map<String, List<String>> mp = new HashMap<>();
for (File file : files) {
List<String> nw;
if (file.isFile()) {
if (endTime != null && endTime.isBefore(nowDate)) continue;
// 代表当天的日志
nw = mp.containsKey("today") ? mp.get("today") : new ArrayList<>();
nw.add(file.getName());
mp.put("today", nw);
} else {
LocalDate nwDate = LocalDate.parse(file.getName(), formatter);
if (startTime != null && nwDate.isBefore(startTime)) {
continue;
}
if (endTime != null && nwDate.isAfter(endTime)) {
continue;
}
// 递归一层遍历日志;
nw = new ArrayList<>();
for (File nxt : Objects.requireNonNull(file.listFiles())) {
if (nxt.isFile()) {
nw.add(nxt.getName());
}
}
mp.put(file.getName(), nw);
}
}
log.info("成功加载所有日志文件名");
return mp;
}
/**
* 添加email
*/
public void addEmails(List<String> emails) {
mailConfig.addEmail(emails);
}
/**
* 删除email
*/
public void removeEmail(String email) {
mailConfig.removeEmail(email);
}
/**
* 加载`dataName`这一天的指定行数的日志;
*/
private List<String> loadContentByDate(String dateName, int lines, Map<String, List<String>> mp) {
if (!mp.containsKey(dateName)) return null;
List<String> todayList = mp.get(dateName).stream().filter(name -> name.startsWith(infoLogsFileNamePrefix)).sorted().toList().reversed(), res = new ArrayList<>();
for (var fileName : todayList) {
String filePath;
if (dateName.equals("today")) {
filePath = String.format("%s/%s", logsFileBaseDir, fileName);
} else {
filePath = String.format("%s/%s/%s", logsFileBaseDir, dateName, fileName);
}
List<String> fileTailList;
try {
fileTailList = Files.readAllLines(Paths.get(filePath), StandardCharsets.UTF_8);
} catch (IOException e) {
throw new InternalServerException(EvilErrorCode.SERVER_FILE_IO_ERROR, "服务器文件系统异常");
}
if (res.size() + fileTailList.size() <= lines) {
res.addAll(fileTailList);
} else {
for (int i = 0; i < fileTailList.size() && res.size() < lines; i++) {
res.add(fileTailList.get(i));
}
}
}
log.info("成功加载日期{}的日志内容, 行数:{}", dateName, res.size());
return res;
}
private String normalizeDateKey(String dateKey) {
if (dateKey == null || dateKey.isBlank()) {
throw new EvilBaseException(EvilErrorCode.BAD_REQUEST, "日期目录不能为空");
}
String normalizedDate = dateKey.trim();
if ("today".equals(normalizedDate)) {
return normalizedDate;
}
try {
LocalDate.parse(normalizedDate, formatter);
return normalizedDate;
} catch (Exception e) {
throw new EvilBaseException(EvilErrorCode.BAD_REQUEST, "非法日期目录: " + normalizedDate);
}
}
private String normalizeFileName(String fileName) {
if (fileName == null || fileName.isBlank()) {
throw new EvilBaseException(EvilErrorCode.BAD_REQUEST, "日志文件名不能为空");
}
String normalizedFileName = fileName.trim();
if (normalizedFileName.contains("..") || normalizedFileName.contains("/") || normalizedFileName.contains("\\")) {
throw new EvilBaseException(EvilErrorCode.BAD_REQUEST, "非法日志文件名: " + normalizedFileName);
}
if (!normalizedFileName.matches("[A-Za-z0-9._-]+\\.log")) {
throw new EvilBaseException(EvilErrorCode.BAD_REQUEST, "仅允许下载 .log 文件: " + normalizedFileName);
}
return normalizedFileName;
}
}

View File

@ -0,0 +1,44 @@
package cc.evil.logtest1.service.log;
import cc.evil.logtest1.exception.EvilBaseException;
import cc.evil.logtest1.exception.EvilErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class LogPushService {
// service
private final MailPushService mailPushService;
public void push(EvilBaseException exception, String ruleKey, long occurrenceCount, boolean immediate, String reason, StackTraceElement[] stackTrace) {
String msgHeader = String.format("[LogTest1 - logs push] ruleKey=%s", ruleKey);
String msgBody = String.format("""
Push immediate: %s
Rule key: %s
Occurrence count: %d
Reason: %s
Exception type: %s
Business code: %s
Message: %s
Custom message: %s
Stack trace: %s
""", immediate, ruleKey, occurrenceCount, reason, exception.getClass().getName(), exception.getErrorCode().getBusinessCode(), exception.getMessage(), exception.getCustomMsg(), stackTraceToString(stackTrace));
mailPushService.pushToAll(msgHeader, msgBody);
}
private Object stackTraceToString(StackTraceElement[] stackTrace) {
if (stackTrace == null) {
return "null";
}
StringBuilder sb = new StringBuilder();
for (StackTraceElement element : stackTrace) {
sb.append(element.toString()).append("\n");
}
return sb.toString();
}
}

View File

@ -0,0 +1,169 @@
package cc.evil.logtest1.service.log;
import cc.evil.logtest1.exception.EvilBaseException;
import cc.evil.logtest1.exception.InternalServerException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@Slf4j
@Service
@RequiredArgsConstructor
public class LogService {
private static final long DEFAULT_WINDOW_SIZE = 60_000L;
private static final long DEFAULT_MAX_WINDOW_SIZE = 5L;
private static final long DEFAULT_WINDOW_RELEASE_TIME = 10 * 60_000L;
private static final String BASE_PACKAGE = "cc.evil.logtest1.";
// Service
private final LogPushService logPushService;
// 多线程安全键值对
private final ConcurrentMap<String, FailureWindow> failureWindows = new ConcurrentHashMap<>();
/**
* 默认推送策略:
* 1. 普通异常只有到达一定的阈值, 才会出发推送日志的条件, 以避免过多的日志推送
* 2. 被标记了严重的异常会立即推送日志, 不需要等待窗口
* 3. 当同一个接口大面积失败的时候, 也会立即推送日志, 不需要等待窗口
*/
@Async("traceableExecutor")
public void pushLogWithDefaultPolicy(EvilBaseException exception) {
if (exception == null) {
return;
}
if (shouldPushNow(exception)) {
// 立即推送
log.info("Push now because setting in exception pushed log for exception: {}, ruleKey: {}.", exception.getClass().getName(), buildRuleKey(exception));
logPushService.push(exception, buildRuleKey(exception), 1L, true, "pushLogNow=true", exception.getStackTrace());
return;
}
evaluateThresholdPolicy(exception);
}
@Async("traceableExecutor")
public void pushLogWithDefaultPolicy(Exception exception) {
if (exception == null) {
return;
}
if (exception instanceof EvilBaseException evilBaseException) {
pushLogWithDefaultPolicy(evilBaseException);
return;
}
// 意料之外的异常立即推送, 并且跟上栈信息, 以便后续排查
InternalServerException newException = new InternalServerException(cc.evil.logtest1.exception.EvilErrorCode.INTERNAL_SERVER_ERROR, exception.getMessage());
newException.initCause(exception);
newException.pushLogNow = true;
newException.setStackTrace(exception.getStackTrace());
log.info("Push now for unexpected error pushed log for exception: {}, ruleKey: {}.", exception.getClass().getName(), buildRuleKey(newException));
logPushService.push(newException, buildRuleKey(newException), 1L, true, "unexpected exception", exception.getStackTrace());
}
private void evaluateThresholdPolicy(EvilBaseException exception) {
long currentTime = System.currentTimeMillis();
String ruleKey = buildRuleKey(exception);
FailureWindow window = failureWindows.computeIfAbsent(ruleKey, key -> new FailureWindow(currentTime));
long cnt = window.push_back(currentTime, DEFAULT_WINDOW_SIZE);
if (cnt >= DEFAULT_MAX_WINDOW_SIZE) {
log.info("Push because threshold reached for exception: {}, ruleKey: {}, cnt: {}.", exception.getClass().getName(), ruleKey, cnt);
logPushService.push(exception, ruleKey, cnt, false, "threshold reached", null);
window.clear();
return;
}
}
// 定时任务, 定时清理一部分的队列, 防止内存溢出
@Scheduled(fixedDelayString = "${log.policy.window-cleanup-delay-ms:60000}")
public void cleanupIdleWindows() {
long minTime = System.currentTimeMillis() - DEFAULT_WINDOW_RELEASE_TIME;
failureWindows.forEach((ruleKey, window) -> {
window.release(minTime);
if (window.shouldRelease(minTime)) {
log.info("Remove idle window for ruleKey: {}, because cleanup schedule.", ruleKey);
failureWindows.remove(ruleKey, window);
}
});
}
private boolean shouldPushNow(EvilBaseException exception) {
return exception.isPushLogNow();
}
private String buildRuleKey(EvilBaseException exception) {
return extractApplicationOrigin(exception);
}
// 提取出问题的类和方法, 作为当前日志的来源, 并且只关注我们自己应用的包路径, 避免被第三方库的异常污染
private String extractApplicationOrigin(Throwable throwable) {
StackTraceElement[] stackTrace = throwable.getStackTrace();
for (StackTraceElement element : stackTrace) {
if (element.getClassName().startsWith(BASE_PACKAGE)) {
return String.format("%s#%s", element.getClassName(), element.getMethodName());
}
}
if (stackTrace.length == 0) {
return throwable.getClass().getSimpleName();
}
StackTraceElement fallback = stackTrace[0];
return String.format("%s#%s", fallback.getClassName(), fallback.getMethodName());
}
private static final class FailureWindow {
private final ConcurrentLinkedDeque<Long> dq = new ConcurrentLinkedDeque<>();
private final AtomicInteger cnt = new AtomicInteger();
private final AtomicLong lstTime = new AtomicLong();
private FailureWindow(long windowStartMillis) {
lstTime.set(windowStartMillis);
}
private long push_back(long currentTime, long windowSize) {
lstTime.set(currentTime);
release(currentTime - windowSize);
dq.offerLast(currentTime);
return cnt.incrementAndGet();
}
// 清理掉过期的记录
private void release(long minTime) {
// 保证操作原子性, 避免在多线程环境下出现计数不准确的情况
while (true) {
Long time = dq.pollFirst();
if (time == null || time >= minTime) {
if (time != null) dq.addFirst(time);
break;
}
cnt.decrementAndGet();
}
}
private void clear() {
dq.clear();
cnt.set(0);
}
private boolean shouldRelease(long minTime) {
return dq.isEmpty() || lstTime.get() < minTime;
}
}
}

View File

@ -0,0 +1,49 @@
package cc.evil.logtest1.service.log;
import cc.evil.logtest1.config.MailConfig;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class MailPushService {
// config
private final MailConfig mailConfig;
// mail sender
private final JavaMailSender mailSender;
public void pushToAll(String header, String msg) {
if (mailConfig.getToEmailsSet().isEmpty()) {
log.info("No email configured for log pushing, skipping email push.");
return;
}
SimpleMailMessage emailMessage = new SimpleMailMessage();
emailMessage.setFrom(mailConfig.getFromEmail());
emailMessage.setSubject(header);
emailMessage.setText(msg);
for (String toEmail : mailConfig.getToEmailsSet()) {
emailMessage.setTo(toEmail);
try {
mailSender.send(emailMessage);
log.info("Successfully sent log email to {}.", toEmail);
} catch (Exception e) {
log.warn("Failed to send log email to {}.", toEmail, e);
}
}
}
}

View File

@ -0,0 +1,69 @@
package cc.evil.logtest1.utils;
import cc.evil.logtest1.constants.LogConstants;
import org.slf4j.MDC;
import java.util.UUID;
public class TraceContextUtil {
/**
* 生成 TraceId32位无横线的UUID
*/
public static String generateTraceId() {
return UUID.randomUUID().toString().replace("-", "");
}
/**
* 生成 SpanId
*/
public static String generateSpanId() {
return UUID.randomUUID().toString().replace("-", "").substring(0, 16);
}
/**
* 设置 TraceId MDC
*/
public static void setTraceId(String traceId) {
MDC.put(LogConstants.TRACE_ID_MDC_KEY, traceId);
}
/**
* 设置 SpanId MDC
*/
public static void setSpanId(String spanId) {
MDC.put(LogConstants.SPAN_ID_MDC_KEY, spanId);
}
/**
* MDC 获取 TraceId
*/
public static String getTraceId() {
return MDC.get(LogConstants.TRACE_ID_MDC_KEY);
}
/**
* MDC 获取 SpanId
*/
public static String getSpanId() {
return MDC.get(LogConstants.SPAN_ID_MDC_KEY);
}
/**
* 初始化如果没有则生成
*/
public static void init(String traceId) {
if (traceId == null || traceId.isBlank()) {
traceId = generateTraceId();
}
setTraceId(traceId);
setSpanId(generateSpanId());
}
/**
* 清理防止内存泄漏
*/
public static void clear() {
MDC.clear();
}
}

View File

@ -0,0 +1,16 @@
spring:
application:
name: LogTest1
profiles:
active: dev
log:
push:
mail:
username: ${MAIL_USERNAME:}
password: ${MAIL_PASSWORD:}
host: smtp.qq.com
port: 587
protocol: smtp
from-email: ${MAIL_FROM_EMAIL:}
to-emails: ${MAIL_TO_EMAILS:}

View File

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 1. 定义变量-->
<property name="LOG_PATH" value="logs/" /> <!-- 日志文件根目录 -->
<property name="LOG_NAME" value="app" /> <!-- 日志基础名称 -->
<!-- =================== 异步通用配置 =================== -->
<!-- 常规日志, 输出INFO及以上 -->
<appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_NAME}-info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/${LOG_NAME}-info.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<!-- 最多保留7天 -->
<maxHistory>7</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>
{"time":"%d{yyyy-MM-dd HH:mm:ss.SSS}","level":"%level","traceId":"%X{traceId}","uid":"%X{uid}","thread":"%thread","logger":"%logger","msg":%msg,"exception":"%ex"}%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<!-- 错误日志, 输出WARN和ERROR -->
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_NAME}-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/${LOG_NAME}-error.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<!-- 最多保留15天 -->
<maxHistory>15</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>
{"time":"%d{yyyy-MM-dd HH:mm:ss.SSS}","level":"%level","traceId":"%X{traceId}","uid":"%X{uid}","thread":"%thread","logger":"%logger","msg":%msg,"exception":"%ex"}%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender>
<!-- 审计日志 -->
<appender name="FILE_AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/${LOG_NAME}-audit.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/${LOG_NAME}-audit.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<!-- 最多保留30天 -->
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>
{"time":"%d{yyyy-MM-dd HH:mm:ss.SSS}","level":"%level","traceId":"%X{traceId}","uid":"%X{uid}","thread":"%thread","logger":"%logger","msg":%msg,"exception":"%ex"}%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 彩色输出到控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %highlight(%-5level) %logger{50} - %msg%n
</pattern>
</encoder>
</appender>
<!-- =================== 异步包装 =================== -->
<appender name="ASYNC_INFO" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>1024</queueSize>
<!-- 队列满时丢弃 TRACE/DEBUG/INFO保留 WARN和ERROR -->
<discardingThreshold>20</discardingThreshold>
<neverBlock>true</neverBlock>
<appender-ref ref="FILE_INFO"/>
</appender>
<appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<!-- 错误日志绝对不能丢失, 因此不允许丢弃并关闭 neverBlock 让其阻塞等待 -->
<discardingThreshold>0</discardingThreshold>
<neverBlock>false</neverBlock>
<appender-ref ref="FILE_ERROR"/>
</appender>
<appender name="ASYNC_AUDIT" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>256</queueSize>
<discardingThreshold>0</discardingThreshold>
<neverBlock>false</neverBlock>
<appender-ref ref="FILE_AUDIT"/>
</appender>
<!-- =================== 日志路由 =================== -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_INFO" />
<appender-ref ref="ASYNC_ERROR" />
</root>
<!-- 防止审计日志穿透到root再次输出 -->
<logger name="AuditLogger" level="INFO" additivity="false">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_AUDIT" />
</logger>
</configuration>

View File

@ -0,0 +1,25 @@
package cc.evil.logtest1;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
@SpringBootTest
class LogTest1ApplicationTests {
@Autowired
private JavaMailSender mailSender;
@Test
void testMail() {
SimpleMailMessage msg = new SimpleMailMessage();
msg.setFrom("2207086349@qq.com");
msg.setTo("2207086349@qq.com");
// msg.setTo("3515694291@qq.com");
msg.setSubject("主题:简单邮件");
msg.setText("测试邮件内容");
mailSender.send(msg);
}
}