初始化v1

This commit is contained in:
2025-08-03 00:11:15 +08:00
commit b88c8b8afa
171 changed files with 22353 additions and 0 deletions

View File

@@ -0,0 +1,312 @@
package recovery
import (
"context"
"fmt"
"runtime"
"strings"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gtime"
"nl-video-api/utility/response"
)
// RecoveryMiddleware 恢复中间件
func RecoveryMiddleware(r *ghttp.Request) {
defer func() {
if err := recover(); err != nil {
// 记录panic信息
LogPanic(r.Context(), err)
// 返回统一错误响应
response.JsonExit(r, 1007, "服务器内部错误")
}
}()
r.Middleware.Next()
}
// LogPanic 记录panic信息
func LogPanic(ctx context.Context, err interface{}) {
// 获取调用栈信息
stack := getStack(3)
// 记录详细的panic信息
g.Log().Error(ctx, "System Panic Recovered", g.Map{
"error": fmt.Sprintf("%v", err),
"stack": stack,
"timestamp": gtime.Now().String(),
})
// 发送告警通知(可以集成钉钉、邮件等)
sendAlertNotification(ctx, err, stack)
}
// getStack 获取调用栈
func getStack(skip int) string {
var buf strings.Builder
for i := skip; ; i++ {
pc, file, line, ok := runtime.Caller(i)
if !ok {
break
}
fn := runtime.FuncForPC(pc)
if fn == nil {
buf.WriteString("unknown function\n")
} else {
buf.WriteString(fmt.Sprintf("%s:%d %s\n", file, line, fn.Name()))
}
}
return buf.String()
}
// sendAlertNotification 发送告警通知
func sendAlertNotification(ctx context.Context, err interface{}, stack string) {
// 这里可以集成各种告警通知方式
// 例如:钉钉机器人、邮件、短信等
g.Log().Warning(ctx, "Alert Notification", g.Map{
"type": "panic_recovery",
"error": fmt.Sprintf("%v", err),
"message": "系统发生panic,已自动恢复",
})
}
// ErrorHandler 统一错误处理器
type ErrorHandler struct {
ctx context.Context
}
// NewErrorHandler 创建错误处理器
func NewErrorHandler(ctx context.Context) *ErrorHandler {
return &ErrorHandler{ctx: ctx}
}
// HandleError 处理错误
func (e *ErrorHandler) HandleError(err error, operation string) {
if err == nil {
return
}
// 记录错误信息
g.Log().Error(e.ctx, "Operation Error", g.Map{
"operation": operation,
"error": err.Error(),
"timestamp": gtime.Now().String(),
})
// 根据错误类型进行不同处理
e.categorizeError(err, operation)
}
// categorizeError 错误分类处理
func (e *ErrorHandler) categorizeError(err error, operation string) {
errMsg := err.Error()
switch {
case strings.Contains(errMsg, "connection refused"):
e.handleConnectionError(err, operation)
case strings.Contains(errMsg, "timeout"):
e.handleTimeoutError(err, operation)
case strings.Contains(errMsg, "duplicate"):
e.handleDuplicateError(err, operation)
case strings.Contains(errMsg, "not found"):
e.handleNotFoundError(err, operation)
default:
e.handleGenericError(err, operation)
}
}
// handleConnectionError 处理连接错误
func (e *ErrorHandler) handleConnectionError(err error, operation string) {
g.Log().Error(e.ctx, "Connection Error", g.Map{
"operation": operation,
"error": err.Error(),
"type": "connection",
"action": "retry_connection",
})
}
// handleTimeoutError 处理超时错误
func (e *ErrorHandler) handleTimeoutError(err error, operation string) {
g.Log().Error(e.ctx, "Timeout Error", g.Map{
"operation": operation,
"error": err.Error(),
"type": "timeout",
"action": "increase_timeout",
})
}
// handleDuplicateError 处理重复错误
func (e *ErrorHandler) handleDuplicateError(err error, operation string) {
g.Log().Warning(e.ctx, "Duplicate Error", g.Map{
"operation": operation,
"error": err.Error(),
"type": "duplicate",
"action": "check_uniqueness",
})
}
// handleNotFoundError 处理未找到错误
func (e *ErrorHandler) handleNotFoundError(err error, operation string) {
g.Log().Info(e.ctx, "Not Found Error", g.Map{
"operation": operation,
"error": err.Error(),
"type": "not_found",
"action": "verify_resource",
})
}
// handleGenericError 处理通用错误
func (e *ErrorHandler) handleGenericError(err error, operation string) {
g.Log().Error(e.ctx, "Generic Error", g.Map{
"operation": operation,
"error": err.Error(),
"type": "generic",
"action": "manual_review",
})
}
// RetryHandler 重试处理器
type RetryHandler struct {
maxRetries int
ctx context.Context
}
// NewRetryHandler 创建重试处理器
func NewRetryHandler(ctx context.Context, maxRetries int) *RetryHandler {
return &RetryHandler{
maxRetries: maxRetries,
ctx: ctx,
}
}
// ExecuteWithRetry 带重试的执行
func (r *RetryHandler) ExecuteWithRetry(operation func() error, operationName string) error {
var lastErr error
for i := 0; i <= r.maxRetries; i++ {
err := operation()
if err == nil {
if i > 0 {
g.Log().Info(r.ctx, "Operation Succeeded After Retry", g.Map{
"operation": operationName,
"retry_count": i,
"max_retries": r.maxRetries,
})
}
return nil
}
lastErr = err
if i < r.maxRetries {
g.Log().Warning(r.ctx, "Operation Failed, Retrying", g.Map{
"operation": operationName,
"error": err.Error(),
"retry_count": i + 1,
"max_retries": r.maxRetries,
})
}
}
g.Log().Error(r.ctx, "Operation Failed After All Retries", g.Map{
"operation": operationName,
"error": lastErr.Error(),
"max_retries": r.maxRetries,
})
return lastErr
}
// CircuitBreaker 熔断器
type CircuitBreaker struct {
failureCount int
successCount int
failureThreshold int
resetTimeout int64
lastFailureTime int64
state string // "closed", "open", "half-open"
ctx context.Context
}
// NewCircuitBreaker 创建熔断器
func NewCircuitBreaker(ctx context.Context, failureThreshold int, resetTimeout int64) *CircuitBreaker {
return &CircuitBreaker{
failureThreshold: failureThreshold,
resetTimeout: resetTimeout,
state: "closed",
ctx: ctx,
}
}
// Execute 执行操作
func (cb *CircuitBreaker) Execute(operation func() error, operationName string) error {
if cb.state == "open" {
if gtime.Now().Unix()-cb.lastFailureTime > cb.resetTimeout {
cb.state = "half-open"
cb.successCount = 0
g.Log().Info(cb.ctx, "Circuit Breaker Half-Open", g.Map{
"operation": operationName,
"state": cb.state,
})
} else {
return fmt.Errorf("circuit breaker is open for operation: %s", operationName)
}
}
err := operation()
if err != nil {
cb.onFailure(operationName)
return err
}
cb.onSuccess(operationName)
return nil
}
// onSuccess 成功回调
func (cb *CircuitBreaker) onSuccess(operationName string) {
cb.successCount++
if cb.state == "half-open" && cb.successCount >= 3 {
cb.state = "closed"
cb.failureCount = 0
g.Log().Info(cb.ctx, "Circuit Breaker Closed", g.Map{
"operation": operationName,
"state": cb.state,
})
}
}
// onFailure 失败回调
func (cb *CircuitBreaker) onFailure(operationName string) {
cb.failureCount++
cb.lastFailureTime = gtime.Now().Unix()
if cb.failureCount >= cb.failureThreshold {
cb.state = "open"
g.Log().Warning(cb.ctx, "Circuit Breaker Opened", g.Map{
"operation": operationName,
"state": cb.state,
"failure_count": cb.failureCount,
"failure_threshold": cb.failureThreshold,
})
}
}
// GetState 获取熔断器状态
func (cb *CircuitBreaker) GetState() map[string]interface{} {
return map[string]interface{}{
"state": cb.state,
"failure_count": cb.failureCount,
"success_count": cb.successCount,
"failure_threshold": cb.failureThreshold,
"last_failure_time": cb.lastFailureTime,
}
}