middleware.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package logger
  2. import (
  3. "time"
  4. "github.com/gin-gonic/gin"
  5. "go.uber.org/zap"
  6. )
  7. // AuditMiddleware 创建审计中间件
  8. func AuditMiddleware(audit AuditLogger, logger Logger) gin.HandlerFunc {
  9. return func(c *gin.Context) {
  10. start := time.Now()
  11. // 获取用户信息(这里需要根据你的认证系统调整)
  12. userID := getUserID(c)
  13. username := getUsername(c)
  14. // 处理请求
  15. c.Next()
  16. // 计算请求持续时间
  17. duration := time.Since(start)
  18. // 记录访问日志
  19. logger.Info("HTTP请求",
  20. zap.String("method", c.Request.Method),
  21. zap.String("path", c.Request.URL.Path),
  22. zap.String("query", c.Request.URL.RawQuery),
  23. zap.String("ip", c.ClientIP()),
  24. zap.String("user_agent", c.Request.UserAgent()),
  25. zap.Int("status", c.Writer.Status()),
  26. zap.Duration("duration", duration),
  27. zap.String("user_id", userID),
  28. )
  29. // 记录审计事件
  30. entry := &AuditEntry{
  31. UserID: userID,
  32. Username: username,
  33. Action: c.Request.Method + " " + c.Request.URL.Path,
  34. Resource: c.Request.URL.Path,
  35. Details: c.Request.URL.RawQuery,
  36. IP: c.ClientIP(),
  37. UserAgent: c.Request.UserAgent(),
  38. Success: c.Writer.Status() < 400,
  39. }
  40. // 如果有错误,记录错误信息
  41. if len(c.Errors) > 0 {
  42. entry.Error = c.Errors.String()
  43. entry.Success = false
  44. }
  45. // 异步记录审计,避免阻塞请求
  46. go func() {
  47. if err := audit.Record(entry); err != nil {
  48. // 审计失败记录到日志,但不影响正常业务
  49. logger.Error("审计记录失败", zap.Error(err))
  50. }
  51. }()
  52. }
  53. }
  54. // RequestLogger 创建请求日志中间件(不包含审计)
  55. func RequestLogger(logger Logger) gin.HandlerFunc {
  56. return func(c *gin.Context) {
  57. start := time.Now()
  58. // 处理请求
  59. c.Next()
  60. // 计算请求持续时间
  61. duration := time.Since(start)
  62. // 记录请求日志
  63. logger.Info("HTTP请求",
  64. zap.String("method", c.Request.Method),
  65. zap.String("path", c.Request.URL.Path),
  66. zap.String("query", c.Request.URL.RawQuery),
  67. zap.String("ip", c.ClientIP()),
  68. zap.String("user_agent", c.Request.UserAgent()),
  69. zap.Int("status", c.Writer.Status()),
  70. zap.Duration("duration", duration),
  71. )
  72. }
  73. }
  74. // RecoveryMiddleware 创建恢复中间件
  75. func RecoveryMiddleware(logger Logger) gin.HandlerFunc {
  76. return gin.CustomRecovery(func(c *gin.Context, recovered interface{}) {
  77. if err, ok := recovered.(string); ok {
  78. logger.Error("panic recovered",
  79. zap.String("error", err),
  80. zap.String("method", c.Request.Method),
  81. zap.String("path", c.Request.URL.Path),
  82. zap.String("ip", c.ClientIP()),
  83. )
  84. } else {
  85. logger.Error("panic recovered",
  86. zap.Any("error", recovered),
  87. zap.String("method", c.Request.Method),
  88. zap.String("path", c.Request.URL.Path),
  89. zap.String("ip", c.ClientIP()),
  90. )
  91. }
  92. c.AbortWithStatusJSON(500, gin.H{
  93. "error": "Internal Server Error",
  94. })
  95. })
  96. }
  97. // getUserID 从请求上下文中获取用户ID
  98. // 这里需要根据你的认证系统进行调整
  99. func getUserID(c *gin.Context) string {
  100. // 示例:从JWT token或session中获取
  101. if userID, exists := c.Get("user_id"); exists {
  102. if id, ok := userID.(string); ok {
  103. return id
  104. }
  105. }
  106. return ""
  107. }
  108. // getUsername 从请求上下文中获取用户名
  109. // 这里需要根据你的认证系统进行调整
  110. func getUsername(c *gin.Context) string {
  111. // 示例:从JWT token或session中获取
  112. if username, exists := c.Get("username"); exists {
  113. if name, ok := username.(string); ok {
  114. return name
  115. }
  116. }
  117. return ""
  118. }
  119. // AuditHelper 审计助手,提供便捷的审计方法
  120. type AuditHelper struct {
  121. audit AuditLogger
  122. logger Logger
  123. }
  124. // NewAuditHelper 创建审计助手
  125. func NewAuditHelper(audit AuditLogger, logger Logger) *AuditHelper {
  126. return &AuditHelper{
  127. audit: audit,
  128. logger: logger,
  129. }
  130. }
  131. // RecordLogin 记录登录事件
  132. func (h *AuditHelper) RecordLogin(userID, username, ip, userAgent string, success bool) {
  133. entry := &AuditEntry{
  134. UserID: userID,
  135. Username: username,
  136. Action: "login",
  137. Resource: "auth",
  138. IP: ip,
  139. UserAgent: userAgent,
  140. Success: success,
  141. }
  142. if err := h.audit.Record(entry); err != nil {
  143. h.logger.Error("记录登录审计失败", zap.Error(err))
  144. }
  145. }
  146. // RecordUserAction 记录用户操作
  147. func (h *AuditHelper) RecordUserAction(userID, username, action, resource, resourceID, ip string, success bool) {
  148. entry := &AuditEntry{
  149. UserID: userID,
  150. Username: username,
  151. Action: action,
  152. Resource: resource,
  153. Details: resourceID,
  154. IP: ip,
  155. Success: success,
  156. }
  157. if err := h.audit.Record(entry); err != nil {
  158. h.logger.Error("记录用户操作审计失败", zap.Error(err))
  159. }
  160. }
  161. // RecordSystemEvent 记录系统事件
  162. func (h *AuditHelper) RecordSystemEvent(event, details string) {
  163. entry := &AuditEntry{
  164. Action: "system_event",
  165. Resource: event,
  166. Details: details,
  167. Success: true,
  168. }
  169. if err := h.audit.Record(entry); err != nil {
  170. h.logger.Error("记录系统事件审计失败", zap.Error(err))
  171. }
  172. }