144 lines
3.9 KiB
Go
144 lines
3.9 KiB
Go
package main
|
||
|
||
import (
|
||
"backend/common"
|
||
shipcommon "backend/sdk/ship/common"
|
||
minigame "backend/sdk/ship/model/mini_game"
|
||
"backend/sdk/ship/model/test"
|
||
"backend/sdk/ship/model/tuyou"
|
||
"backend/util"
|
||
"context"
|
||
"fmt"
|
||
"io"
|
||
"log"
|
||
"net/http"
|
||
"os"
|
||
"os/signal"
|
||
"syscall"
|
||
"time"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
|
||
)
|
||
|
||
var (
|
||
rl *rotatelogs.RotateLogs
|
||
logWriter io.Writer
|
||
errWriter io.Writer
|
||
)
|
||
|
||
func init() {
|
||
// 确保日志目录存在
|
||
if err := os.MkdirAll("./log", 0755); err != nil {
|
||
log.Fatalf("failed to create log dir: %v", err)
|
||
}
|
||
|
||
// 使用按天轮转的日志文件,保留最近 30 个文件
|
||
var err error
|
||
rl, err = rotatelogs.New(
|
||
"./log/charge.%Y-%m-%d.log",
|
||
rotatelogs.WithRotationTime(24*time.Hour),
|
||
rotatelogs.WithRotationCount(30),
|
||
)
|
||
if err != nil {
|
||
log.Fatalf("failed to initialize log rotator: %v", err)
|
||
}
|
||
|
||
// 打开一个普通的最新日志文件(不使用 symlink),用于提供固定路径的最新日志
|
||
currFile, err := os.OpenFile("./log/charge.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||
if err != nil {
|
||
// 如果打开失败,仍然继续使用轮转器+控制台
|
||
util.LogStructured("warn", "failed to open current log file", map[string]any{"error": err.Error()})
|
||
logWriter = io.MultiWriter(rl, os.Stdout)
|
||
errWriter = io.MultiWriter(rl, os.Stderr)
|
||
} else {
|
||
// 同时输出到轮转日志、固定最新日志文件和控制台
|
||
logWriter = io.MultiWriter(rl, currFile, os.Stdout)
|
||
errWriter = io.MultiWriter(rl, currFile, os.Stderr)
|
||
}
|
||
|
||
log.SetOutput(logWriter)
|
||
|
||
// 保持全局默认 writer(以兼容其他调用)
|
||
gin.DefaultWriter = os.Stdout
|
||
gin.DefaultErrorWriter = errWriter
|
||
|
||
common.Init()
|
||
}
|
||
|
||
func requestLogger() gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
startedAt := time.Now()
|
||
c.Next()
|
||
|
||
util.LogStructured("info", "http request", map[string]any{
|
||
"clientIp": c.ClientIP(),
|
||
"latencyMs": time.Since(startedAt).Milliseconds(),
|
||
"method": c.Request.Method,
|
||
"path": c.Request.URL.Path,
|
||
"query": c.Request.URL.RawQuery,
|
||
"status": c.Writer.Status(),
|
||
"userAgent": c.Request.UserAgent(),
|
||
})
|
||
}
|
||
}
|
||
|
||
func main() {
|
||
// 使用 gin.New 并显式注入写入器,确保中间件把日志写到轮转器
|
||
// gin.SetMode(gin.ReleaseMode)
|
||
r := gin.New()
|
||
r.Use(requestLogger())
|
||
r.Use(gin.RecoveryWithWriter(errWriter))
|
||
|
||
ChargeApi := r.Group("/api")
|
||
{
|
||
// 充值发货
|
||
ChargeApi.POST("test/charge", test.Charge)
|
||
ChargeApi.POST("tuyou/charge", tuyou.Charge)
|
||
//小游戏奖励
|
||
ChargeApi.POST("tuyou/reward", minigame.Reward)
|
||
}
|
||
|
||
server := &http.Server{
|
||
Addr: fmt.Sprintf(":%d", shipcommon.AppConf.Port),
|
||
Handler: r,
|
||
ReadHeaderTimeout: 5 * time.Second,
|
||
ReadTimeout: 15 * time.Second,
|
||
WriteTimeout: 30 * time.Second,
|
||
IdleTimeout: 60 * time.Second,
|
||
}
|
||
|
||
shutdownCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
||
defer stop()
|
||
|
||
serverErr := make(chan error, 1)
|
||
go func() {
|
||
util.LogStructured("info", "ship sdk started", map[string]any{
|
||
"port": shipcommon.AppConf.Port,
|
||
"version": shipcommon.AppConf.Version,
|
||
})
|
||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||
serverErr <- err
|
||
}
|
||
close(serverErr)
|
||
}()
|
||
|
||
select {
|
||
case err, ok := <-serverErr:
|
||
if ok && err != nil {
|
||
util.LogStructured("error", "ship sdk start failed", map[string]any{"error": err.Error()})
|
||
os.Exit(1)
|
||
}
|
||
case <-shutdownCtx.Done():
|
||
util.LogStructured("info", "ship sdk shutting down", map[string]any{"reason": shutdownCtx.Err().Error()})
|
||
}
|
||
|
||
gracefulCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||
defer cancel()
|
||
if err := server.Shutdown(gracefulCtx); err != nil {
|
||
util.LogStructured("error", "ship sdk shutdown failed", map[string]any{"error": err.Error()})
|
||
os.Exit(1)
|
||
}
|
||
util.LogStructured("info", "ship sdk stopped", nil)
|
||
}
|