diff --git a/handler.go b/handler.go index cbefad0..ed5f029 100644 --- a/handler.go +++ b/handler.go @@ -141,8 +141,12 @@ type handler struct { aliasedMethods map[string]string paramDecoders map[reflect.Type]ParamDecoder + + tracer Tracer } +type Tracer func(method string, params []reflect.Value, results []reflect.Value, err error) + func makeHandler(sc ServerConfig) *handler { return &handler{ methods: make(map[string]methodHandler), @@ -445,12 +449,18 @@ func (s *handler) handle(ctx context.Context, req request, w func(func(io.Writer if err != nil { rpcError(w, &req, 0, xerrors.Errorf("fatal error calling '%s': %w", req.Method, err)) stats.Record(ctx, metrics.RPCRequestError.M(1)) + if s.tracer != nil { + s.tracer(req.Method, callParams, nil, err) + } return } if req.ID == nil { return // notification } + if s.tracer != nil { + s.tracer(req.Method, callParams, callResult, nil) + } // ///////////////// resp := response{ diff --git a/options_server.go b/options_server.go index f6721fc..1443ec7 100644 --- a/options_server.go +++ b/options_server.go @@ -21,6 +21,7 @@ type ServerConfig struct { errors *Errors reverseClientBuilder func(context.Context, *wsConn) (context.Context, error) + tracer Tracer } type ServerOption func(c *ServerConfig) @@ -58,6 +59,14 @@ func WithServerPingInterval(d time.Duration) ServerOption { } } +// WithTracer allows the instantiator to trace the method calls and results. +// This is useful for debugging a client-server interaction. +func WithTracer(l Tracer) ServerOption { + return func(c *ServerConfig) { + c.tracer = l + } +} + // WithReverseClient will allow extracting reverse client on **WEBSOCKET** calls. // RP is a proxy-struct type, much like the one passed to NewClient. func WithReverseClient[RP any](namespace string) ServerOption {