diff --git a/gateway/handlers/debug/debug.go b/gateway/handlers/debug/debug.go new file mode 100644 index 00000000..7db355ec --- /dev/null +++ b/gateway/handlers/debug/debug.go @@ -0,0 +1,40 @@ +package debug + +import ( + "expvar" + "net/http" + _ "net/http/pprof" + "strconv" +) + +func Handler() http.Handler { + mux := http.NewServeMux() + + mux.Handle(`GET /vars`, expvar.Handler()) + mux.HandleFunc(`POST /vars/{var}`, func(w http.ResponseWriter, r *http.Request) { + va := expvar.Get(r.PathValue(`var`)) + if va == nil { + http.NotFound(w, r) + return + } + switch typed := va.(type) { + case *expvar.Int: + i, err := strconv.Atoi(r.URL.Query().Get(`v`)) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + typed.Set(int64(i)) + default: + http.Error(w, `unknown var type`, http.StatusBadRequest) + return + } + }) + + mux.HandleFunc(`/pprof/`, func(w http.ResponseWriter, r *http.Request) { + r.URL.Path = `/debug` + r.URL.Path + http.DefaultServeMux.ServeHTTP(w, r) + }) + + return mux +} diff --git a/gateway/main.go b/gateway/main.go index 9e9e4f5c..f275f27d 100644 --- a/gateway/main.go +++ b/gateway/main.go @@ -12,6 +12,7 @@ import ( "github.com/movsb/taoblog/gateway/handlers/apidoc" "github.com/movsb/taoblog/gateway/handlers/assets" "github.com/movsb/taoblog/gateway/handlers/avatar" + "github.com/movsb/taoblog/gateway/handlers/debug" "github.com/movsb/taoblog/gateway/handlers/features" "github.com/movsb/taoblog/gateway/handlers/robots" "github.com/movsb/taoblog/gateway/handlers/rss" @@ -112,6 +113,9 @@ func (g *Gateway) register(ctx context.Context, mux *http.ServeMux) error { // 订阅:rss mc.Handle(`GET /rss`, rss.New(g.auther, g.client, rss.WithArticleCount(10)), g.lastPostTimeHandler) + + // 调试相关 + mc.Handle(`/debug/`, http.StripPrefix(`/debug`, debug.Handler()), g.adminHandler) } return nil @@ -126,3 +130,14 @@ func (g *Gateway) lastPostTimeHandler(h http.Handler) http.Handler { ).ServeHTTP(w, r) }) } + +func (g *Gateway) adminHandler(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ac := auth.Context(r.Context()) + if !ac.User.IsAdmin() { + w.WriteHeader(http.StatusForbidden) + return + } + h.ServeHTTP(w, r) + }) +} diff --git a/service/main.go b/service/main.go index 696af41d..b197ce47 100644 --- a/service/main.go +++ b/service/main.go @@ -4,6 +4,7 @@ import ( "context" "crypto/tls" "database/sql" + "expvar" "fmt" "log" "net" @@ -292,7 +293,14 @@ func grpcLoggerStream(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo grpcLogger(ss.Context(), info.FullMethod) return handler(srv, ss) } + +var enableGrpcLogger = expvar.NewInt(`log.grpc`) + func grpcLogger(ctx context.Context, method string) { + logEnabled := enableGrpcLogger.Value() == 1 + if !logEnabled { + return + } if md, ok := metadata.FromIncomingContext(ctx); ok { log.Println(md) }