diff --git a/context.go b/context.go index 6cb6a07..718ba94 100644 --- a/context.go +++ b/context.go @@ -14,6 +14,7 @@ import ( "strings" "sync" + "github.com/fenthope/reco" "github.com/go-json-experiment/json" "github.com/WJQSERVER-STUDIO/go-utils/copyb" @@ -468,8 +469,7 @@ func (c *Context) ErrorUseHandle(code int) { c.Abort() return } else { - // Default error handling if no custom handler is set - c.String(code, http.StatusText(code)) + c.String(code, "%s", http.StatusText(code)) c.Abort() } } @@ -478,3 +478,13 @@ func (c *Context) ErrorUseHandle(code int) { func (c *Context) GetProtocol() string { return c.Request.Proto } + +// GetHTTPC 获取框架自带传递的httpc +func (c *Context) GetHTTPC() *httpc.Client { + return c.HTTPClient +} + +// GetLogger 获取engine的Logger +func (c *Context) GetLogger() *reco.Logger { + return c.engine.LogReco +} diff --git a/engine.go b/engine.go index b97e90d..0d58bd1 100644 --- a/engine.go +++ b/engine.go @@ -13,6 +13,7 @@ import ( "sync" "github.com/WJQSERVER-STUDIO/httpc" + "github.com/fenthope/reco" ) // Last 返回链中的最后一个处理函数。 @@ -45,6 +46,8 @@ type Engine struct { HTTPClient *httpc.Client // 用于在此上下文中执行出站 HTTP 请求。 + LogReco *reco.Logger + HTMLRender interface{} // 用于 HTML 模板渲染,可以设置为 *template.Template 或自定义渲染器接口 routesInfo []RouteInfo // 存储所有注册的路由信息 @@ -139,6 +142,7 @@ func New() *Engine { } //engine.SetProtocols(GetDefaultProtocolsConfig()) engine.SetDefaultProtocols() + engine.SetLogger(defaultLogRecoConfig) // 初始化 Context Pool,为每个新 Context 实例提供一个构造函数 engine.pool.New = func() interface{} { return &Context{ @@ -164,6 +168,11 @@ func Default() *Engine { // === 外部操作方法 === +// 配置日志Logger +func (engine *Engine) SetLogger(logcfg reco.Config) { + engine.LogReco = NewLogger(logcfg) +} + // 设置自定义错误处理 func (engine *Engine) SetErrorHandler(handler ErrorHandler) { engine.errorHandle.useDefault = false diff --git a/go.mod b/go.mod index 239260c..58e1acc 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.24.3 require ( github.com/WJQSERVER-STUDIO/go-utils/copyb v0.0.4 github.com/WJQSERVER-STUDIO/httpc v0.5.1 + github.com/fenthope/reco v0.0.1 github.com/go-json-experiment/json v0.0.0-20250517221953-25912455fbc8 github.com/gorilla/websocket v1.5.3 ) diff --git a/go.sum b/go.sum index 7d9a3dd..69661e4 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/WJQSERVER-STUDIO/go-utils/copyb v0.0.4 h1:JLtFd00AdFg/TP+dtvIzLkdHwKU github.com/WJQSERVER-STUDIO/go-utils/copyb v0.0.4/go.mod h1:FZ6XE+4TKy4MOfX1xWKe6Rwsg0ucYFCdNh1KLvyKTfc= github.com/WJQSERVER-STUDIO/httpc v0.5.1 h1:+TKCPYBuj7PAHuiduGCGAqsHAa4QtsUfoVwRN777q64= github.com/WJQSERVER-STUDIO/httpc v0.5.1/go.mod h1:M7KNUZjjhCkzzcg9lBPs9YfkImI+7vqjAyjdA19+joE= +github.com/fenthope/reco v0.0.1 h1:GYcuXCEKYoctD0dFkiBC+t0RMTOyOiujBCin8bbLR3Y= +github.com/fenthope/reco v0.0.1/go.mod h1:mDkGLHte5udWTIcjQTxrABRcf56SSdxBOCLgrRDwI/Y= github.com/go-json-experiment/json v0.0.0-20250517221953-25912455fbc8 h1:o8UqXPI6SVwQt04RGsqKp3qqmbOfTNMqDrWsc4O47kk= github.com/go-json-experiment/json v0.0.0-20250517221953-25912455fbc8/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= diff --git a/logreco.go b/logreco.go new file mode 100644 index 0000000..290778f --- /dev/null +++ b/logreco.go @@ -0,0 +1,34 @@ +package touka + +import ( + "log" + "os" + + "github.com/fenthope/reco" +) + +// 默认LogReco配置 +var defaultLogRecoConfig = reco.Config{ + Level: reco.LevelInfo, + Mode: reco.ModeText, + Output: os.Stdout, + Async: true, + DefaultFields: nil, +} + +func NewLogger(logcfg reco.Config) *reco.Logger { + logger, err := reco.New(logcfg) + if err != nil { + log.Printf("New Logreco Error: %s", err) + return nil + } + return logger +} + +func CloseLogger(logger *reco.Logger) { + err := logger.Close() + if err != nil { + log.Printf("Close Logreco Error: %s", err) + return + } +} diff --git a/serve.go b/serve.go index ecda82b..ab4aec3 100644 --- a/serve.go +++ b/serve.go @@ -13,6 +13,8 @@ import ( "sync" "syscall" "time" + + "github.com/fenthope/reco" ) const defaultShutdownTimeout = 5 * time.Second // 定义默认的优雅关闭超时时间 @@ -55,12 +57,17 @@ func getShutdownTimeout(timeouts []time.Duration) time.Duration { // handleGracefulShutdown 处理一个或多个 http.Server 实例的优雅关闭。 // 它监听操作系统信号,并在指定超时时间内尝试关闭所有服务器。 -func handleGracefulShutdown(servers []*http.Server, timeout time.Duration) error { +func handleGracefulShutdown(servers []*http.Server, timeout time.Duration, logger *reco.Logger) error { quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("Shutting down Touka server(s)...") + go func() { + log.Println("Touka Logger Clossing...") + CloseLogger(logger) + }() + ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -116,7 +123,7 @@ func (engine *Engine) RunShutdown(addr string, timeouts ...time.Duration) error } }() - return handleGracefulShutdown([]*http.Server{srv}, timeout) + return handleGracefulShutdown([]*http.Server{srv}, timeout, engine.LogReco) } // RunWithTLS 启动 HTTPS 服务器并支持优雅关闭。 @@ -152,7 +159,7 @@ func (engine *Engine) RunWithTLS(addr string, tlsConfig *tls.Config, timeouts .. } }() - return handleGracefulShutdown([]*http.Server{srv}, timeout) + return handleGracefulShutdown([]*http.Server{srv}, timeout, engine.LogReco) } // RunWithTLSRedir 启动 HTTP 和 HTTPS 服务器,并将所有 HTTP 请求重定向到 HTTPS。 @@ -227,5 +234,5 @@ func (engine *Engine) RunWithTLSRedir(httpAddr, httpsAddr string, tlsConfig *tls } }() - return handleGracefulShutdown([]*http.Server{httpsSrv, httpSrv}, timeout) + return handleGracefulShutdown([]*http.Server{httpsSrv, httpSrv}, timeout, engine.LogReco) }