diff --git a/README.md b/README.md index e73dc2d303b61554d0422c6cf970f138c8ddd56c..3750723c48feb3031a0ae20674ac6878470b58bc 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ go-sage框架,目前自用 -#### 初始化创建示例 +#### 启用多个服务 ``` @@ -37,6 +37,7 @@ func main() { "exampleApp", v1.WithAppOpsLog(logger), //放入logger v1.WithAppOpsServer(server1), //放入一个 server + v1.WithAppOpsServer(server2), ) if err != nil { logger.Fatal(fmt.Sprintf("new app error:%s", err)) @@ -53,3 +54,202 @@ func main() { +#### 添加logger + + + +``` + +app, err := v1.NewApp( + "exampleApp", + v1.WithAppOpsLog(logger), #初始化时设置logger + v1.WithAppOpsStopTimeout(time.Second*5), + v1.WithAppOpsServer(server1), + v1.WithAppOpsServer(server2), + ) + +#也可单独设置logger +app.AddLogger(logger) + +err = app.Run() +if err != nil { +logger.Fatal("app running error: " + err.Error()) +} + +``` + + + + + +#### 一键暂停服务 + +app可调用 Stop 方法直接暂停所有服务 + +``` + + go func() { + time.Sleep(time.Second * 3) + logger.Info("stop server") + app.Stop() + }() + + err = app.Run() + if err != nil { + logger.Fatal("app running error: " + err.Error()) + } + +``` + +并且任意一个服务停止也会触发整体服务暂停 + +``` + + go func() { + time.Sleep(time.Second * 10) + logger.Info("stop server") + server1.Stop() + }() + + err = app.Run() + if err != nil { + logger.Fatal("app running error: " + err.Error()) + } + +``` + + + +#### + + + +#### 支持自定义服务 + +使用包里提供的 WithAppOpsServer(server2) 方法,只要提供的服务符合以下接口就可支持添加 + +``` + +type IServer interface { + Name() string + Run() error + Stop() error +} + +``` + + + +#### 设置 StopTimeout + +设置了 StopTimeout 后,如果服务在超时时间外还未暂停,会强制结束 + +``` +app, err := v1.NewApp( + "exampleApp", + v1.WithAppOpsLog(logger), + v1.WithAppOpsStopTimeout(time.Second*5), #初始化时设置 + v1.WithAppOpsServer(server1), + v1.WithAppOpsServer(server2), + ) +``` + + + + + +### HttpServer + +httpServer负责 http服务器 的启动管理 + + + +#### 直接启动 + +``` + +func main() { + name := "example" + logPath := fmt.Sprintf("./runtime/logs/%s.log", filepath.Base(os.Args[0])) + + logger := v1log.NewZapLog(name, logPath, nil) + httpServer, err := v1http.NewHttpServer("", ":8080") + if err != nil { + logger.Error("run http server error:%s" + err.Error()) + return + } + //添加logger + httpServer.AddLogger(logger) + + logger.Fatal(httpServer.Run().Error()) +} +``` + +#### 注册路由 + +路由方法需要是以下的类型 + +``` +func(ctx *Ctx) +``` + + + +##### GET/POST/DELETE/OPTION/PUT 路由 + +``` + //注册简单的路由 + httpServer.RouteGet("/v1/users", api.Users, nil) + httpServer.RoutePost("/v1/exception", api.Exception, nil) + httpServer.RouteOptions("/v1/exception", api.Exception, nil) + httpServer.RouteDelete("/v1/exception", api.Exception, nil) + httpServer.RoutePut("/v1/exception", api.Exception, nil) + +``` + + + +##### 静态文件请求 + +``` +# +httpServer.RouteFiles("/static", http.Dir("public")) +``` + + + +##### 请求处理 + +``` +//直接使用 write 返回 +func (h *ApiHandler) Index(ctx *v1http.Ctx) { + ctx.Write([]byte("Hello World")) +} + +//使用内置的返回格式 +func (h *ApiHandler) Users(ctx *v1http.Ctx) { + users := []map[string]interface{}{ + {"uid": 1, "username": "jack"}, + {"uid": 2, "username": "lucy"}, + } + ctx.Data(users) + ctx.Msg("success") + ctx.Response() +} + +#自定义返回状态 +func (h *ApiHandler) Exception(ctx *v1http.Ctx) { + ctx.WriteHeader(500) + ctx.Response() +} + +``` + + + +#### 中间件(待完善) + + + + + diff --git a/examples/run_app.go b/examples/run_app.go index bbd9dd6b4c7a4ae94a6a40501aed7895e4f3e51f..770838e7ca8a8f2191fc5f3edad8cb03d4c2c21f 100644 --- a/examples/run_app.go +++ b/examples/run_app.go @@ -40,6 +40,12 @@ func main() { return } + go func() { + time.Sleep(time.Second * 10) + logger.Info("stop server") + server1.Stop() + }() + err = app.Run() if err != nil { logger.Fatal("app running error: " + err.Error()) @@ -64,7 +70,7 @@ func getHttpServer(logger v1log.ILog) *v1http.HttpServer { func getJobServer(logger v1log.ILog) *v1job.Job { //创建一个job job := v1job.NewJob("printX", func() { - logger.Info("job: " + time.Now().Format(miscs.TimeLayout)) + logger.Info("job: " + time.Now().Format(miscs.DateTimeLayout)) }) job.SetCoNum(2) job.AddLogger(logger) @@ -73,7 +79,7 @@ func getJobServer(logger v1log.ILog) *v1job.Job { func getJobScheduler(logger v1log.ILog) *v1job.JobScheduler { job := v1job.NewJob("", func() { - logger.Info("job: " + time.Now().Format(miscs.TimeLayout)) + logger.Info("job: " + time.Now().Format(miscs.DateTimeLayout)) }) //创建一个scheduler diff --git a/examples/run_app_stop.go b/examples/run_app_stop.go index fe2f3171099cd69a82b99bb685980732085cd4af..e95c38082835194c86cf59107f3529e5d1b5348c 100644 --- a/examples/run_app_stop.go +++ b/examples/run_app_stop.go @@ -33,7 +33,9 @@ func main() { go func() { time.Sleep(time.Second * 3) logger.Info("stop server") - server1.Stop() + //server1.Stop() + + app.Stop() }() err = app.Run() @@ -55,7 +57,7 @@ func getHttpServer(logger v1log.ILog, addr string) *v1http.HttpServer { }, []v1http.Middleware{}) httpServer.RouteGet("/v1/panic", func(ctx *v1http.Ctx) { - panic("trigger panic " + time.Now().Format(miscs.TimeLayout)) + panic("trigger panic " + time.Now().Format(miscs.DateTimeLayout)) }, []v1http.Middleware{}) return httpServer diff --git a/examples/run_httpserver.go b/examples/run_httpserver.go index b5daa52dcc196986a9769a179f2fc2977c21bc20..9ad922ea8dc96a4813e5ed2cde876abc53fb1f64 100644 --- a/examples/run_httpserver.go +++ b/examples/run_httpserver.go @@ -29,7 +29,10 @@ func main() { //使用json返回 httpServer.RouteGet("/v1/users", api.Users, nil) - httpServer.RouteGet("/v1/exception", api.Exception, nil) + httpServer.RoutePost("/v1/exception", api.Exception, nil) + httpServer.RouteOptions("/v1/exception", api.Exception, nil) + httpServer.RouteDelete("/v1/exception", api.Exception, nil) + httpServer.RoutePut("/v1/exception", api.Exception, nil) httpServer.RouteFiles("/static", http.Dir("public")) logger.Fatal(httpServer.Run().Error()) @@ -48,8 +51,8 @@ func (h *ApiHandler) Users(ctx *v1http.Ctx) { {"uid": 1, "username": "jack"}, {"uid": 2, "username": "lucy"}, } - ctx.Data(users) - ctx.Msg("success") + ctx.SetData(users) + ctx.SetMsg("success") ctx.Response() } diff --git a/examples/run_httpserver_middleware.go b/examples/run_httpserver_middleware.go index ab17d3b4e93220e4793489fe2c2c41ff744f38d2..4e3f7c63013d2b9bd19ad521d4f2a083b13675ef 100644 --- a/examples/run_httpserver_middleware.go +++ b/examples/run_httpserver_middleware.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "gitee.com/scottq/go-framework/src/utils" v1http "gitee.com/scottq/go-framework/src/v1/httpserver" v1log "gitee.com/scottq/go-framework/src/v1/log" "net/http" @@ -26,6 +27,7 @@ func main() { //注册简单的路由 httpServer.RouteGet("/v1", Index, []v1http.Middleware{ + RequestIdMiddleware, ResponseMiddleware, }) @@ -34,40 +36,49 @@ func main() { //http router func Index(ctx *v1http.Ctx) { - ctx.Msg("self defined response") - ctx.Data(map[string]interface{}{}) + ctx.SetMsg("self defined response") + ctx.SetData(map[string]interface{}{}) ctx.Response() } +//中间件中设置 添加 RequestId +var RequestIdMiddleware v1http.Middleware = func(ctx *v1http.Ctx, next func(*v1http.Ctx)) { + ctx.WithValue("RequestId", utils.NewRequestId()) + next(ctx) +} + //中间件中设置 自定义response处理器 var ResponseMiddleware v1http.Middleware = func(ctx *v1http.Ctx, next func(*v1http.Ctx)) { - ctx.SetResponseHandler(NewResponseHandler(ctx.Writer())) + requestId := ctx.Value("RequestId").(string) + ctx.SetResponseHandler(NewResponseHandler(ctx.Writer(), requestId)) next(ctx) } +//自定义的返回格式 type DefinedResponse struct { data map[string]interface{} writer http.ResponseWriter } -func NewResponseHandler(writer http.ResponseWriter) *DefinedResponse { +func NewResponseHandler(writer http.ResponseWriter, requestId string) *DefinedResponse { return &DefinedResponse{ data: map[string]interface{}{ - "time": time.Now().UnixNano(), + "time": time.Now().UnixNano(), + "requestId": requestId, }, writer: writer, } } -func (resp *DefinedResponse) Code(code int64) { +func (resp *DefinedResponse) SetCode(code int64) { resp.data["code"] = code } -func (resp *DefinedResponse) Msg(msg string) { +func (resp *DefinedResponse) SetMsg(msg string) { resp.data["message"] = msg } -func (resp *DefinedResponse) Data(data interface{}) { +func (resp *DefinedResponse) SetData(data interface{}) { resp.data["data"] = data } diff --git a/examples/run_job_mix.go b/examples/run_job_mix.go index bb21635dd846b2b27d09be3b616ecb9b3d50d49e..c08986c6ecda3177195bda551cb4d7779a840608 100644 --- a/examples/run_job_mix.go +++ b/examples/run_job_mix.go @@ -11,7 +11,7 @@ func main() { //第一个job(5秒后执行结束) job := v1job.NewJob("printX", func() { for i := 0; i <= 10; i++ { - println("job", i, time.Now().Format(miscs.TimeLayout)) + println("job", i, time.Now().Format(miscs.DateTimeLayout)) time.Sleep(time.Millisecond * 500) } }) @@ -19,7 +19,7 @@ func main() { //第二个job(定时执行的,每秒执行) sch := v1job.NewJobScheduler("scheduler", time.Second, v1job.NewJob("printX", func() { - println("scheduler", time.Now().Format(miscs.TimeLayout)) + println("scheduler", time.Now().Format(miscs.DateTimeLayout)) })) runner := v1job.NewJobRunner("mixJobs") @@ -27,13 +27,13 @@ func main() { runner.AddJob(sch) //只执行一次 runner.AddExecute("printTime", func() { - println("executor", time.Now().Format(miscs.TimeLayout)) + println("executor", time.Now().Format(miscs.DateTimeLayout)) }) //15秒后手动停止定时任务 go func() { time.Sleep(time.Second * 15) - println("stop scheduler", time.Now().Format(miscs.TimeLayout)) + println("stop scheduler", time.Now().Format(miscs.DateTimeLayout)) sch.Stop() }() diff --git a/examples/run_job_runner.go b/examples/run_job_runner.go index 2262ac75d352512dd52d96a44f4e374c41653eae..61b009e9ba13597f269f16c093b8174a46c150d9 100644 --- a/examples/run_job_runner.go +++ b/examples/run_job_runner.go @@ -21,7 +21,7 @@ func main() { jobRunner.AddJob(job) //添加job jobRunner.AddExecute("printTime", func() { for i := 0; i <= 10; i++ { - println(time.Now().Format(miscs.TimeLayout)) + println(time.Now().Format(miscs.DateTimeLayout)) time.Sleep(time.Second) } }) //添加自定义执行job diff --git a/examples/run_job_scheduler.go b/examples/run_job_scheduler.go index 1de9efe33ea921deec99a794e2c8e6200c96dfe0..1c7c58f6fe9a3270f120f68af984be2d20cc59c6 100644 --- a/examples/run_job_scheduler.go +++ b/examples/run_job_scheduler.go @@ -10,7 +10,7 @@ func main() { //创建一个job job := v1job.NewJob("printX", func() { - println(time.Now().Format(miscs.TimeLayout)) + println(time.Now().Format(miscs.DateTimeLayout)) }) job.SetCoNum(2) @@ -19,7 +19,7 @@ func main() { go func() { time.Sleep(time.Second * 10) - println("stop scheduler", time.Now().Format(miscs.TimeLayout)) + println("stop scheduler", time.Now().Format(miscs.DateTimeLayout)) sch.Stop() }() diff --git a/go.mod b/go.mod index f3a24d34f2b941b74ba9c41565c26384bdf9e26f..0c93d2d2e639e334db97cef715a844bd3a369680 100644 --- a/go.mod +++ b/go.mod @@ -7,5 +7,6 @@ require ( github.com/natefinch/lumberjack v2.0.0+incompatible github.com/satori/go.uuid v1.2.0 go.uber.org/zap v1.16.0 + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect ) diff --git a/go.sum b/go.sum index b82c732cdc6f08fc12d76f72a3a9435e5b68a50e..fbedd2e61bc3d56f312d32fdaf9937d21bcdbcad 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= diff --git a/src/miscs/const.go b/src/miscs/const.go index 477dbd49d0fa23a936e5fe4a631f345cecf0ec6e..d5deb4e195fa215fdf7c4740f267364bcdef88c5 100644 --- a/src/miscs/const.go +++ b/src/miscs/const.go @@ -1,6 +1,6 @@ package miscs -const TimeLayout = "2006-01-02 15:04:05" -const DateTimeLayout = "2006-01-02" -const TimeTimeLayout = "15:04:05" \ No newline at end of file +const DateTimeLayout = "2006-01-02 15:04:05" +const DateLayout = "2006-01-02" +const TimeLayout = "15:04:05" \ No newline at end of file diff --git a/src/v1/app.go b/src/v1/app.go index 662d13cb7633298c6f4235717ccff1f8112f6e06..fd5bfe85fca63ba0237cfbb9a2dbc10721061ee2 100644 --- a/src/v1/app.go +++ b/src/v1/app.go @@ -106,6 +106,10 @@ func (app *App) runServer(server IServer, ch chan<- error) { return } +func (app *App) Stop() { + app.stop() +} + func (app *App) stop() { if len(app.servers) == 0 { return diff --git a/src/v1/httpserver/server_config.go b/src/v1/httpserver/server_config.go new file mode 100644 index 0000000000000000000000000000000000000000..9eb4748167383d3882b322c735328dfb9761674a --- /dev/null +++ b/src/v1/httpserver/server_config.go @@ -0,0 +1,15 @@ +package httpserver + +type ServerOps = func(*HttpServer) + +type ServerConfig struct { + requestId bool + requestIdField string +} + +var WithOpsRequestId = func(requestIdField string) ServerOps { + return func(server *HttpServer) { + server.config.requestId = requestIdField != "" + server.config.requestIdField = requestIdField + } +} diff --git a/src/v1/httpserver/server_http.go b/src/v1/httpserver/server_http.go index 2f3911c571f8307e133998051a793ae9742158ee..96bd00d90a603a98f4013ee2ab45f09f6ac8d17b 100644 --- a/src/v1/httpserver/server_http.go +++ b/src/v1/httpserver/server_http.go @@ -16,17 +16,25 @@ type HttpServer struct { rHandler *httprouter.Router server *http.Server + config *ServerConfig + log.InvokeLog } -func NewHttpServer(name string, addr string) (*HttpServer, error) { + +func NewHttpServer(name string, addr string, ops ...ServerOps) (*HttpServer, error) { server := &HttpServer{ name: name, listenAdd: addr, routers: []*Router{}, + config: &ServerConfig{}, rHandler: httprouter.New(), } + for i, _ := range ops { + ops[i](server) + } + //register health router server.DefaultRouteHealth() @@ -105,7 +113,7 @@ func (s *HttpServer) initRouter() error { } for _, x := range routers { - x.invokeRegister(s.rHandler) + x.invokeRegister(s.rHandler,s.config) } return nil } diff --git a/src/v1/httpserver/server_http_ctx.go b/src/v1/httpserver/server_http_ctx.go index 6a112353406ec14ecf0abf7ad9129cc7efc486cd..10977f438181adf153b8f7e5f3a8b226e88af70e 100644 --- a/src/v1/httpserver/server_http_ctx.go +++ b/src/v1/httpserver/server_http_ctx.go @@ -2,8 +2,10 @@ package httpserver import ( "context" + "encoding/json" "github.com/julienschmidt/httprouter" "net/http" + "net/url" ) type Ctx struct { @@ -32,6 +34,43 @@ func (ctx *Ctx) _setRouterParams(params httprouter.Params) { ctx.routerParams = params } +func (ctx *Ctx) Context() context.Context { + return ctx.httpContext +} + +func (ctx *Ctx) WithValue(key, val interface{}) { + ctx.httpContext = context.WithValue(ctx.httpContext, key, val) +} + +func (ctx *Ctx) Form() url.Values { + r := ctx.request + + contentType := r.Header.Get("Content-Type") + + form := url.Values{} + switch contentType { + case "application/json": + var fm map[string]string + + decoder := json.NewDecoder(r.Body) + decoder.Decode(&fm) + + for k, v := range fm { + form.Add(k, v) + } + + default: + r.ParseForm() + form = r.Form + } + + return form +} + +func (ctx *Ctx) Value(key interface{}) interface{} { + return ctx.httpContext.Value(key) +} + func (ctx *Ctx) SetResponseHandler(response IHttpResponse) { ctx.IHttpResponse = response } diff --git a/src/v1/httpserver/server_http_response.go b/src/v1/httpserver/server_http_response.go index a11eb2db1d3a107c07524fb09f12329ac03e503d..cdd5cea1d340a39de2b3c845f0b4364a783a9edb 100644 --- a/src/v1/httpserver/server_http_response.go +++ b/src/v1/httpserver/server_http_response.go @@ -6,9 +6,9 @@ import ( ) type IHttpResponse interface { - Code(code int64) - Msg(msg string) - Data(data interface{}) + SetCode(code int64) + SetMsg(msg string) + SetData(data interface{}) Response() } @@ -41,15 +41,15 @@ func NewHttpResponse(writer http.ResponseWriter) IHttpResponse { } } -func (resp *HttpResponse) Code(code int64) { +func (resp *HttpResponse) SetCode(code int64) { resp.respData.Code = code } -func (resp *HttpResponse) Msg(msg string) { +func (resp *HttpResponse) SetMsg(msg string) { resp.respData.Msg = msg } -func (resp *HttpResponse) Data(data interface{}) { +func (resp *HttpResponse) SetData(data interface{}) { resp.respData.Data = data } diff --git a/src/v1/httpserver/server_http_router.go b/src/v1/httpserver/server_http_router.go index 3abe2b57335c4fccc60fb240afb6233e28657892..66776ed27d99716d7a7b6b9d2883dd6804a1ff79 100644 --- a/src/v1/httpserver/server_http_router.go +++ b/src/v1/httpserver/server_http_router.go @@ -1,6 +1,8 @@ package httpserver import ( + "context" + "gitee.com/scottq/go-framework/src/utils" "github.com/julienschmidt/httprouter" "net/http" "strings" @@ -19,8 +21,8 @@ func (r *Router) hash() string { return r.Method + "_" + r.Path } -func (r *Router) invokeRegister(router *httprouter.Router) { - handler := r.handler() +func (r *Router) invokeRegister(router *httprouter.Router, c *ServerConfig) { + handler := r.handler(c) if handler != nil { switch strings.ToUpper(r.Method) { case "GET": @@ -37,13 +39,20 @@ func (r *Router) invokeRegister(router *httprouter.Router) { } } -func (r *Router) handler() func(http.ResponseWriter, *http.Request, httprouter.Params) { +func (r *Router) handler(c *ServerConfig) func(http.ResponseWriter, *http.Request, httprouter.Params) { + + genCtx := func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) *Ctx { + ctx := NewCtx(writer, request) + ctx._setRouterParams(params) + if c.requestId { + ctx.httpContext = context.WithValue(ctx.httpContext, c.requestIdField, utils.NewRequestId()) + } + return ctx + } if r.HttpHandler != nil { return func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { - - ctx := NewCtx(writer, request) - ctx._setRouterParams(params) + ctx := genCtx(writer, request, params) handlerMiddleware(func(ctx *Ctx) { r.HttpHandler.ServeHTTP(writer, request) @@ -53,8 +62,7 @@ func (r *Router) handler() func(http.ResponseWriter, *http.Request, httprouter.P if r.RouteHandler != nil { return func(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { - ctx := NewCtx(writer, request) - ctx._setRouterParams(params) + ctx := genCtx(writer, request, params) handlerMiddleware(r.RouteHandler, r.Middleware)(ctx) } diff --git a/src/v1/httpserver/vars.go b/src/v1/httpserver/vars.go new file mode 100644 index 0000000000000000000000000000000000000000..0194bdacb7a657a5118dc80ff3a897790802540f --- /dev/null +++ b/src/v1/httpserver/vars.go @@ -0,0 +1,104 @@ +package httpserver + +import ( + "context" + "gitee.com/scottq/go-framework/src/utils" + "golang.org/x/time/rate" + "net/http" + "runtime/debug" +) + +//qps限流 +var GlobalMiddlewareQPSLimiter = func(r rate.Limit, b int) Middleware { + limiter := rate.NewLimiter(r, b) + return func(ctx *Ctx, next func(ctx *Ctx)) { + if !limiter.Allow() { + ctx.writer.WriteHeader(http.StatusNoContent) + return + } + + next(ctx) + } +} + +//panic处理 +var GlobalMiddlewarePanic Middleware = func(ctx *Ctx, next func(*Ctx)) { + defer func() { + if err := recover(); err != nil { + debug.PrintStack() + ctx.WriteHeader(http.StatusInternalServerError) + ctx.Response() + return + } + }() + next(ctx) +} + +//添加requestId +var GlobalMiddlewareAddRequestId = func(requestIdField string) Middleware { + return func(ctx *Ctx, next func(*Ctx)) { + + //添加requestId + c := context.WithValue(ctx.request.Context(), requestIdField, utils.NewRequestId()) + ctx.request = ctx.request.WithContext(c) + + next(ctx) + } +} + +//OPTION请求过滤 +var GlobalMiddlewareOptionRequest Middleware = func(ctx *Ctx, next func(*Ctx)) { + if ctx.request.Method == "OPTIONS" { + ctx.writer.WriteHeader(http.StatusNoContent) + return + } + next(ctx) +} + +//跨域资源请求 +var GlobalMiddlewareCorsMiddleware = func(domainWhites []string) Middleware { + return func(ctx *Ctx, next func(*Ctx)) { + allow := false + + //跨域设置 + if origin := ctx.request.Header.Get("Origin"); origin != "" { + if domainWhites == nil { + allow = true + } else { + for _, white := range domainWhites { + if white == origin { + allow = true + break + } + } + } + if allow { + ctx.writer.Header().Set("Access-Control-Allow-Origin", origin) + } + } + ctx.writer.Header().Set("Access-Control-Allow-Credentials", "true") + ctx.writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") + ctx.writer.Header().Set("Access-Control-Allow-Headers", "Content-type,Authorization,x-requested-with,Request-Service") + + next(ctx) + } +} + +const limiterR = 100 +const limiterInit = 100 +const requestIdFiled = "RequestId" + +var BaseMiddlewareArr = []Middleware{ + GlobalMiddlewarePanic, + GlobalMiddlewareAddRequestId(requestIdFiled), + GlobalMiddlewareCorsMiddleware(nil), + GlobalMiddlewareOptionRequest, +} + +var HealthMiddlewareArr = []Middleware{ + GlobalMiddlewarePanic, + GlobalMiddlewareAddRequestId(requestIdFiled), + GlobalMiddlewareCorsMiddleware(nil), + GlobalMiddlewareOptionRequest, + GlobalMiddlewareQPSLimiter(limiterR, limiterInit), +} diff --git a/src/v1/log/log_default.go b/src/v1/log/log_default.go index 2b0a79a7fff791a39f94ab811f52a013bc6ac687..5278823accc58a579d57b20980cad8442a36bd62 100644 --- a/src/v1/log/log_default.go +++ b/src/v1/log/log_default.go @@ -97,7 +97,7 @@ func (logger *MyLogger) LogPath() string { var parseT time.Time parseT = time.Now() - t := parseT.Format(miscs.DateTimeLayout) + t := parseT.Format(miscs.DateLayout) return fmt.Sprintf("%s-%s.log", p[:len(p)-len(".log")], t) }