@llryiop/avatar-boot-cli 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/exam-question-generate-api.md +163 -0
- package/package.json +1 -1
- package/src/prompts.js +3 -3
- package/src/transform.js +1 -1
- package/templates/.claude/skills/avatar-boot-starter-feign/README.md +243 -0
- package/templates/.claude/skills/avatar-boot-starter-feign/SKILL.md +47 -219
- package/templates/.claude/skills/avatar-boot-starter-feign/references//345/212/237/350/203/275/350/257/246/350/247/243.md +65 -0
- package/templates/.claude/skills/avatar-boot-starter-feign/references//345/277/253/351/200/237/346/216/245/345/205/245/346/214/207/345/215/227.md +75 -0
- package/templates/.claude/skills/avatar-boot-starter-feign/references//351/205/215/347/275/256/345/217/202/350/200/203.md +70 -0
- package/templates/.claude/skills/avatar-boot-starter-job/README.md +437 -0
- package/templates/.claude/skills/avatar-boot-starter-job/SKILL.md +35 -414
- package/templates/.claude/skills/avatar-boot-starter-job/references//345/270/270/350/247/201/351/227/256/351/242/230.md +55 -0
- package/templates/.claude/skills/avatar-boot-starter-job/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +124 -0
- package/templates/.claude/skills/avatar-boot-starter-job/references//347/233/221/346/216/247/346/214/207/346/240/207.md +72 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/README.md +580 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/SKILL.md +36 -560
- package/templates/.claude/skills/avatar-boot-starter-kafka/references//346/234/200/344/275/263/345/256/236/350/267/265.md +43 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/references//346/240/270/345/277/203/345/212/237/350/203/275.md +117 -0
- package/templates/.claude/skills/avatar-boot-starter-kafka/references//351/205/215/347/275/256/345/217/202/350/200/203.md +54 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/README.md +572 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/SKILL.md +40 -550
- package/templates/.claude/skills/avatar-boot-starter-mysql/references//345/256/236/344/275/223/344/270/216/345/212/237/350/203/275.md +96 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/346/225/260/346/215/256/346/272/220.md +91 -0
- package/templates/.claude/skills/avatar-boot-starter-mysql/references//351/253/230/347/272/247/347/211/271/346/200/247/344/270/216/351/205/215/347/275/256.md +59 -0
- package/templates/.claude/skills/avatar-boot-starter-nacos/README.md +901 -0
- package/templates/.claude/skills/avatar-boot-starter-nacos/SKILL.md +40 -879
- package/templates/.claude/skills/avatar-boot-starter-nacos/references//345/212/237/350/203/275/344/275/277/347/224/250.md +134 -0
- package/templates/.claude/skills/avatar-boot-starter-nacos/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +96 -0
- package/templates/.claude/skills/avatar-boot-starter-nacos/references//346/225/205/351/232/234/346/216/222/346/237/245.md +64 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/README.md +594 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/SKILL.md +52 -570
- package/templates/.claude/skills/avatar-boot-starter-oss/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +77 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/references//346/240/270/345/277/203/345/212/237/350/203/275.md +94 -0
- package/templates/.claude/skills/avatar-boot-starter-oss/references//350/247/204/350/214/203/344/270/216/346/263/250/346/204/217/344/272/213/351/241/271.md +61 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/README.md +586 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/SKILL.md +42 -566
- package/templates/.claude/skills/avatar-boot-starter-redis/references//345/277/253/351/200/237/346/216/245/345/205/245/344/270/216/351/205/215/347/275/256.md +78 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/references//346/225/260/346/215/256/346/223/215/344/275/234.md +111 -0
- package/templates/.claude/skills/avatar-boot-starter-redis/references//351/253/230/347/272/247/345/212/237/350/203/275.md +90 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/README.md +662 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/SKILL.md +48 -640
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//346/240/270/345/277/203/345/212/237/350/203/275.md +101 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//351/205/215/347/275/256/344/270/216/346/263/250/346/204/217/344/272/213/351/241/271.md +44 -0
- package/templates/.claude/skills/avatar-boot-starter-rocketmq/references//351/253/230/347/272/247/347/211/271/346/200/247.md +71 -0
- package/templates/.claude/skills/avatar-boot-starter-web/README.md +1007 -0
- package/templates/.claude/skills/avatar-boot-starter-web/SKILL.md +150 -1003
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-LogInfo/346/263/250/350/247/243.md +75 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/345/205/250/345/261/200/345/274/202/345/270/270/345/244/204/347/220/206.md +90 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/346/214/207/346/240/207/347/233/221/346/216/247.md +74 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/346/227/245/345/277/227/344/275/223/347/263/273.md +73 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/212/237/350/203/275-/350/257/267/346/261/202/344/270/212/344/270/213/346/226/207.md +77 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//345/277/253/351/200/237/346/216/245/345/205/245/346/214/207/345/215/227.md +52 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//346/263/250/346/204/217/344/272/213/351/241/271.md +68 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//350/207/252/345/256/232/344/271/211/346/211/251/345/261/225/346/214/207/345/215/227.md +107 -0
- package/templates/.claude/skills/avatar-boot-starter-web/references//351/205/215/347/275/256/345/217/202/350/200/203.md +107 -0
- package/templates/.claude/skills/crud-generator/SKILL.md +133 -64
- package/templates/.claude/skills/database-design/README.md +207 -0
- package/templates/.claude/skills/database-design/SKILL.md +469 -82
- package/templates/.claude/skills/database-design/references//345/221/275/345/220/215/350/247/204/350/214/203.md +232 -0
- package/templates/.claude/skills/database-design/references//345/255/227/346/256/265/347/261/273/345/236/213/350/247/204/350/214/203.md +400 -0
- package/templates/.claude/skills/database-design/references//347/264/242/345/274/225/350/247/204/350/214/203.md +506 -0
- package/templates/README.md +65 -100
- package/templates/avatar-scaffold-api/pom.xml +0 -5
- package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/api/LoginFeignClient.java +2 -0
- package/templates/avatar-scaffold-api/src/main/java/com/iflytek/avatar/login/exception/LoginErrorCode.java +25 -0
- package/templates/avatar-scaffold-service/pom.xml +25 -87
- package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/feign/DemoFeign.java +4 -1
- package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/repository/UserLoginRepository.java +10 -0
- package/templates/avatar-scaffold-service/src/main/java/com/iflytek/avatar/login/repository/mapper/UserLoginMapper.java +4 -1
- package/templates/avatar-scaffold-service/src/main/resources/application-dev.yaml +3 -5
- package/templates/avatar-scaffold-service/src/main/resources/application-local.yaml +21 -21
- package/templates/pom.xml +9 -18
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# 试题生成 API 接口协议
|
|
2
|
+
|
|
3
|
+
## 1. 按要求生成试题
|
|
4
|
+
|
|
5
|
+
**POST** `/api/exam/questions/generate-by-requirement`
|
|
6
|
+
|
|
7
|
+
**Content-Type:** `application/json`
|
|
8
|
+
|
|
9
|
+
### 请求参数
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"examName": "考题名称",
|
|
14
|
+
"requirement": "请用自然语言描述考题要求,不超过1000字",
|
|
15
|
+
"questionType": "SINGLE_CHOICE",
|
|
16
|
+
"count": 5,
|
|
17
|
+
"example": "可提供示例作为参考(选填)"
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
22
|
+
|------|------|------|------|
|
|
23
|
+
| examName | String | 是 | 考题名称 |
|
|
24
|
+
| requirement | String | 是 | 考题要求,最大1000字 |
|
|
25
|
+
| questionType | String(enum) | 是 | 出题类型,见枚举定义 |
|
|
26
|
+
| count | Integer | 是 | 题量,>=1 |
|
|
27
|
+
| example | String | 否 | 示例参考 |
|
|
28
|
+
|
|
29
|
+
### 响应
|
|
30
|
+
|
|
31
|
+
见 [统一响应格式](#4-统一响应格式)
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. 上传文件生成试题
|
|
36
|
+
|
|
37
|
+
**POST** `/api/exam/questions/generate-by-file`
|
|
38
|
+
|
|
39
|
+
**Content-Type:** `multipart/form-data`
|
|
40
|
+
|
|
41
|
+
### 请求参数
|
|
42
|
+
|
|
43
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
44
|
+
|------|------|------|------|
|
|
45
|
+
| examName | String | 是 | 考题名称 |
|
|
46
|
+
| file | MultipartFile | 是 | 上传文件,支持 doc/docx/ppt/pptx/md/txt/pdf,单文件不超过50MB,总量不超过100MB |
|
|
47
|
+
| questionType | String(enum) | 是 | 出题类型,见枚举定义 |
|
|
48
|
+
| count | Integer | 是 | 题量,>=1 |
|
|
49
|
+
| example | String | 否 | 示例参考 |
|
|
50
|
+
|
|
51
|
+
### 响应
|
|
52
|
+
|
|
53
|
+
见 [统一响应格式](#4-统一响应格式)
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 3. 枚举定义
|
|
58
|
+
|
|
59
|
+
### QuestionTypeEnum 出题类型
|
|
60
|
+
|
|
61
|
+
| 枚举值 | 说明 |
|
|
62
|
+
|--------|------|
|
|
63
|
+
| SINGLE_CHOICE | 单选题 |
|
|
64
|
+
| MULTIPLE_CHOICE | 多选题 |
|
|
65
|
+
| FILL_BLANK | 填空题 |
|
|
66
|
+
| TRUE_FALSE | 判断题 |
|
|
67
|
+
| SHORT_ANSWER | 简答题 |
|
|
68
|
+
|
|
69
|
+
> 注意:每次请求只能指定一种出题类型,支持生成单个或多个题目。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 4. 统一响应格式
|
|
74
|
+
|
|
75
|
+
所有接口统一使用 `Result<ExamGenerateResponse>` 包装。
|
|
76
|
+
|
|
77
|
+
### 响应结构
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"code": 200,
|
|
82
|
+
"message": "success",
|
|
83
|
+
"data": {
|
|
84
|
+
"examName": "考题名称",
|
|
85
|
+
"questionType": "SINGLE_CHOICE",
|
|
86
|
+
"questions": [
|
|
87
|
+
{
|
|
88
|
+
"index": 1,
|
|
89
|
+
"stem": "题干内容",
|
|
90
|
+
"options": [
|
|
91
|
+
{ "key": "A", "value": "选项A" },
|
|
92
|
+
{ "key": "B", "value": "选项B" },
|
|
93
|
+
{ "key": "C", "value": "选项C" },
|
|
94
|
+
{ "key": "D", "value": "选项D" }
|
|
95
|
+
],
|
|
96
|
+
"answer": "A",
|
|
97
|
+
"analysis": "解析说明"
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 响应字段说明
|
|
105
|
+
|
|
106
|
+
#### ExamGenerateResponse
|
|
107
|
+
|
|
108
|
+
| 字段 | 类型 | 说明 |
|
|
109
|
+
|------|------|------|
|
|
110
|
+
| examName | String | 考题名称 |
|
|
111
|
+
| questionType | String(enum) | 出题类型 |
|
|
112
|
+
| questions | List\<QuestionItem\> | 题目列表 |
|
|
113
|
+
|
|
114
|
+
#### QuestionItem
|
|
115
|
+
|
|
116
|
+
| 字段 | 类型 | 说明 |
|
|
117
|
+
|------|------|------|
|
|
118
|
+
| index | Integer | 题目序号,从1开始 |
|
|
119
|
+
| stem | String | 题干内容 |
|
|
120
|
+
| options | List\<Option\> | 选项列表,仅单选题/多选题有值,其他题型为 null |
|
|
121
|
+
| answer | String | 正确答案 |
|
|
122
|
+
| analysis | String | 答案解析 |
|
|
123
|
+
|
|
124
|
+
#### Option
|
|
125
|
+
|
|
126
|
+
| 字段 | 类型 | 说明 |
|
|
127
|
+
|------|------|------|
|
|
128
|
+
| key | String | 选项标识,如 A、B、C、D |
|
|
129
|
+
| value | String | 选项内容 |
|
|
130
|
+
|
|
131
|
+
### 各题型 answer 格式差异
|
|
132
|
+
|
|
133
|
+
| 题型 | options | answer 格式 | 示例 |
|
|
134
|
+
|------|---------|-------------|------|
|
|
135
|
+
| 单选题(SINGLE_CHOICE) | A/B/C/D 选项列表 | 单个字母 | `"A"` |
|
|
136
|
+
| 多选题(MULTIPLE_CHOICE) | A/B/C/D/E 选项列表 | 多个字母,逗号分隔 | `"A,B,D"` |
|
|
137
|
+
| 填空题(FILL_BLANK) | null | 填空答案,多空用 `\|\|` 分隔 | `"答案1\|\|答案2"` |
|
|
138
|
+
| 判断题(TRUE_FALSE) | null | TRUE 或 FALSE | `"TRUE"` |
|
|
139
|
+
| 简答题(SHORT_ANSWER) | null | 参考答案文本 | `"参考答案内容..."` |
|
|
140
|
+
|
|
141
|
+
> 填空题题干中使用 `___` 表示填空位置。
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 5. 错误码
|
|
146
|
+
|
|
147
|
+
| code | message | 说明 |
|
|
148
|
+
|------|---------|------|
|
|
149
|
+
| 200 | success | 成功 |
|
|
150
|
+
| 400 | 参数校验失败 | 必填字段缺失或格式错误 |
|
|
151
|
+
| 413 | 文件大小超出限制 | 单文件超过50MB或总量超过100MB |
|
|
152
|
+
| 415 | 不支持的文件格式 | 文件类型不在支持列表中 |
|
|
153
|
+
| 500 | 生成失败 | 服务端异常 |
|
|
154
|
+
|
|
155
|
+
### 错误响应示例
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"code": 400,
|
|
160
|
+
"message": "考题名称不能为空",
|
|
161
|
+
"data": null
|
|
162
|
+
}
|
|
163
|
+
```
|
package/package.json
CHANGED
package/src/prompts.js
CHANGED
|
@@ -32,7 +32,7 @@ export async function collectConfig(initialName) {
|
|
|
32
32
|
type: 'input',
|
|
33
33
|
name: 'avatarBootVersion',
|
|
34
34
|
message: 'Avatar Boot 版本:',
|
|
35
|
-
default: '1.0.
|
|
35
|
+
default: '1.0.1',
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
type: 'checkbox',
|
|
@@ -50,14 +50,14 @@ export async function collectConfig(initialName) {
|
|
|
50
50
|
type: 'input',
|
|
51
51
|
name: 'nacosAddr',
|
|
52
52
|
message: 'Nacos 地址:',
|
|
53
|
-
default: '
|
|
53
|
+
default: '172.31.250.98:8848',
|
|
54
54
|
when: (answers) => answers.starters.includes('nacos'),
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
type: 'input',
|
|
58
58
|
name: 'dbUrl',
|
|
59
59
|
message: '数据库地址 (host:port/dbname):',
|
|
60
|
-
default: '
|
|
60
|
+
default: 'mysql1_23306_test.xfyousheng.com:23306/avatar_zhizuo',
|
|
61
61
|
when: (answers) => answers.starters.includes('mysql'),
|
|
62
62
|
},
|
|
63
63
|
{
|
package/src/transform.js
CHANGED
|
@@ -14,7 +14,7 @@ export function transformProject(projectDir, config) {
|
|
|
14
14
|
const {
|
|
15
15
|
projectName,
|
|
16
16
|
groupId = DEFAULT_GROUP_ID,
|
|
17
|
-
avatarBootVersion = '1.0.
|
|
17
|
+
avatarBootVersion = '1.0.1',
|
|
18
18
|
starters = ['web', 'nacos'],
|
|
19
19
|
includeExample = true,
|
|
20
20
|
nacosAddr = '127.0.0.1:8848',
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: avatar-boot-starter-feign
|
|
3
|
+
description: 当使用 avatar-boot-starter-feign 模块时使用此技能 - 为 Spring Boot 3.5.3 应用提供全面的 openfeign开发,包括自动配置、TraceId 传播、日志配置、指标集成。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Avatar Boot 的 OpenFeign 客户端集成模块,提供开箱即用的 openfeign功能,包含自动日志记录和性能指标监控。
|
|
7
|
+
|
|
8
|
+
## 功能特性
|
|
9
|
+
|
|
10
|
+
- ✅ **自动配置** - 基于 Spring Boot 自动配置机制,零配置即可使用
|
|
11
|
+
- ✅ **请求日志** - 自动记录 Feign 客户端的请求参数和响应数据
|
|
12
|
+
- ✅ **TraceId 传播** - 自动传播分布式追踪 ID 到下游服务
|
|
13
|
+
- ✅ **性能指标** - 集成 Micrometer,记录调用次数、执行时间、成功/失败率
|
|
14
|
+
- ✅ **慢请求检测** - 自动检测并警告超过阈值的慢请求
|
|
15
|
+
- ✅ **灵活配置** - 支持细粒度的功能开关和参数配置
|
|
16
|
+
|
|
17
|
+
## 快速开始
|
|
18
|
+
|
|
19
|
+
### 1. 添加依赖
|
|
20
|
+
|
|
21
|
+
在项目的 `pom.xml` 中添加依赖:
|
|
22
|
+
|
|
23
|
+
```xml
|
|
24
|
+
<dependency>
|
|
25
|
+
<groupId>com.iflytek.avatar.boot</groupId>
|
|
26
|
+
<artifactId>avatar-boot-starter-feign</artifactId>
|
|
27
|
+
</dependency>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. 定义 Feign 客户端
|
|
31
|
+
|
|
32
|
+
在 Spring Boot 应用主类上添加 `@EnableFeignClients` 注解:
|
|
33
|
+
|
|
34
|
+
```java
|
|
35
|
+
@SpringBootApplication
|
|
36
|
+
@EnableFeignClients
|
|
37
|
+
public class Application {
|
|
38
|
+
public static void main(String[] args) {
|
|
39
|
+
SpringApplication.run(Application.class, args);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
然后定义 Feign 客户端接口:
|
|
45
|
+
|
|
46
|
+
```java
|
|
47
|
+
import com.iflytek.avatar.boot.config.FeignLoggingConfiguration;
|
|
48
|
+
|
|
49
|
+
// 使用 FeignLoggingConfiguration 启用详细日志记录
|
|
50
|
+
@FeignClient(name = "user-service", url = "http://localhost:8080",
|
|
51
|
+
configuration = FeignLoggingConfiguration.class)
|
|
52
|
+
public interface UserServiceClient {
|
|
53
|
+
|
|
54
|
+
@GetMapping("/api/users/{id}")
|
|
55
|
+
User getUserById(@PathVariable("id") Long id);
|
|
56
|
+
|
|
57
|
+
@PostMapping("/api/users")
|
|
58
|
+
User createUser(@RequestBody User user);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**重要说明:**
|
|
63
|
+
- `FeignLoggingConfiguration` 不是默认启用的,需要在 `@FeignClient` 的 `configuration` 属性中显式指定
|
|
64
|
+
- 如果不指定 `configuration`,则只会启用 TraceId 传播功能,不会打印详细日志
|
|
65
|
+
- 这样设计是为了让你可以灵活控制哪些 Feign 客户端需要详细日志
|
|
66
|
+
|
|
67
|
+
### 3. 使用 Feign 客户端
|
|
68
|
+
|
|
69
|
+
```java
|
|
70
|
+
@Service
|
|
71
|
+
@RequiredArgsConstructor
|
|
72
|
+
public class UserService {
|
|
73
|
+
|
|
74
|
+
private final UserServiceClient userServiceClient;
|
|
75
|
+
|
|
76
|
+
public User getUser(Long id) {
|
|
77
|
+
return userServiceClient.getUserById(id);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## 配置说明
|
|
83
|
+
|
|
84
|
+
### 基础配置
|
|
85
|
+
|
|
86
|
+
```yaml
|
|
87
|
+
avatar:
|
|
88
|
+
feign:
|
|
89
|
+
logging:
|
|
90
|
+
enabled: true # 启用日志拦截器(TraceId 传播)
|
|
91
|
+
request-enabled: true # 记录请求参数
|
|
92
|
+
response-enabled: true # 记录响应数据
|
|
93
|
+
print-request-details: true # 打印请求详情(URI、Method、Params)
|
|
94
|
+
print-response-details: true # 打印响应详情(包含响应体)
|
|
95
|
+
print-stack-trace: true # 打印异常堆栈信息
|
|
96
|
+
slow-request-threshold: 3000 # 慢请求阈值(毫秒)
|
|
97
|
+
max-body-length: 1000 # 最大请求体长度
|
|
98
|
+
trace-id-header: X-Trace-Id # TraceId 请求头名称
|
|
99
|
+
metrics:
|
|
100
|
+
enabled: true # 启用指标记录
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 完整配置示例
|
|
104
|
+
|
|
105
|
+
参考 `src/main/resources/application-example.yml` 查看完整配置示例。
|
|
106
|
+
|
|
107
|
+
## 功能详解
|
|
108
|
+
|
|
109
|
+
### 1. 详细日志记录
|
|
110
|
+
|
|
111
|
+
当在 FeignClient 中配置 `FeignLoggingConfiguration` 后,会自动记录详细的请求和响应信息:
|
|
112
|
+
|
|
113
|
+
**成功请求日志:**
|
|
114
|
+
```
|
|
115
|
+
Feign Request => URI: http://localhost:8080/api/users/1, Method: GET, Params: N/A
|
|
116
|
+
Feign Response => Method: getUserById, URI: http://localhost:8080/api/users/1, Params: N/A, Response: {"id":1,"name":"John"}, Status: 200, Time: 125ms
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**失败请求日志:**
|
|
120
|
+
```
|
|
121
|
+
Feign Error => Method: getUserById, URI: http://localhost:8080/api/users/1, Params: N/A, Error: Connection refused, Time: 50ms, StackTrace:
|
|
122
|
+
java.net.ConnectException: Connection refused
|
|
123
|
+
at ...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**配置控制:**
|
|
127
|
+
- `print-request-details: false` - 不打印请求详情
|
|
128
|
+
- `print-response-details: false` - 不打印响应体(只打印状态和耗时)
|
|
129
|
+
- `print-stack-trace: false` - 不打印异常堆栈信息
|
|
130
|
+
- `max-body-length: 500` - 限制请求体/响应体的最大长度
|
|
131
|
+
|
|
132
|
+
### 2. TraceId 传播
|
|
133
|
+
|
|
134
|
+
自动从 `ContextManager` 获取 TraceId 并添加到请求头,实现分布式追踪:
|
|
135
|
+
|
|
136
|
+
```java
|
|
137
|
+
// 在上游服务中设置 TraceId
|
|
138
|
+
ContextManager.get().setTraceId("trace-123");
|
|
139
|
+
|
|
140
|
+
// Feign 客户端会自动将 TraceId 添加到请求头
|
|
141
|
+
// X-Trace-Id: trace-123
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**注意:** TraceId 传播是全局启用的,不需要在 FeignClient 中配置 `FeignLoggingConfiguration`。
|
|
145
|
+
|
|
146
|
+
### 3. 性能指标
|
|
147
|
+
|
|
148
|
+
集成 Micrometer,自动记录以下指标:
|
|
149
|
+
|
|
150
|
+
- `feign.client.invocation.count` - 调用次数(标签:client, method, status)
|
|
151
|
+
- `feign.client.execution.time` - 执行时间(标签:client, method, status)
|
|
152
|
+
|
|
153
|
+
查看指标:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# 访问 Actuator 端
|
|
157
|
+
curl http://localhost:8080/actuator/metrics/feign.client.invocation.count
|
|
158
|
+
curl http://localhost:8080/actuator/metrics/feign.client.execution.time
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 4. 慢请求检测
|
|
162
|
+
|
|
163
|
+
当请求执行时间超过配置的阈值时,自动记录警告日志:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
WARN: Slow Feign Request Detected: getUserById took 3500ms (threshold: 3000ms)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## 使用场景
|
|
170
|
+
|
|
171
|
+
### 场景 1:只需要 TraceId 传播,不需要详细日志
|
|
172
|
+
|
|
173
|
+
```java
|
|
174
|
+
// 不指定 configuration,只会启用 TraceId 传播
|
|
175
|
+
@FeignClient(name = "simple-service", url = "http://localhost:8080")
|
|
176
|
+
public interface SimpleServiceClient {
|
|
177
|
+
@GetMapping("/api/data")
|
|
178
|
+
String getData();
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 场景 2:需要详细日志记录和性能监控
|
|
183
|
+
|
|
184
|
+
```java
|
|
185
|
+
// 指定 FeignLoggingConfiguration,启用详细日志
|
|
186
|
+
@FeignClient(name = "important-service", url = "http://localhost:8080",
|
|
187
|
+
configuration = FeignLoggingConfiguration.class)
|
|
188
|
+
public interface ImportantServiceClient {
|
|
189
|
+
@PostMapping("/api/process")
|
|
190
|
+
Result processData(@RequestBody Data data);
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 场景 3:自定义日志配置
|
|
195
|
+
|
|
196
|
+
```yaml
|
|
197
|
+
avatar:
|
|
198
|
+
feign:
|
|
199
|
+
logging:
|
|
200
|
+
# 只打印错误日志,不打印成功请求
|
|
201
|
+
print-request-details: false
|
|
202
|
+
print-response-details: false
|
|
203
|
+
# 但保留异常堆栈信息
|
|
204
|
+
print-stack-trace: true
|
|
205
|
+
# 降低慢请求阈值
|
|
206
|
+
slow-request-threshold: 1000
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## 高级配置
|
|
210
|
+
|
|
211
|
+
### 针对特定客户端的配置
|
|
212
|
+
|
|
213
|
+
```yaml
|
|
214
|
+
feign:
|
|
215
|
+
client:
|
|
216
|
+
config:
|
|
217
|
+
user-service:
|
|
218
|
+
connectTimeout: 3000
|
|
219
|
+
readTimeout: 5000
|
|
220
|
+
loggerLevel: FULL
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### 禁用日志或指标
|
|
224
|
+
|
|
225
|
+
```yaml
|
|
226
|
+
avatar:
|
|
227
|
+
feign:
|
|
228
|
+
logging:
|
|
229
|
+
enabled: false # 禁用日志
|
|
230
|
+
metrics:
|
|
231
|
+
enabled: false # 禁用指标
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## 依赖版本
|
|
235
|
+
|
|
236
|
+
- Spring Boot: 3.5.3
|
|
237
|
+
- Spring Cloud: 2025.0.0
|
|
238
|
+
- Java: 21
|
|
239
|
+
|
|
240
|
+
## 许可证
|
|
241
|
+
|
|
242
|
+
Copyright © 2024 iFLYTEK Co., Ltd.
|
|
243
|
+
|