79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
package middleware
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"time"
|
|
|
|
"github.com/go-kratos/kratos/v2/log"
|
|
"github.com/go-kratos/kratos/v2/middleware"
|
|
"github.com/go-kratos/kratos/v2/transport"
|
|
kratoshttp "github.com/go-kratos/kratos/v2/transport/http"
|
|
)
|
|
|
|
// EmailSender 邮件发送接口
|
|
type EmailSender interface {
|
|
SendError(subject, body string) error
|
|
}
|
|
|
|
// ErrorToEmail 错误邮件通知中间件
|
|
func ErrorToEmail(sender EmailSender, logger log.Logger) middleware.Middleware {
|
|
helper := log.NewHelper(logger)
|
|
return func(handler middleware.Handler) middleware.Handler {
|
|
return func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
var (
|
|
username string
|
|
body string
|
|
method string
|
|
path string
|
|
ip string
|
|
)
|
|
|
|
// 获取用户信息
|
|
if claims, ok := GetClaims(ctx); ok {
|
|
username = claims.Username
|
|
}
|
|
if username == "" {
|
|
username = "Unknown"
|
|
}
|
|
|
|
if tr, ok := transport.FromServerContext(ctx); ok {
|
|
path = tr.Operation()
|
|
if header := tr.RequestHeader(); header != nil {
|
|
method = header.Get(":method")
|
|
}
|
|
|
|
if ht, ok := tr.(kratoshttp.Transporter); ok {
|
|
r := ht.Request()
|
|
ip = getClientIP(r)
|
|
|
|
// 读取body
|
|
bodyBytes, _ := io.ReadAll(r.Body)
|
|
r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
|
body = string(bodyBytes)
|
|
}
|
|
}
|
|
|
|
start := time.Now()
|
|
reply, err := handler(ctx, req)
|
|
latency := time.Since(start)
|
|
|
|
// 如果有错误,发送邮件
|
|
if err != nil && sender != nil {
|
|
subject := fmt.Sprintf("%s %s调用了%s报错了", username, ip, path)
|
|
content := fmt.Sprintf(
|
|
"接收到的请求为%s\n请求方式为%s\n报错信息如下%s\n耗时%s\n",
|
|
body, method, err.Error(), latency.String(),
|
|
)
|
|
if sendErr := sender.SendError(subject, content); sendErr != nil {
|
|
helper.Error("ErrorToEmail Failed, err:", sendErr)
|
|
}
|
|
}
|
|
|
|
return reply, err
|
|
}
|
|
}
|
|
}
|