From d4d823df45ea420939692b16d6b6e810feb76967 Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Sun, 21 Jun 2026 13:25:27 +0800 Subject: [PATCH] fix(recorder): forward per-service recorder metadata to plugin recorders (#412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-configured metadata on recorder objects (recorders[].metadata in YAML) was silently discarded — MetadataRecordOption existed but was never called anywhere in the codebase, causing plugin (HTTP/gRPC) recorders to always receive null metadata. Fix: wrap recorders that carry config metadata in MetadataRecorder, which auto-appends the metadata to every Record() call. This covers all paths (handler, router, sniffer, service) with zero call-site changes. --- config/parsing/service/parse.go | 11 ++++++++++- recorder/recorder.go | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/config/parsing/service/parse.go b/config/parsing/service/parse.go index e64ff70e..c1a06a1c 100644 --- a/config/parsing/service/parse.go +++ b/config/parsing/service/parse.go @@ -34,6 +34,7 @@ import ( "github.com/go-gost/x/metadata" mdutil "github.com/go-gost/x/metadata/util" xstats "github.com/go-gost/x/observer/stats" + xrecorder "github.com/go-gost/x/recorder" "github.com/go-gost/x/registry" xservice "github.com/go-gost/x/service" "github.com/vishvananda/netns" @@ -285,8 +286,15 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) { var recorders []recorder.RecorderObject for _, r := range cfg.Recorders { md := metadata.NewMetadata(r.Metadata) + rec := registry.RecorderRegistry().Get(r.Name) + if r.Metadata != nil { + rec = &xrecorder.MetadataRecorder{ + Recorder: rec, + Metadata: r.Metadata, + } + } recorders = append(recorders, recorder.RecorderObject{ - Recorder: registry.RecorderRegistry().Get(r.Name), + Recorder: rec, Record: r.Record, Options: &recorder.Options{ Direction: mdutil.GetBool(md, parsing.MDKeyRecorderDirection), @@ -295,6 +303,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) { HTTPBody: mdutil.GetBool(md, parsing.MDKeyRecorderHTTPBody), MaxBodySize: mdutil.GetInt(md, parsing.MDKeyRecorderHTTPMaxBodySize), }, + Metadata: r.Metadata, }) } diff --git a/recorder/recorder.go b/recorder/recorder.go index cfce680d..a3d04e6b 100644 --- a/recorder/recorder.go +++ b/recorder/recorder.go @@ -10,6 +10,23 @@ import ( xctx "github.com/go-gost/x/ctx" ) +// MetadataRecorder wraps a Recorder and automatically appends metadata +// to every Record call. +type MetadataRecorder struct { + recorder.Recorder + Metadata any +} + +func (r *MetadataRecorder) Record(ctx context.Context, b []byte, opts ...recorder.RecordOption) error { + if r.Recorder == nil { + return nil + } + if r.Metadata == nil { + return r.Recorder.Record(ctx, b, opts...) + } + return r.Recorder.Record(ctx, b, append(opts, recorder.MetadataRecordOption(r.Metadata))...) +} + const ( RecorderServiceHandler = "recorder.service.handler" RecorderServiceHandlerSerial = "recorder.service.handler.serial"