109 lines
2.4 KiB
Go
109 lines
2.4 KiB
Go
package middleware
|
||
|
||
import (
|
||
"bytes"
|
||
"io"
|
||
"strconv"
|
||
"time"
|
||
|
||
"kra/pkg/utils"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
// EmailSender 邮件发送接口
|
||
type EmailSender interface {
|
||
ErrorToEmail(subject, body string) error
|
||
}
|
||
|
||
// UserFinder 用户查找接口
|
||
type UserFinder interface {
|
||
FindUsernameByID(id int) (string, error)
|
||
}
|
||
|
||
// EmailConfig 邮件中间件配置
|
||
type EmailConfig struct {
|
||
EmailSender EmailSender
|
||
UserFinder UserFinder
|
||
Logger *zap.Logger
|
||
}
|
||
|
||
// 全局邮件配置
|
||
var emailConfig *EmailConfig
|
||
|
||
// SetEmailConfig 设置邮件配置
|
||
func SetEmailConfig(cfg *EmailConfig) {
|
||
emailConfig = cfg
|
||
}
|
||
|
||
// ErrorToEmail 错误发送邮件中间件(与 kra 保持一致)
|
||
func ErrorToEmail() gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
var username string
|
||
|
||
// 获取用户信息
|
||
claims, _ := utils.GetClaims(c)
|
||
if claims != nil && claims.Username != "" {
|
||
username = claims.Username
|
||
} else {
|
||
id, _ := strconv.Atoi(c.Request.Header.Get("x-user-id"))
|
||
if id > 0 && emailConfig != nil && emailConfig.UserFinder != nil {
|
||
if name, err := emailConfig.UserFinder.FindUsernameByID(id); err == nil {
|
||
username = name
|
||
} else {
|
||
username = "Unknown"
|
||
}
|
||
} else {
|
||
username = "Unknown"
|
||
}
|
||
}
|
||
|
||
// 读取请求体
|
||
body, _ := io.ReadAll(c.Request.Body)
|
||
// 将原body塞回去
|
||
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
|
||
|
||
// 记录请求信息
|
||
record := struct {
|
||
IP string
|
||
Method string
|
||
Path string
|
||
Agent string
|
||
Body string
|
||
}{
|
||
IP: c.ClientIP(),
|
||
Method: c.Request.Method,
|
||
Path: c.Request.URL.Path,
|
||
Agent: c.Request.UserAgent(),
|
||
Body: string(body),
|
||
}
|
||
|
||
now := time.Now()
|
||
|
||
c.Next()
|
||
|
||
latency := time.Since(now)
|
||
status := c.Writer.Status()
|
||
errorMessage := c.Errors.ByType(gin.ErrorTypePrivate).String()
|
||
|
||
// 构建邮件内容
|
||
str := "接收到的请求为" + record.Body + "\n" +
|
||
"请求方式为" + record.Method + "\n" +
|
||
"报错信息如下" + errorMessage + "\n" +
|
||
"耗时" + latency.String() + "\n"
|
||
|
||
// 如果状态码不是200,发送邮件
|
||
if status != 200 {
|
||
subject := username + " " + record.IP + "调用了" + record.Path + "报错了"
|
||
if emailConfig != nil && emailConfig.EmailSender != nil {
|
||
if err := emailConfig.EmailSender.ErrorToEmail(subject, str); err != nil {
|
||
if emailConfig.Logger != nil {
|
||
emailConfig.Logger.Error("ErrorToEmail Failed, err:", zap.Error(err))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|