create-dp-koa 1.1.2 → 1.1.4
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/package.json +1 -1
- package/template/.cursor/rules/00-backend-core.skill.md +1 -1
- package/template/.cursor/rules/01-backend-skill-router.skill.md +8 -2
- package/template/.cursor/rules/10-backend-api.skill.md +8 -0
- package/template/.cursor/rules/11-backend-controller-recipes.skill.md +12 -9
- package/template/.cursor/rules/21-backend-service.skill.md +14 -0
- package/template/.cursor/rules/30-backend-validation.skill.md +1 -1
- package/template/.cursor/rules/40-backend-error-logging.skill.md +9 -5
- package/template/.cursor/rules/50-backend-bootstrap-lifecycle.skill.md +4 -4
- package/template/.cursor/rules/60-backend-router-registration.skill.md +16 -6
- package/template/.cursor/rules/70-backend-middleware.skill.md +2 -2
- package/template/.cursor/rules/80-backend-utils-and-libs.skill.md +71 -14
- package/template/.cursor/rules/85-backend-plugins.rule.md +4 -4
- package/template/.cursor/rules/90-backend-testing.skill.md +26 -0
- package/template/.cursor/rules/README.md +2 -2
- package/template/.trae/skills/11-backend-controller-recipes.skill.md +12 -9
- package/template/.trae/skills/21-backend-service.skill.md +15 -1
- package/template/.trae/skills/40-backend-error-logging.skill.md +9 -5
- package/template/.trae/skills/80-backend-utils-and-libs.skill.md +77 -8
- package/template/.trae/skills/90-backend-testing.skill.md +26 -0
- package/template/scripts/sync-template.mjs +20 -0
- package/template/src/app.ts +1 -2
- package/template/src/{framework/plugins → plugins}/registry.ts +2 -2
- package/template/src/plugins/weboffice/http/routes.ts +1 -1
- package/template/src/plugins/weboffice/index.ts +3 -3
- package/template/src/plugins/weboffice/services/webofficeCallback.service.ts +3 -4
- package/template/src/types/ctxState.ts +9 -0
- package/template/src/utils/testDataInitializer.ts +1 -1
- package/template/tsconfig.json +6 -0
- package/template/src/annotations/decorators/ConfigManagement.ts +0 -9
- package/template/src/annotations/decorators/DistributedTracing.ts +0 -9
- package/template/src/annotations/decorators/EnterprisePerformance.ts +0 -9
- package/template/src/annotations/decorators/PerformanceMonitor.ts +0 -32
- package/template/src/annotations/decorators/SecurityAudit.ts +0 -9
- package/template/src/annotations/index.ts +0 -50
- package/template/src/annotations/processors/ConfigManagementProcessor.ts +0 -369
- package/template/src/annotations/processors/DistributedTracingProcessor.ts +0 -288
- package/template/src/annotations/processors/EnterprisePerformanceProcessor.ts +0 -189
- package/template/src/annotations/processors/PerformanceMonitorProcessor.ts +0 -101
- package/template/src/annotations/processors/SecurityAuditProcessor.ts +0 -345
- package/template/src/annotations/processors/SwaggerProcessor.ts +0 -612
- package/template/src/annotations/processors/index.ts +0 -10
- package/template/src/examples/InterceptorExampleRunner.ts +0 -284
- package/template/src/examples/ServiceInterceptorExample.ts +0 -214
- package/template/src/examples/cacheExamples.ts +0 -155
- package/template/src/framework/decorator/controller.ts +0 -311
- package/template/src/framework/decorator/processor/AnnotationDecorators.ts +0 -100
- package/template/src/framework/decorator/processor/AnnotationProcessor.ts +0 -160
- package/template/src/framework/decorator/processor/AnnotationProcessorConfig.ts +0 -45
- package/template/src/framework/decorator/processor/AnnotationRegistry.ts +0 -117
- package/template/src/framework/decorator/processor/AnnotationSystemInitializer.ts +0 -95
- package/template/src/framework/decorator/processor/ProcessorManager.ts +0 -76
- package/template/src/framework/decorator/processor/processors/CustomProcessors.ts +0 -126
- package/template/src/framework/decorator/processor/processors/DefaultProcessors.ts +0 -207
- package/template/src/framework/decorator/refactored/DecoratorFactory.ts +0 -99
- package/template/src/framework/decorator/refactored/DecoratorMetadataManager.ts +0 -125
- package/template/src/framework/decorator/refactored/DecoratorValidator.ts +0 -128
- package/template/src/framework/decorator/refactored/TypeSafeDecorators.ts +0 -139
- package/template/src/framework/decorator/refactored/index.ts +0 -98
- package/template/src/framework/decorator/swagger.ts +0 -150
- package/template/src/framework/interceptors/AdvancedServiceCallInterceptor.ts +0 -375
- package/template/src/framework/interceptors/ServiceCallInterceptor.ts +0 -348
- package/template/src/framework/interceptors/index.ts +0 -19
- package/template/src/framework/plugins/types.ts +0 -15
- package/template/src/framework/types/ServiceResult.ts +0 -151
- package/template/src/framework/types/index.ts +0 -16
- package/template/src/framework/utils/CacheManager.ts +0 -430
- package/template/src/framework/utils/CacheService.ts +0 -248
- package/template/src/framework/utils/DtoValidator.ts +0 -164
- package/template/src/framework/utils/MigrationHelper.ts +0 -179
- package/template/src/framework/utils/MigrationManager.ts +0 -256
- package/template/src/framework/utils/NewRouter.ts +0 -207
- package/template/src/framework/utils/TransactionManager.ts +0 -172
- package/template/src/framework/utils/bootstrap.ts +0 -445
- package/template/src/framework/utils/cache.ts +0 -269
- package/template/src/framework/utils/databaseConfig.ts +0 -148
- package/template/src/framework/utils/db.ts +0 -39
- package/template/src/framework/utils/dbMonitor.ts +0 -106
- package/template/src/framework/utils/function.ts +0 -61
- package/template/src/framework/utils/gracefulShutdown.ts +0 -131
- package/template/src/framework/utils/logger.ts +0 -388
- package/template/src/framework/utils/metrics.ts +0 -182
- package/template/src/framework/utils/router.ts +0 -417
- package/template/src/framework/utils/swagger.ts +0 -184
- package/template/src/framework/utils/testDb.ts +0 -19
- package/template/src/framework/utils/token.ts +0 -23
- package/template/src/framework/utils/transform.ts +0 -17
- package/template/src/libs/aokEmailSender.ts +0 -42
- package/template/src/libs/captcha.ts +0 -37
- package/template/src/libs/cos.ts +0 -45
- package/template/src/libs/mCache.ts +0 -7
- package/template/src/libs/serviceValidate.ts +0 -3
- package/template/src/libs/tecentSms.ts +0 -51
- package/template/src/middlewares/a.middleware.ts +0 -6
- package/template/src/middlewares/error.middleware.ts +0 -14
- package/template/src/middlewares/logging.middleware.ts +0 -187
- package/template/src/middlewares/static.middleware.ts +0 -79
- package/template/src/middlewares/swagger.middleware.ts +0 -70
- package/template/src/middlewares/token.middleware.ts +0 -32
- package/template/src/migrations/1700000000000-InitialDatabaseStructure.ts +0 -172
- package/template/src/migrations/index.ts +0 -6
- package/template/src/repository/base/BaseRepository.ts +0 -124
- package/template/src/repository/interfaces/IBaseRepository.ts +0 -67
- package/template/src/service/base.service.ts +0 -116
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
import log4js from 'log4js'
|
|
2
|
-
import { getFullPath, isDebug, getRuntimeEnvironmentLabel } from '@src/framework/utils/function'
|
|
3
|
-
import { randomUUID } from 'crypto'
|
|
4
|
-
|
|
5
|
-
// 企业级日志配置
|
|
6
|
-
interface LogContext {
|
|
7
|
-
requestId?: string
|
|
8
|
-
userId?: string
|
|
9
|
-
sessionId?: string
|
|
10
|
-
traceId?: string
|
|
11
|
-
spanId?: string
|
|
12
|
-
service?: string
|
|
13
|
-
version?: string
|
|
14
|
-
environment?: string
|
|
15
|
-
[key: string]: any
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// 敏感信息脱敏配置
|
|
19
|
-
const SENSITIVE_FIELDS = [
|
|
20
|
-
'password', 'token', 'secret', 'key', 'auth', 'credential',
|
|
21
|
-
'ssn', 'socialSecurityNumber', 'creditCard', 'cardNumber',
|
|
22
|
-
'phone', 'email', 'address', 'ip', 'mac'
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
// 自定义布局器 - 支持结构化日志
|
|
26
|
-
class EnterpriseLayout {
|
|
27
|
-
constructor(private config: any) {}
|
|
28
|
-
|
|
29
|
-
format(loggingEvent: any): string {
|
|
30
|
-
const timestamp = new Date(loggingEvent.startTime).toISOString()
|
|
31
|
-
const level = loggingEvent.level.levelStr
|
|
32
|
-
const category = loggingEvent.categoryName
|
|
33
|
-
const message = loggingEvent.data[0]
|
|
34
|
-
const context = loggingEvent.context || {}
|
|
35
|
-
|
|
36
|
-
// 构建结构化日志对象
|
|
37
|
-
const logEntry = {
|
|
38
|
-
timestamp,
|
|
39
|
-
level,
|
|
40
|
-
category,
|
|
41
|
-
message,
|
|
42
|
-
service: context.service || 'dp-koa-framework',
|
|
43
|
-
version: context.version || '1.0.0',
|
|
44
|
-
environment: context.environment || getRuntimeEnvironmentLabel(),
|
|
45
|
-
requestId: context.requestId,
|
|
46
|
-
userId: context.userId,
|
|
47
|
-
sessionId: context.sessionId,
|
|
48
|
-
traceId: context.traceId,
|
|
49
|
-
spanId: context.spanId,
|
|
50
|
-
pid: process.pid,
|
|
51
|
-
hostname: process.env.HOSTNAME || 'localhost',
|
|
52
|
-
...this.extractAdditionalData(loggingEvent.data.slice(1))
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// 脱敏处理
|
|
56
|
-
this.sanitizeSensitiveData(logEntry)
|
|
57
|
-
|
|
58
|
-
return JSON.stringify(logEntry)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private extractAdditionalData(data: any[]): any {
|
|
62
|
-
const additionalData: any = {}
|
|
63
|
-
|
|
64
|
-
data.forEach((item, index) => {
|
|
65
|
-
if (typeof item === 'object' && item !== null) {
|
|
66
|
-
Object.assign(additionalData, item)
|
|
67
|
-
} else {
|
|
68
|
-
additionalData[`param${index}`] = item
|
|
69
|
-
}
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
return additionalData
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
private sanitizeSensitiveData(obj: any): void {
|
|
76
|
-
const sanitize = (value: any): any => {
|
|
77
|
-
if (typeof value === 'string') {
|
|
78
|
-
return '***REDACTED***'
|
|
79
|
-
}
|
|
80
|
-
if (typeof value === 'object' && value !== null) {
|
|
81
|
-
const sanitized: any = {}
|
|
82
|
-
for (const [key, val] of Object.entries(value)) {
|
|
83
|
-
sanitized[key] = this.isSensitiveField(key) ? '***REDACTED***' : sanitize(val)
|
|
84
|
-
}
|
|
85
|
-
return sanitized
|
|
86
|
-
}
|
|
87
|
-
return value
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
91
|
-
if (this.isSensitiveField(key)) {
|
|
92
|
-
obj[key] = '***REDACTED***'
|
|
93
|
-
} else if (typeof value === 'object' && value !== null) {
|
|
94
|
-
obj[key] = sanitize(value)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private isSensitiveField(fieldName: string): boolean {
|
|
100
|
-
return SENSITIVE_FIELDS.some(field =>
|
|
101
|
-
fieldName.toLowerCase().includes(field.toLowerCase())
|
|
102
|
-
)
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// 企业级日志器类
|
|
107
|
-
class EnterpriseLogger {
|
|
108
|
-
private logger: log4js.Logger
|
|
109
|
-
private context: LogContext = {}
|
|
110
|
-
private isProduction: boolean
|
|
111
|
-
|
|
112
|
-
constructor() {
|
|
113
|
-
this.logger = log4js.getLogger()
|
|
114
|
-
this.isProduction = !isDebug()
|
|
115
|
-
this.setupContext()
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private setupContext(): void {
|
|
119
|
-
this.context = {
|
|
120
|
-
service: 'dp-koa-framework',
|
|
121
|
-
version: process.env.npm_package_version || '1.0.0',
|
|
122
|
-
environment: getRuntimeEnvironmentLabel(),
|
|
123
|
-
pid: process.pid,
|
|
124
|
-
hostname: process.env.HOSTNAME || 'localhost'
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 设置请求上下文
|
|
129
|
-
setRequestContext(requestId: string, userId?: string, sessionId?: string): void {
|
|
130
|
-
this.context.requestId = requestId
|
|
131
|
-
this.context.userId = userId
|
|
132
|
-
this.context.sessionId = sessionId
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// 设置追踪上下文
|
|
136
|
-
setTraceContext(traceId: string, spanId?: string): void {
|
|
137
|
-
this.context.traceId = traceId
|
|
138
|
-
this.context.spanId = spanId
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// 清除上下文
|
|
142
|
-
clearContext(): void {
|
|
143
|
-
this.context = {
|
|
144
|
-
service: 'dp-koa-framework',
|
|
145
|
-
version: process.env.npm_package_version || '1.0.0',
|
|
146
|
-
environment: getRuntimeEnvironmentLabel(),
|
|
147
|
-
pid: process.pid,
|
|
148
|
-
hostname: process.env.HOSTNAME || 'localhost'
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// 生成请求ID
|
|
153
|
-
generateRequestId(): string {
|
|
154
|
-
return randomUUID()
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// 安全审计日志
|
|
158
|
-
audit(action: string, resource: string, details?: any): void {
|
|
159
|
-
// 审计日志写入文件,但不在控制台输出
|
|
160
|
-
const auditLogger = log4js.getLogger('audit')
|
|
161
|
-
auditLogger.info('AUDIT', {
|
|
162
|
-
...this.context,
|
|
163
|
-
action,
|
|
164
|
-
resource,
|
|
165
|
-
details,
|
|
166
|
-
timestamp: new Date().toISOString()
|
|
167
|
-
})
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// 性能监控日志 - 使用独立的category,不在控制台输出
|
|
171
|
-
performance(operation: string, duration: number, metrics?: any): void {
|
|
172
|
-
// 只在生产环境的慢请求时输出到控制台
|
|
173
|
-
if (this.isProduction && duration > 1000) {
|
|
174
|
-
this.logger.warn('慢请求警告', {
|
|
175
|
-
operation,
|
|
176
|
-
duration,
|
|
177
|
-
metrics
|
|
178
|
-
})
|
|
179
|
-
}
|
|
180
|
-
// 性能日志始终写入文件,但不会输出到控制台
|
|
181
|
-
const perfLogger = log4js.getLogger('performance')
|
|
182
|
-
perfLogger.info('PERFORMANCE', {
|
|
183
|
-
...this.context,
|
|
184
|
-
operation,
|
|
185
|
-
duration,
|
|
186
|
-
metrics,
|
|
187
|
-
timestamp: new Date().toISOString()
|
|
188
|
-
})
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// 安全事件日志
|
|
192
|
-
security(event: string, severity: 'low' | 'medium' | 'high' | 'critical', details?: any): void {
|
|
193
|
-
this.logger.warn('SECURITY', {
|
|
194
|
-
...this.context,
|
|
195
|
-
event,
|
|
196
|
-
severity,
|
|
197
|
-
details,
|
|
198
|
-
timestamp: new Date().toISOString()
|
|
199
|
-
})
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// 业务事件日志 - 不输出到控制台,只写入文件
|
|
203
|
-
business(event: string, data?: any): void {
|
|
204
|
-
// 业务日志不输出到控制台,会被 shouldFilterInfo 过滤掉
|
|
205
|
-
// 如果需要查看业务日志,请查看 logs/structured.log 文件
|
|
206
|
-
this.info('BUSINESS', {
|
|
207
|
-
...this.context,
|
|
208
|
-
event,
|
|
209
|
-
data,
|
|
210
|
-
timestamp: new Date().toISOString()
|
|
211
|
-
})
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// 错误日志增强
|
|
215
|
-
error(message: string, error?: Error, context?: any): void {
|
|
216
|
-
const errorDetails = error ? {
|
|
217
|
-
name: error.name,
|
|
218
|
-
message: error.message,
|
|
219
|
-
stack: error.stack,
|
|
220
|
-
code: (error as any).code
|
|
221
|
-
} : undefined
|
|
222
|
-
|
|
223
|
-
this.logger.error(message, {
|
|
224
|
-
...this.context,
|
|
225
|
-
error: errorDetails,
|
|
226
|
-
context,
|
|
227
|
-
timestamp: new Date().toISOString()
|
|
228
|
-
})
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// 标准日志方法 - 带智能过滤
|
|
232
|
-
info(message: string, ...args: any[]): void {
|
|
233
|
-
// 过滤掉冗余信息
|
|
234
|
-
if (this.shouldFilterInfo(message)) {
|
|
235
|
-
return
|
|
236
|
-
}
|
|
237
|
-
this.logger.info(message, ...args)
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
warn(message: string, ...args: any[]): void {
|
|
241
|
-
this.logger.warn(message, ...args)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
debug(message: string, ...args: any[]): void {
|
|
245
|
-
// 只在调试模式下输出debug日志
|
|
246
|
-
if (!isDebug()) {
|
|
247
|
-
return
|
|
248
|
-
}
|
|
249
|
-
this.logger.debug(message, ...args)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
trace(message: string, ...args: any[]): void {
|
|
253
|
-
// 只在调试模式下输出trace日志
|
|
254
|
-
if (!isDebug()) {
|
|
255
|
-
return
|
|
256
|
-
}
|
|
257
|
-
this.logger.trace(message, ...args)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// 判断是否应该过滤info级别的日志
|
|
261
|
-
private shouldFilterInfo(message: string): boolean {
|
|
262
|
-
const filterPatterns = [
|
|
263
|
-
'创建缓存',
|
|
264
|
-
'缓存命中',
|
|
265
|
-
'缓存未命中',
|
|
266
|
-
'Request started',
|
|
267
|
-
'Request completed',
|
|
268
|
-
'启动后执行',
|
|
269
|
-
'启动前初始化完毕',
|
|
270
|
-
'启动成功',
|
|
271
|
-
'[Logging]',
|
|
272
|
-
'BUSINESS'
|
|
273
|
-
]
|
|
274
|
-
|
|
275
|
-
return filterPatterns.some(pattern => message.includes(pattern))
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// 获取当前上下文
|
|
279
|
-
getContext(): LogContext {
|
|
280
|
-
return { ...this.context }
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// 注册自定义布局器
|
|
285
|
-
log4js.addLayout('enterprise', (config: any) => {
|
|
286
|
-
const layout = new EnterpriseLayout(config)
|
|
287
|
-
return (logEvent: any) => layout.format(logEvent)
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
// 配置log4js
|
|
291
|
-
log4js.configure({
|
|
292
|
-
pm2: true,
|
|
293
|
-
appenders: {
|
|
294
|
-
// 结构化日志文件
|
|
295
|
-
structured: {
|
|
296
|
-
type: 'dateFile',
|
|
297
|
-
filename: getFullPath("/logs/structured"),
|
|
298
|
-
pattern: 'yyyy-MM-dd.log',
|
|
299
|
-
alwaysIncludePattern: true,
|
|
300
|
-
maxLogSize: '50M',
|
|
301
|
-
backups: 30,
|
|
302
|
-
layout: {
|
|
303
|
-
type: 'enterprise'
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
// 错误日志文件
|
|
307
|
-
error: {
|
|
308
|
-
type: 'dateFile',
|
|
309
|
-
filename: getFullPath("/logs/error"),
|
|
310
|
-
pattern: 'yyyy-MM-dd.log',
|
|
311
|
-
alwaysIncludePattern: true,
|
|
312
|
-
maxLogSize: '20M',
|
|
313
|
-
backups: 15,
|
|
314
|
-
layout: {
|
|
315
|
-
type: 'enterprise'
|
|
316
|
-
},
|
|
317
|
-
},
|
|
318
|
-
// 审计日志文件
|
|
319
|
-
audit: {
|
|
320
|
-
type: 'dateFile',
|
|
321
|
-
filename: getFullPath("/logs/audit"),
|
|
322
|
-
pattern: 'yyyy-MM-dd.log',
|
|
323
|
-
alwaysIncludePattern: true,
|
|
324
|
-
maxLogSize: '30M',
|
|
325
|
-
backups: 20,
|
|
326
|
-
layout: {
|
|
327
|
-
type: 'enterprise'
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
|
-
// 性能日志文件
|
|
331
|
-
performance: {
|
|
332
|
-
type: 'dateFile',
|
|
333
|
-
filename: getFullPath("/logs/performance"),
|
|
334
|
-
pattern: 'yyyy-MM-dd.log',
|
|
335
|
-
alwaysIncludePattern: true,
|
|
336
|
-
maxLogSize: '25M',
|
|
337
|
-
backups: 15,
|
|
338
|
-
layout: {
|
|
339
|
-
type: 'enterprise'
|
|
340
|
-
},
|
|
341
|
-
// 不输出到控制台
|
|
342
|
-
suppressClustering: true
|
|
343
|
-
},
|
|
344
|
-
// 控制台输出 - 简化格式
|
|
345
|
-
console: {
|
|
346
|
-
type: 'console',
|
|
347
|
-
layout: {
|
|
348
|
-
type: 'colored',
|
|
349
|
-
pattern: isDebug()
|
|
350
|
-
? '[%d{hh:mm:ss}] [%p] %c - %m'
|
|
351
|
-
: '[%d{hh:mm:ss}] [%p] %m'
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
},
|
|
355
|
-
categories: {
|
|
356
|
-
default: {
|
|
357
|
-
// 开发与生产均输出到控制台,便于查看启动与运行状态
|
|
358
|
-
appenders: ['console', 'structured'],
|
|
359
|
-
level: isDebug() ? 'debug' : 'info'
|
|
360
|
-
},
|
|
361
|
-
error: {
|
|
362
|
-
appenders: ['error', 'console'],
|
|
363
|
-
level: 'error'
|
|
364
|
-
},
|
|
365
|
-
audit: {
|
|
366
|
-
appenders: ['audit'],
|
|
367
|
-
level: 'info'
|
|
368
|
-
},
|
|
369
|
-
performance: {
|
|
370
|
-
appenders: ['performance'], // 只写入文件,不输出到控制台
|
|
371
|
-
level: 'info'
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
})
|
|
375
|
-
|
|
376
|
-
// 创建企业级日志器实例
|
|
377
|
-
export const logger = new EnterpriseLogger()
|
|
378
|
-
|
|
379
|
-
// 导出类型和工具函数
|
|
380
|
-
export { LogContext, EnterpriseLogger }
|
|
381
|
-
export const createRequestLogger = (requestId?: string) => {
|
|
382
|
-
const requestLogger = new EnterpriseLogger()
|
|
383
|
-
if (requestId) {
|
|
384
|
-
requestLogger.setRequestContext(requestId)
|
|
385
|
-
}
|
|
386
|
-
return requestLogger
|
|
387
|
-
}
|
|
388
|
-
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { logger } from '@src/framework/utils/logger';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Prometheus指标收集器
|
|
5
|
-
*/
|
|
6
|
-
export class MetricsCollector {
|
|
7
|
-
private static instance: MetricsCollector;
|
|
8
|
-
private metrics: Map<string, any> = new Map();
|
|
9
|
-
|
|
10
|
-
private constructor() {
|
|
11
|
-
this.initializeMetrics();
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
static getInstance(): MetricsCollector {
|
|
15
|
-
if (!MetricsCollector.instance) {
|
|
16
|
-
MetricsCollector.instance = new MetricsCollector();
|
|
17
|
-
}
|
|
18
|
-
return MetricsCollector.instance;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* 初始化指标
|
|
23
|
-
*/
|
|
24
|
-
private initializeMetrics(): void {
|
|
25
|
-
// HTTP请求指标
|
|
26
|
-
this.metrics.set('http_requests_total', {
|
|
27
|
-
type: 'counter',
|
|
28
|
-
help: 'Total number of HTTP requests',
|
|
29
|
-
labels: ['method', 'route', 'status_code']
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// HTTP请求持续时间
|
|
33
|
-
this.metrics.set('http_request_duration_seconds', {
|
|
34
|
-
type: 'histogram',
|
|
35
|
-
help: 'HTTP request duration in seconds',
|
|
36
|
-
labels: ['method', 'route'],
|
|
37
|
-
buckets: [0.1, 0.5, 1, 2, 5, 10]
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// 活跃连接数
|
|
41
|
-
this.metrics.set('http_active_connections', {
|
|
42
|
-
type: 'gauge',
|
|
43
|
-
help: 'Number of active HTTP connections'
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// 数据库连接数
|
|
47
|
-
this.metrics.set('database_connections_active', {
|
|
48
|
-
type: 'gauge',
|
|
49
|
-
help: 'Number of active database connections'
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// 缓存命中率
|
|
53
|
-
this.metrics.set('cache_hits_total', {
|
|
54
|
-
type: 'counter',
|
|
55
|
-
help: 'Total number of cache hits',
|
|
56
|
-
labels: ['cache_name']
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
this.metrics.set('cache_misses_total', {
|
|
60
|
-
type: 'counter',
|
|
61
|
-
help: 'Total number of cache misses',
|
|
62
|
-
labels: ['cache_name']
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// 错误计数
|
|
66
|
-
this.metrics.set('errors_total', {
|
|
67
|
-
type: 'counter',
|
|
68
|
-
help: 'Total number of errors',
|
|
69
|
-
labels: ['error_type', 'severity']
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// 内存使用
|
|
73
|
-
this.metrics.set('memory_usage_bytes', {
|
|
74
|
-
type: 'gauge',
|
|
75
|
-
help: 'Memory usage in bytes',
|
|
76
|
-
labels: ['type']
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// CPU使用率
|
|
80
|
-
this.metrics.set('cpu_usage_percent', {
|
|
81
|
-
type: 'gauge',
|
|
82
|
-
help: 'CPU usage percentage'
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 记录HTTP请求
|
|
88
|
-
*/
|
|
89
|
-
recordHttpRequest(method: string, route: string, statusCode: number, duration: number): void {
|
|
90
|
-
// 这里可以集成实际的Prometheus客户端
|
|
91
|
-
logger.debug('HTTP请求指标', {
|
|
92
|
-
method,
|
|
93
|
-
route,
|
|
94
|
-
statusCode,
|
|
95
|
-
duration
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* 记录错误
|
|
101
|
-
*/
|
|
102
|
-
recordError(errorType: string, severity: string): void {
|
|
103
|
-
logger.debug('错误指标', {
|
|
104
|
-
errorType,
|
|
105
|
-
severity
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* 记录缓存操作
|
|
111
|
-
*/
|
|
112
|
-
recordCacheOperation(cacheName: string, hit: boolean): void {
|
|
113
|
-
logger.debug('缓存指标', {
|
|
114
|
-
cacheName,
|
|
115
|
-
hit
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* 记录数据库连接
|
|
121
|
-
*/
|
|
122
|
-
recordDatabaseConnection(active: number): void {
|
|
123
|
-
logger.debug('数据库连接指标', {
|
|
124
|
-
active
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* 获取系统指标
|
|
130
|
-
*/
|
|
131
|
-
getSystemMetrics(): any {
|
|
132
|
-
const memUsage = process.memoryUsage();
|
|
133
|
-
const cpuUsage = process.cpuUsage();
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
memory: {
|
|
137
|
-
rss: memUsage.rss,
|
|
138
|
-
heapTotal: memUsage.heapTotal,
|
|
139
|
-
heapUsed: memUsage.heapUsed,
|
|
140
|
-
external: memUsage.external
|
|
141
|
-
},
|
|
142
|
-
cpu: {
|
|
143
|
-
user: cpuUsage.user,
|
|
144
|
-
system: cpuUsage.system
|
|
145
|
-
},
|
|
146
|
-
uptime: process.uptime(),
|
|
147
|
-
pid: process.pid
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* 生成Prometheus格式的指标
|
|
153
|
-
*/
|
|
154
|
-
generatePrometheusMetrics(): string {
|
|
155
|
-
const metrics: string[] = [];
|
|
156
|
-
const systemMetrics = this.getSystemMetrics();
|
|
157
|
-
|
|
158
|
-
// 内存指标
|
|
159
|
-
metrics.push(`# HELP memory_usage_bytes Memory usage in bytes`);
|
|
160
|
-
metrics.push(`# TYPE memory_usage_bytes gauge`);
|
|
161
|
-
metrics.push(`memory_usage_bytes{type="rss"} ${systemMetrics.memory.rss}`);
|
|
162
|
-
metrics.push(`memory_usage_bytes{type="heap_total"} ${systemMetrics.memory.heapTotal}`);
|
|
163
|
-
metrics.push(`memory_usage_bytes{type="heap_used"} ${systemMetrics.memory.heapUsed}`);
|
|
164
|
-
metrics.push(`memory_usage_bytes{type="external"} ${systemMetrics.memory.external}`);
|
|
165
|
-
|
|
166
|
-
// CPU指标
|
|
167
|
-
metrics.push(`# HELP cpu_usage_seconds CPU usage in seconds`);
|
|
168
|
-
metrics.push(`# TYPE cpu_usage_seconds gauge`);
|
|
169
|
-
metrics.push(`cpu_usage_seconds{type="user"} ${systemMetrics.cpu.user / 1000000}`);
|
|
170
|
-
metrics.push(`cpu_usage_seconds{type="system"} ${systemMetrics.cpu.system / 1000000}`);
|
|
171
|
-
|
|
172
|
-
// 进程指标
|
|
173
|
-
metrics.push(`# HELP process_uptime_seconds Process uptime in seconds`);
|
|
174
|
-
metrics.push(`# TYPE process_uptime_seconds gauge`);
|
|
175
|
-
metrics.push(`process_uptime_seconds ${systemMetrics.uptime}`);
|
|
176
|
-
|
|
177
|
-
return metrics.join('\n');
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// 导出单例实例
|
|
182
|
-
export const metricsCollector = MetricsCollector.getInstance();
|