Files
platform/web/web.go

172 lines
3.5 KiB
Go

package web
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/fiber/v2/middleware/requestid"
"github.com/google/uuid"
"github.com/jxskiss/base62"
"log/slog"
"net/http"
_ "net/http/pprof"
"platform/web/auth"
"platform/web/core"
g "platform/web/globals"
m "platform/web/models"
q "platform/web/queries"
"runtime"
"strconv"
"strings"
"time"
)
// region web
type Config struct {
Listen string
}
type Server struct {
config *Config
fiber *fiber.App
}
func New(config *Config) (*Server, error) {
_config := config
if config == nil {
_config = &Config{}
}
return &Server{
config: _config,
}, nil
}
func (s *Server) Run() error {
// inits
g.InitBaiyin()
g.InitAlipay()
g.InitWechatPay()
g.InitAliyun()
g.InitValidator()
// config
s.fiber = fiber.New(fiber.Config{
ProxyHeader: fiber.HeaderXForwardedFor,
ErrorHandler: ErrorHandler,
})
// middlewares
s.fiber.Use(useRequestId())
s.fiber.Use(useLogger())
// routes
ApplyRouters(s.fiber)
// pprof
go func() {
runtime.SetBlockProfileRate(1)
err := http.ListenAndServe(":6060", nil)
if err != nil {
slog.Error("pprof 服务错误", slog.Any("err", err))
}
}()
// listen
slog.Info("Server started on :8080")
err := s.fiber.Listen(":8080")
if err != nil {
slog.Error("Failed to start server", slog.Any("err", err))
}
slog.Info("Server stopped")
return nil
}
func (s *Server) Stop() {
err := s.fiber.Shutdown()
if err != nil {
slog.Error("Failed to shutdown server", slog.Any("err", err))
}
}
// endregion
// region requestid
func useRequestId() fiber.Handler {
return requestid.New(requestid.Config{
Generator: func() string {
binary, _ := uuid.New().MarshalBinary()
return base62.EncodeToString(binary)
},
})
}
// endregion
// region logger
func useLogger() fiber.Handler {
return logger.New(logger.Config{
DisableColors: true,
Format: "🚀 ${time} | ${locals:authtype} ${locals:authid} | ${method} ${path} | ${status} | ${latency} | ${error}\n",
TimeFormat: "2006-01-02 15:04:05",
TimeZone: "Asia/Shanghai",
Next: func(c *fiber.Ctx) bool {
c.Locals("authtype", auth.PayloadNone.ToStr())
c.Locals("authid", 0)
return false
},
Done: func(c *fiber.Ctx, logBytes []byte) {
var logStr = strings.TrimPrefix(string(logBytes), "🚀")
var logVars = strings.Split(logStr, "|")
var reqTimeStr = strings.TrimSpace(logVars[0])
reqTime, err := time.ParseInLocation("2006-01-02 15:04:05", reqTimeStr, time.Local)
if err != nil {
slog.Error("时间解析错误", slog.Any("err", err))
return
}
var authInfo = strings.Split(strings.TrimSpace(logVars[1]), " ")
var authType = auth.PayloadTypeFromStr(strings.TrimSpace(authInfo[0]))
authID, err := strconv.Atoi(strings.TrimSpace(authInfo[1]))
if err != nil {
slog.Error("负载ID解析错误", slog.Any("err", err))
return
}
var latency = strings.TrimSpace(logVars[4])
var errStr = strings.TrimSpace(logVars[5])
var item = &m.LogsRequest{
IP: c.IP(),
Ua: c.Get("User-Agent"),
Method: c.Method(),
Path: c.Path(),
Latency: latency,
Status: int32(c.Response().StatusCode()),
Error: errStr,
Time: core.LocalDateTime(reqTime),
}
if authType != auth.PayloadNone {
item.Identity = int32(authType)
}
if authID != 0 {
item.Visitor = int32(authID)
}
err = q.LogsRequest.Create(item)
if err != nil {
slog.Error("日志记录错误", slog.Any("err", err))
return
}
},
})
}
// endregion