From 6204b07afaa6ef44c0dec87a51fc4308e2683433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Pablo=20Villaf=C3=A1=C3=B1ez?= Date: Wed, 24 Jul 2024 18:18:34 +0200 Subject: [PATCH] feat: include additional metadata for tracing the collaboration service --- .../pkg/connector/contentconnector.go | 6 +++ .../collaboration/pkg/middleware/tracing.go | 39 +++++++++++++++++++ .../collaboration/pkg/server/http/server.go | 12 ++++-- services/proxy/pkg/middleware/tracing.go | 2 + 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 services/collaboration/pkg/middleware/tracing.go diff --git a/services/collaboration/pkg/connector/contentconnector.go b/services/collaboration/pkg/connector/contentconnector.go index a292442141d..41208410f66 100644 --- a/services/collaboration/pkg/connector/contentconnector.go +++ b/services/collaboration/pkg/connector/contentconnector.go @@ -15,9 +15,11 @@ import ( providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" revactx "github.com/cs3org/reva/v2/pkg/ctx" + "github.com/owncloud/ocis/v2/ocis-pkg/tracing" "github.com/owncloud/ocis/v2/services/collaboration/pkg/config" "github.com/owncloud/ocis/v2/services/collaboration/pkg/middleware" "github.com/rs/zerolog" + "go.opentelemetry.io/otel/propagation" ) // ContentConnectorService is the interface to implement the "File contents" @@ -143,6 +145,8 @@ func (c *ContentConnector) GetFile(ctx context.Context, writer io.Writer) error } else { httpReq.Header.Add("X-Access-Token", wopiContext.AccessToken) } + tracingProp := tracing.GetPropagator() + tracingProp.Inject(ctx, propagation.HeaderCarrier(httpReq.Header)) httpResp, err := httpClient.Do(httpReq) if err != nil { @@ -341,6 +345,8 @@ func (c *ContentConnector) PutFile(ctx context.Context, stream io.Reader, stream //if lockID, ok := ctxpkg.ContextGetLockID(ctx); ok { // httpReq.Header.Add("X-Lock-Id", lockID) //} + tracingProp := tracing.GetPropagator() + tracingProp.Inject(ctx, propagation.HeaderCarrier(httpReq.Header)) httpResp, err := httpClient.Do(httpReq) if err != nil { diff --git a/services/collaboration/pkg/middleware/tracing.go b/services/collaboration/pkg/middleware/tracing.go new file mode 100644 index 00000000000..e4f4b890f53 --- /dev/null +++ b/services/collaboration/pkg/middleware/tracing.go @@ -0,0 +1,39 @@ +package middleware + +import ( + "net/http" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) + +func CollaborationTracingMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + wopiContext, err := WopiContextFromCtx(r.Context()) + if err != nil { + // if we can't get the context, skip this middleware + next.ServeHTTP(w, r) + } + + span := trace.SpanFromContext(r.Context()) + + wopiMethod := r.Header.Get("X-WOPI-Override") + + wopiFile := wopiContext.FileReference + wopiUser := wopiContext.User.GetId() + + attrs := []attribute.KeyValue{ + attribute.String("ocis.wopi.method", wopiMethod), + attribute.String("ocis.wopi.resource.id.storage", wopiFile.GetResourceId().GetStorageId()), + attribute.String("ocis.wopi.resource.id.opaque", wopiFile.GetResourceId().GetOpaqueId()), + attribute.String("ocis.wopi.resource.id.space", wopiFile.GetResourceId().GetSpaceId()), + attribute.String("ocis.wopi.resource.path", wopiFile.GetPath()), + attribute.String("ocis.wopi.user.idp", wopiUser.GetIdp()), + attribute.String("ocis.wopi.user.opaque", wopiUser.GetOpaqueId()), + attribute.String("ocis.wopi.user.type", wopiUser.GetType().String()), + } + span.SetAttributes(attrs...) + + next.ServeHTTP(w, r) + }) +} diff --git a/services/collaboration/pkg/server/http/server.go b/services/collaboration/pkg/server/http/server.go index c331d6b6714..abeb23052fe 100644 --- a/services/collaboration/pkg/server/http/server.go +++ b/services/collaboration/pkg/server/http/server.go @@ -73,6 +73,7 @@ func Server(opts ...Option) (http.Service, error) { otelchi.WithChiRoutes(mux), otelchi.WithTracerProvider(options.TracerProvider), otelchi.WithPropagators(tracing.GetPropagator()), + otelchi.WithRequestMethodInSpanName(true), ), ) @@ -115,10 +116,13 @@ func prepareRoutes(r *chi.Mux, options Options) { r.Route("/files/{fileid}", func(r chi.Router) { - r.Use(func(h stdhttp.Handler) stdhttp.Handler { - // authentication and wopi context - return colabmiddleware.WopiContextAuthMiddleware(options.Config.Wopi.Secret, h) - }) + r.Use( + func(h stdhttp.Handler) stdhttp.Handler { + // authentication and wopi context + return colabmiddleware.WopiContextAuthMiddleware(options.Config.Wopi.Secret, h) + }, + colabmiddleware.CollaborationTracingMiddleware, + ) // check whether we should check for proof keys if !options.Config.App.ProofKeys.Disable { diff --git a/services/proxy/pkg/middleware/tracing.go b/services/proxy/pkg/middleware/tracing.go index 9b897720dce..aed4b675693 100644 --- a/services/proxy/pkg/middleware/tracing.go +++ b/services/proxy/pkg/middleware/tracing.go @@ -32,6 +32,8 @@ func (m tracer) ServeHTTP(w http.ResponseWriter, r *http.Request) { span trace.Span ) + ctx = pkgtrace.Propagator.Extract(ctx, propagation.HeaderCarrier(r.Header)) + tracer := m.traceProvider.Tracer("proxy") spanOpts := []trace.SpanStartOption{ trace.WithSpanKind(trace.SpanKindServer),