t034_structured_logging_demo.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /**
  2. * T034 演示:结构化日志和审计跟踪
  3. * 演示结构化日志系统的完整功能
  4. */
  5. import { logger } from '../src/utils/logger.js'
  6. // 模拟 MonitoringEventManager
  7. class MockMonitoringEventManager {
  8. private events: any[] = []
  9. addEvent(event: any): void {
  10. this.events.push(event)
  11. logger.info(`添加监控事件: ${event.type}`)
  12. }
  13. getAllEvents(): any[] {
  14. return this.events
  15. }
  16. }
  17. // 模拟文件系统操作
  18. class MockFileSystem {
  19. private files = new Map<string, string>()
  20. existsSync(path: string): boolean {
  21. return this.files.has(path)
  22. }
  23. mkdirSync(path: string, options?: any): void {
  24. this.files.set(path, '')
  25. logger.info(`创建目录: ${path}`)
  26. }
  27. appendFileSync(path: string, data: string): void {
  28. const existing = this.files.get(path) || ''
  29. this.files.set(path, existing + data)
  30. }
  31. readFileSync(path: string): string {
  32. return this.files.get(path) || ''
  33. }
  34. getFileSize(path: string): number {
  35. const content = this.files.get(path) || ''
  36. return Buffer.byteLength(content, 'utf8')
  37. }
  38. getFiles(): string[] {
  39. return Array.from(this.files.keys())
  40. }
  41. }
  42. // 简化的结构化日志服务实现
  43. class SimpleStructuredLoggingService {
  44. private config: any
  45. private stats: any
  46. private monitoringManager: MockMonitoringEventManager
  47. private mockFs: MockFileSystem
  48. private logQueue: any[] = []
  49. private isProcessing = false
  50. constructor(monitoringManager: MockMonitoringEventManager) {
  51. this.monitoringManager = monitoringManager
  52. this.mockFs = new MockFileSystem()
  53. this.config = {
  54. enableAuditLogging: true,
  55. enablePerformanceLogging: true,
  56. enableSecurityLogging: true,
  57. enableTradingLogging: true,
  58. logLevel: 'info',
  59. logDirectory: './logs',
  60. maxLogFileSize: 100 * 1024 * 1024,
  61. retentionDays: 30,
  62. enableCompression: false
  63. }
  64. this.stats = {
  65. totalLogs: 0,
  66. auditLogs: 0,
  67. performanceLogs: 0,
  68. securityLogs: 0,
  69. tradingLogs: 0,
  70. errorLogs: 0,
  71. lastLogTime: 0,
  72. logFileSize: 0
  73. }
  74. this.initializeLogging()
  75. }
  76. private initializeLogging(): void {
  77. logger.info('初始化结构化日志系统')
  78. try {
  79. // 创建日志目录
  80. if (!this.mockFs.existsSync(this.config.logDirectory)) {
  81. this.mockFs.mkdirSync(this.config.logDirectory, { recursive: true })
  82. }
  83. // 启动日志处理队列
  84. this.startLogProcessing()
  85. // 记录系统启动日志
  86. this.logAuditEvent({
  87. eventType: 'system_startup',
  88. service: 'StructuredLoggingService',
  89. action: 'initialize',
  90. details: { config: this.config },
  91. result: 'success'
  92. })
  93. logger.info('结构化日志系统初始化完成')
  94. } catch (error: any) {
  95. logger.error(`结构化日志系统初始化失败: ${error.message}`)
  96. throw error
  97. }
  98. }
  99. private startLogProcessing(): void {
  100. setInterval(() => {
  101. this.processLogQueue()
  102. }, 1000)
  103. }
  104. private async processLogQueue(): Promise<void> {
  105. if (this.isProcessing || this.logQueue.length === 0) {
  106. return
  107. }
  108. this.isProcessing = true
  109. try {
  110. const logsToProcess = [...this.logQueue]
  111. this.logQueue = []
  112. for (const logEntry of logsToProcess) {
  113. await this.writeLogEntry(logEntry)
  114. }
  115. this.stats.totalLogs += logsToProcess.length
  116. this.stats.lastLogTime = Date.now()
  117. } catch (error: any) {
  118. logger.error(`处理日志队列失败: ${error.message}`)
  119. } finally {
  120. this.isProcessing = false
  121. }
  122. }
  123. private async writeLogEntry(logEntry: any): Promise<void> {
  124. try {
  125. // 写入审计日志文件
  126. if (this.config.enableAuditLogging) {
  127. await this.writeAuditLog(logEntry)
  128. }
  129. // 写入结构化日志文件
  130. await this.writeStructuredLog(logEntry)
  131. // 更新统计信息
  132. this.updateLogStats(logEntry)
  133. // 发送到监控系统
  134. await this.sendToMonitoring(logEntry)
  135. } catch (error: any) {
  136. logger.error(`写入日志条目失败: ${error.message}`)
  137. }
  138. }
  139. private async writeAuditLog(logEntry: any): Promise<void> {
  140. const auditLogPath = `${this.config.logDirectory}/audit.log`
  141. const logLine = JSON.stringify(logEntry) + '\n'
  142. this.mockFs.appendFileSync(auditLogPath, logLine)
  143. }
  144. private async writeStructuredLog(logEntry: any): Promise<void> {
  145. const logPath = `${this.config.logDirectory}/structured.log`
  146. const logLine = JSON.stringify(logEntry) + '\n'
  147. this.mockFs.appendFileSync(logPath, logLine)
  148. }
  149. private updateLogStats(logEntry: any): void {
  150. switch (logEntry.eventType) {
  151. case 'audit':
  152. this.stats.auditLogs++
  153. break
  154. case 'performance':
  155. this.stats.performanceLogs++
  156. break
  157. case 'security':
  158. this.stats.securityLogs++
  159. break
  160. case 'trading':
  161. this.stats.tradingLogs++
  162. break
  163. }
  164. if (logEntry.result === 'failure') {
  165. this.stats.errorLogs++
  166. }
  167. }
  168. private async sendToMonitoring(logEntry: any): Promise<void> {
  169. try {
  170. const monitoringEvent = {
  171. eventId: logEntry.eventId,
  172. type: logEntry.eventType,
  173. payload: {
  174. service: logEntry.service,
  175. action: logEntry.action,
  176. details: logEntry.details,
  177. result: logEntry.result,
  178. duration: logEntry.duration
  179. },
  180. severity: this.mapResultToSeverity(logEntry.result),
  181. createdAt: new Date(logEntry.timestamp)
  182. }
  183. this.monitoringManager.addEvent(monitoringEvent)
  184. } catch (error: any) {
  185. logger.error(`发送到监控系统失败: ${error.message}`)
  186. }
  187. }
  188. private mapResultToSeverity(result: string): 'INFO' | 'WARN' | 'ERROR' {
  189. switch (result) {
  190. case 'success':
  191. return 'INFO'
  192. case 'warning':
  193. return 'WARN'
  194. case 'failure':
  195. return 'ERROR'
  196. default:
  197. return 'INFO'
  198. }
  199. }
  200. logAuditEvent(event: any): void {
  201. const logEntry = {
  202. timestamp: new Date().toISOString(),
  203. eventId: `audit-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
  204. ...event
  205. }
  206. this.logQueue.push(logEntry)
  207. logger.info(`[AUDIT] ${event.service}: ${event.action} - ${event.result}`, {
  208. eventId: logEntry.eventId,
  209. eventType: event.eventType,
  210. details: event.details
  211. })
  212. }
  213. logPerformanceEvent(event: any): void {
  214. const logEntry = {
  215. timestamp: new Date().toISOString(),
  216. eventId: `perf-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
  217. eventType: 'performance',
  218. ...event
  219. }
  220. this.logQueue.push(logEntry)
  221. logger.debug(`[PERF] ${event.service}: ${event.action} - ${event.duration}ms`, {
  222. eventId: logEntry.eventId,
  223. details: event.details
  224. })
  225. }
  226. logSecurityEvent(event: any): void {
  227. const logEntry = {
  228. timestamp: new Date().toISOString(),
  229. eventId: `sec-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
  230. eventType: 'security',
  231. ...event
  232. }
  233. this.logQueue.push(logEntry)
  234. logger.warn(`[SEC] ${event.service}: ${event.action} - ${event.result}`, {
  235. eventId: logEntry.eventId,
  236. details: event.details
  237. })
  238. }
  239. logTradingEvent(event: any): void {
  240. const logEntry = {
  241. timestamp: new Date().toISOString(),
  242. eventId: `trade-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
  243. eventType: 'trading',
  244. ...event
  245. }
  246. this.logQueue.push(logEntry)
  247. logger.info(`[TRADE] ${event.service}: ${event.action} - ${event.result}`, {
  248. eventId: logEntry.eventId,
  249. symbol: event.symbol,
  250. accountId: event.accountId,
  251. details: event.details
  252. })
  253. }
  254. logSystemEvent(event: any): void {
  255. const logEntry = {
  256. timestamp: new Date().toISOString(),
  257. eventId: `sys-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
  258. eventType: 'system',
  259. ...event
  260. }
  261. this.logQueue.push(logEntry)
  262. logger.info(`[SYS] ${event.service}: ${event.action} - ${event.result}`, {
  263. eventId: logEntry.eventId,
  264. details: event.details
  265. })
  266. }
  267. getLogStats(): any {
  268. return { ...this.stats }
  269. }
  270. getConfig(): any {
  271. return { ...this.config }
  272. }
  273. async cleanupOldLogs(): Promise<void> {
  274. try {
  275. this.logAuditEvent({
  276. eventType: 'maintenance',
  277. service: 'StructuredLoggingService',
  278. action: 'cleanupOldLogs',
  279. details: { retentionDays: this.config.retentionDays },
  280. result: 'success'
  281. })
  282. logger.info('旧日志文件清理完成')
  283. } catch (error: any) {
  284. this.logAuditEvent({
  285. eventType: 'maintenance',
  286. service: 'StructuredLoggingService',
  287. action: 'cleanupOldLogs',
  288. details: { error: error.message },
  289. result: 'failure'
  290. })
  291. logger.error(`清理旧日志文件失败: ${error.message}`)
  292. }
  293. }
  294. getLogFiles(): string[] {
  295. return this.mockFs.getFiles()
  296. }
  297. getLogContent(fileName: string): string {
  298. return this.mockFs.readFileSync(fileName)
  299. }
  300. }
  301. async function main() {
  302. logger.info('=== T034 结构化日志和审计跟踪演示 ===')
  303. try {
  304. // 1. 创建监控事件管理器
  305. const monitoringManager = new MockMonitoringEventManager()
  306. // 2. 创建结构化日志服务
  307. const loggingService = new SimpleStructuredLoggingService(monitoringManager)
  308. // 3. 等待日志系统初始化
  309. await new Promise(resolve => setTimeout(resolve, 1000))
  310. // 4. 测试各种类型的日志记录
  311. logger.info('测试审计日志记录...')
  312. loggingService.logAuditEvent({
  313. eventType: 'account_sync',
  314. service: 'AccountManager',
  315. action: 'syncAccounts',
  316. accountId: 'pacifica-1',
  317. details: { accountCount: 2, syncDuration: 150 },
  318. result: 'success'
  319. })
  320. logger.info('测试性能日志记录...')
  321. loggingService.logPerformanceEvent({
  322. service: 'HedgingCoordinator',
  323. action: 'executeHedge',
  324. duration: 250,
  325. details: { hedgeQuantity: 0.01, executionPrice: 108000 },
  326. result: 'success'
  327. })
  328. logger.info('测试安全日志记录...')
  329. loggingService.logSecurityEvent({
  330. service: 'AccountManager',
  331. action: 'validateCredentials',
  332. details: { accountId: 'pacifica-1', validationResult: 'valid' },
  333. result: 'success'
  334. })
  335. logger.info('测试交易日志记录...')
  336. loggingService.logTradingEvent({
  337. service: 'TradingEngine',
  338. action: 'executeOrder',
  339. accountId: 'pacifica-1',
  340. symbol: 'BTC-USD',
  341. details: { orderType: 'limit', quantity: 0.01, price: 108000 },
  342. result: 'success',
  343. duration: 100
  344. })
  345. logger.info('测试系统日志记录...')
  346. loggingService.logSystemEvent({
  347. service: 'SystemOrchestrator',
  348. action: 'startService',
  349. details: { serviceName: 'TradingEngineV2', startTime: Date.now() },
  350. result: 'success'
  351. })
  352. // 5. 等待日志处理
  353. await new Promise(resolve => setTimeout(resolve, 2000))
  354. // 6. 检查日志统计
  355. const logStats = loggingService.getLogStats()
  356. logger.info('日志统计信息:', logStats)
  357. // 7. 检查日志文件
  358. const logFiles = loggingService.getLogFiles()
  359. logger.info(`生成的日志文件: ${logFiles.length}`)
  360. logFiles.forEach(fileName => {
  361. logger.info(`- ${fileName}`)
  362. })
  363. // 8. 检查监控事件
  364. const monitoringEvents = monitoringManager.getAllEvents()
  365. logger.info(`监控事件数量: ${monitoringEvents.length}`)
  366. // 9. 测试日志清理功能
  367. logger.info('测试日志清理功能...')
  368. await loggingService.cleanupOldLogs()
  369. // 10. 验证日志内容
  370. logger.info('验证日志内容...')
  371. const auditLogContent = loggingService.getLogContent('./logs/audit.log')
  372. const structuredLogContent = loggingService.getLogContent('./logs/structured.log')
  373. const auditLogLines = auditLogContent.split('\n').filter(line => line.trim()).length
  374. const structuredLogLines = structuredLogContent.split('\n').filter(line => line.trim()).length
  375. logger.info(`验证结果:`)
  376. logger.info(`- 审计日志行数: ${auditLogLines}`)
  377. logger.info(`- 结构化日志行数: ${structuredLogLines}`)
  378. logger.info(`- 监控事件数量: ${monitoringEvents.length}`)
  379. logger.info(`- 总日志数量: ${logStats.totalLogs}`)
  380. logger.info(`- 审计日志数量: ${logStats.auditLogs}`)
  381. logger.info(`- 性能日志数量: ${logStats.performanceLogs}`)
  382. logger.info(`- 安全日志数量: ${logStats.securityLogs}`)
  383. logger.info(`- 交易日志数量: ${logStats.tradingLogs}`)
  384. logger.info(`- 错误日志数量: ${logStats.errorLogs}`)
  385. logger.info(`- 数据一致性: ${auditLogLines > 0 && structuredLogLines > 0 && monitoringEvents.length > 0 ? '✅' : '❌'}`)
  386. logger.info('=== T034 结构化日志和审计跟踪演示完成 ===')
  387. } catch (error: any) {
  388. logger.error('T034 演示失败:', { error: error.message, stack: error.stack })
  389. process.exit(1)
  390. }
  391. }
  392. // 运行演示
  393. if (import.meta.url === `file://${process.argv[1]}`) {
  394. main().catch(error => {
  395. logger.error('演示运行失败:', error)
  396. process.exit(1)
  397. })
  398. }