aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kosov <rusyak777@list.ru>2025-05-21 17:57:39 +0300
committerGitHub <noreply@github.com>2025-05-21 07:57:39 -0700
commit5182d46e22d2458b16f1f2fb0358f6b5f3e18b5d (patch)
tree1f95adace7c8954512150f205005a347aff3653b
parent140b7a7402109a55072458e42a32bc1ef4a608a9 (diff)
downloadseaweedfs-5182d46e22d2458b16f1f2fb0358f6b5f3e18b5d.tar.xz
seaweedfs-5182d46e22d2458b16f1f2fb0358f6b5f3e18b5d.zip
Added middleware for processing request_id grpc and http requests (#6805)
-rw-r--r--weed/pb/grpc_client_server.go26
-rw-r--r--weed/server/common.go21
-rw-r--r--weed/server/filer_server.go8
-rw-r--r--weed/server/master_server.go24
-rw-r--r--weed/server/volume_server.go10
-rw-r--r--weed/util/request_id.go20
6 files changed, 88 insertions, 21 deletions
diff --git a/weed/pb/grpc_client_server.go b/weed/pb/grpc_client_server.go
index 777dfb402..ba0d7d0cc 100644
--- a/weed/pb/grpc_client_server.go
+++ b/weed/pb/grpc_client_server.go
@@ -3,6 +3,7 @@ package pb
import (
"context"
"fmt"
+ "github.com/google/uuid"
"google.golang.org/grpc/metadata"
"math/rand/v2"
"net/http"
@@ -58,6 +59,7 @@ func NewGrpcServer(opts ...grpc.ServerOption) *grpc.Server {
}),
grpc.MaxRecvMsgSize(Max_Message_Size),
grpc.MaxSendMsgSize(Max_Message_Size),
+ grpc.UnaryInterceptor(requestIDUnaryInterceptor()),
)
for _, opt := range opts {
if opt != nil {
@@ -118,6 +120,30 @@ func getOrCreateConnection(address string, waitForReady bool, opts ...grpc.DialO
return vgc, nil
}
+func requestIDUnaryInterceptor() grpc.UnaryServerInterceptor {
+ return func(
+ ctx context.Context,
+ req interface{},
+ info *grpc.UnaryServerInfo,
+ handler grpc.UnaryHandler,
+ ) (interface{}, error) {
+ md, _ := metadata.FromIncomingContext(ctx)
+ idList := md.Get(util.RequestIDKey)
+ var reqID string
+ if len(idList) > 0 {
+ reqID = idList[0]
+ }
+ if reqID == "" {
+ reqID = uuid.New().String()
+ }
+
+ ctx = util.WithRequestID(ctx, reqID)
+ grpc.SetTrailer(ctx, metadata.Pairs(util.RequestIDKey, reqID))
+
+ return handler(ctx, req)
+ }
+}
+
// WithGrpcClient In streamingMode, always use a fresh connection. Otherwise, try to reuse an existing connection.
func WithGrpcClient(streamingMode bool, signature int32, fn func(*grpc.ClientConn) error, address string, waitForReady bool, opts ...grpc.DialOption) error {
diff --git a/weed/server/common.go b/weed/server/common.go
index 5dad9d81b..516f8bf1c 100644
--- a/weed/server/common.go
+++ b/weed/server/common.go
@@ -3,9 +3,12 @@ package weed_server
import (
"bufio"
"bytes"
+ "context"
"encoding/json"
"errors"
"fmt"
+ "github.com/google/uuid"
+ "google.golang.org/grpc/metadata"
"io"
"io/fs"
"mime/multipart"
@@ -421,3 +424,21 @@ func ProcessRangeRequest(r *http.Request, w http.ResponseWriter, totalSize int64
}
return nil
}
+
+func requestIDMiddleware(h http.HandlerFunc) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ reqID := r.Header.Get(util.RequestIdHttpHeader)
+ if reqID == "" {
+ reqID = uuid.New().String()
+ }
+
+ ctx := context.WithValue(r.Context(), util.RequestIDKey, reqID)
+ ctx = metadata.NewOutgoingContext(ctx,
+ metadata.New(map[string]string{
+ util.RequestIDKey: reqID,
+ }))
+
+ w.Header().Set(util.RequestIdHttpHeader, reqID)
+ h(w, r.WithContext(ctx))
+ }
+}
diff --git a/weed/server/filer_server.go b/weed/server/filer_server.go
index 090c795fa..57af97d84 100644
--- a/weed/server/filer_server.go
+++ b/weed/server/filer_server.go
@@ -189,13 +189,13 @@ func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption)
handleStaticResources(defaultMux)
if !option.DisableHttp {
- defaultMux.HandleFunc("/healthz", fs.filerHealthzHandler)
- defaultMux.HandleFunc("/", fs.filerGuard.WhiteList(fs.filerHandler))
+ defaultMux.HandleFunc("/healthz", requestIDMiddleware(fs.filerHealthzHandler))
+ defaultMux.HandleFunc("/", fs.filerGuard.WhiteList(requestIDMiddleware(fs.filerHandler)))
}
if defaultMux != readonlyMux {
handleStaticResources(readonlyMux)
- readonlyMux.HandleFunc("/healthz", fs.filerHealthzHandler)
- readonlyMux.HandleFunc("/", fs.filerGuard.WhiteList(fs.readonlyFilerHandler))
+ readonlyMux.HandleFunc("/healthz", requestIDMiddleware(fs.filerHealthzHandler))
+ readonlyMux.HandleFunc("/", fs.filerGuard.WhiteList(requestIDMiddleware(fs.readonlyFilerHandler)))
}
existingNodes := fs.filer.ListExistingPeerUpdates(context.Background())
diff --git a/weed/server/master_server.go b/weed/server/master_server.go
index 8621708d2..6569fdbd4 100644
--- a/weed/server/master_server.go
+++ b/weed/server/master_server.go
@@ -134,24 +134,24 @@ func NewMasterServer(r *mux.Router, option *MasterOption, peers map[string]pb.Se
ms.guard = security.NewGuard(append(ms.option.WhiteList, whiteList...), signingKey, expiresAfterSec, readSigningKey, readExpiresAfterSec)
handleStaticResources2(r)
- r.HandleFunc("/", ms.proxyToLeader(ms.uiStatusHandler))
- r.HandleFunc("/ui/index.html", ms.uiStatusHandler)
+ r.HandleFunc("/", ms.proxyToLeader(requestIDMiddleware(ms.uiStatusHandler)))
+ r.HandleFunc("/ui/index.html", requestIDMiddleware(ms.uiStatusHandler))
if !ms.option.DisableHttp {
- r.HandleFunc("/dir/assign", ms.proxyToLeader(ms.guard.WhiteList(ms.dirAssignHandler)))
- r.HandleFunc("/dir/lookup", ms.guard.WhiteList(ms.dirLookupHandler))
- r.HandleFunc("/dir/status", ms.proxyToLeader(ms.guard.WhiteList(ms.dirStatusHandler)))
- r.HandleFunc("/col/delete", ms.proxyToLeader(ms.guard.WhiteList(ms.collectionDeleteHandler)))
- r.HandleFunc("/vol/grow", ms.proxyToLeader(ms.guard.WhiteList(ms.volumeGrowHandler)))
- r.HandleFunc("/vol/status", ms.proxyToLeader(ms.guard.WhiteList(ms.volumeStatusHandler)))
- r.HandleFunc("/vol/vacuum", ms.proxyToLeader(ms.guard.WhiteList(ms.volumeVacuumHandler)))
- r.HandleFunc("/submit", ms.guard.WhiteList(ms.submitFromMasterServerHandler))
- r.HandleFunc("/collection/info", ms.guard.WhiteList(ms.collectionInfoHandler))
+ r.HandleFunc("/dir/assign", ms.proxyToLeader(ms.guard.WhiteList(requestIDMiddleware(ms.dirAssignHandler))))
+ r.HandleFunc("/dir/lookup", ms.guard.WhiteList(requestIDMiddleware(ms.dirLookupHandler)))
+ r.HandleFunc("/dir/status", ms.proxyToLeader(ms.guard.WhiteList(requestIDMiddleware(ms.dirStatusHandler))))
+ r.HandleFunc("/col/delete", ms.proxyToLeader(ms.guard.WhiteList(requestIDMiddleware(ms.collectionDeleteHandler))))
+ r.HandleFunc("/vol/grow", ms.proxyToLeader(ms.guard.WhiteList(requestIDMiddleware(ms.volumeGrowHandler))))
+ r.HandleFunc("/vol/status", ms.proxyToLeader(ms.guard.WhiteList(requestIDMiddleware(ms.volumeStatusHandler))))
+ r.HandleFunc("/vol/vacuum", ms.proxyToLeader(ms.guard.WhiteList(requestIDMiddleware(ms.volumeVacuumHandler))))
+ r.HandleFunc("/submit", ms.guard.WhiteList(requestIDMiddleware(ms.submitFromMasterServerHandler)))
+ r.HandleFunc("/collection/info", ms.guard.WhiteList(requestIDMiddleware(ms.collectionInfoHandler)))
/*
r.HandleFunc("/stats/health", ms.guard.WhiteList(statsHealthHandler))
r.HandleFunc("/stats/counter", ms.guard.WhiteList(statsCounterHandler))
r.HandleFunc("/stats/memory", ms.guard.WhiteList(statsMemoryHandler))
*/
- r.HandleFunc("/{fileId}", ms.redirectHandler)
+ r.HandleFunc("/{fileId}", requestIDMiddleware(ms.redirectHandler))
}
ms.Topo.StartRefreshWritableVolumes(
diff --git a/weed/server/volume_server.go b/weed/server/volume_server.go
index a3f072eb7..5c5ebc49a 100644
--- a/weed/server/volume_server.go
+++ b/weed/server/volume_server.go
@@ -115,22 +115,22 @@ func NewVolumeServer(adminMux, publicMux *http.ServeMux, ip string,
vs.guard = security.NewGuard(whiteList, signingKey, expiresAfterSec, readSigningKey, readExpiresAfterSec)
handleStaticResources(adminMux)
- adminMux.HandleFunc("/status", vs.statusHandler)
- adminMux.HandleFunc("/healthz", vs.healthzHandler)
+ adminMux.HandleFunc("/status", requestIDMiddleware(vs.statusHandler))
+ adminMux.HandleFunc("/healthz", requestIDMiddleware(vs.healthzHandler))
if signingKey == "" || enableUiAccess {
// only expose the volume server details for safe environments
- adminMux.HandleFunc("/ui/index.html", vs.uiStatusHandler)
+ adminMux.HandleFunc("/ui/index.html", requestIDMiddleware(vs.uiStatusHandler))
/*
adminMux.HandleFunc("/stats/counter", vs.guard.WhiteList(statsCounterHandler))
adminMux.HandleFunc("/stats/memory", vs.guard.WhiteList(statsMemoryHandler))
adminMux.HandleFunc("/stats/disk", vs.guard.WhiteList(vs.statsDiskHandler))
*/
}
- adminMux.HandleFunc("/", vs.privateStoreHandler)
+ adminMux.HandleFunc("/", requestIDMiddleware(vs.privateStoreHandler))
if publicMux != adminMux {
// separated admin and public port
handleStaticResources(publicMux)
- publicMux.HandleFunc("/", vs.publicReadOnlyHandler)
+ publicMux.HandleFunc("/", requestIDMiddleware(vs.publicReadOnlyHandler))
}
go vs.heartbeat()
diff --git a/weed/util/request_id.go b/weed/util/request_id.go
new file mode 100644
index 000000000..85ec254dc
--- /dev/null
+++ b/weed/util/request_id.go
@@ -0,0 +1,20 @@
+package util
+
+import "context"
+
+const (
+ RequestIdHttpHeader = "X-Request-ID"
+ RequestIDKey = "x-request-id"
+)
+
+func GetRequestID(ctx context.Context) string {
+ if ctx == nil {
+ return ""
+ }
+ id, _ := ctx.Value(RequestIDKey).(string)
+ return id
+}
+
+func WithRequestID(ctx context.Context, id string) context.Context {
+ return context.WithValue(ctx, RequestIDKey, id)
+}