Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions origin/blobserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (s *Server) Handler() http.Handler {

r.Head("/internal/namespace/{namespace}/blobs/{digest}", handler.Wrap(s.statHandler))

r.Get("/internal/namespace/{namespace}/blobs/{digest}/metainfo", handler.Wrap(s.getMetaInfoHandler))
r.With(tracingMiddleware).Get("/internal/namespace/{namespace}/blobs/{digest}/metainfo", handler.Wrap(s.getMetaInfoHandler))

r.Put(
"/internal/duplicate/namespace/{namespace}/blobs/{digest}/uploads/{uid}",
Expand Down Expand Up @@ -439,25 +439,49 @@ func (s *Server) getPeerContextHandler(w http.ResponseWriter, r *http.Request) e
}

func (s *Server) getMetaInfoHandler(w http.ResponseWriter, r *http.Request) error {
ctx, span := s.tracer.Start(r.Context(), "origin.get_metainfo",
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(
attribute.String("component", "origin"),
attribute.String("operation", "get_metainfo"),
),
)
defer span.End()

namespace, err := httputil.ParseParam(r, "namespace")
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "parse namespace failed")
return err
}
d, err := httputil.ParseDigest(r, "digest")
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "parse digest failed")
return err
}
log.With("namespace", namespace, "digest", d.Hex()).Debug("Getting metainfo")

span.SetAttributes(
attribute.String("namespace", namespace),
attribute.String("blob.digest", d.Hex()),
)
log.WithTraceContext(ctx).With("namespace", namespace, "digest", d.Hex()).Debug("Getting metainfo")

raw, err := s.getMetaInfo(namespace, d)
if err != nil {
log.With("namespace", namespace, "digest", d.Hex(), "error", err).
span.RecordError(err)
span.SetStatus(codes.Error, "get metainfo failed")
log.WithTraceContext(ctx).With("namespace", namespace, "digest", d.Hex(), "error", err).
Debug("getMetaInfo returned non-nil error")
return err
}
if _, err := w.Write(raw); err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "write response failed")
return fmt.Errorf("write response: %s", err)
}
log.With("namespace", namespace, "digest", d.Hex()).Debug("Successfully retrieved metainfo")
span.SetStatus(codes.Ok, "metainfo retrieved")
log.WithTraceContext(ctx).With("namespace", namespace, "digest", d.Hex()).Debug("Successfully retrieved metainfo")
return nil
}

Expand Down
34 changes: 33 additions & 1 deletion tracker/trackerserver/metainfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,48 @@ import (

"github.com/uber/kraken/utils/handler"
"github.com/uber/kraken/utils/httputil"
"github.com/uber/kraken/utils/log"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)

func (s *Server) getMetaInfoHandler(w http.ResponseWriter, r *http.Request) error {
ctx, span := otel.Tracer("kraken-tracker").Start(r.Context(), "tracker.get_metainfo",
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tracker is creating a tracer inline with otel.Tracer("kraken-tracker") while the origin server uses s.tracer which is initialized in the server constructor. For consistency with the rest of the codebase (see origin/blobserver/server.go:123, build-index/tagserver/server.go, and other examples), the tracker server should also initialize a tracer field in its constructor and use s.tracer.Start() here instead of calling otel.Tracer() inline.

Copilot uses AI. Check for mistakes.
trace.WithSpanKind(trace.SpanKindServer),
trace.WithAttributes(
attribute.String("component", "tracker"),
attribute.String("operation", "get_metainfo"),
),
)
defer span.End()

namespace, err := httputil.ParseParam(r, "namespace")
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "parse namespace failed")
return err
}
d, err := httputil.ParseDigest(r, "digest")
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "parse digest failed")
return handler.Errorf("parse digest: %s", err).Status(http.StatusBadRequest)
}

span.SetAttributes(
attribute.String("namespace", namespace),
attribute.String("blob.digest", d.Hex()),
)
log.WithTraceContext(ctx).With("namespace", namespace, "digest", d.Hex()).Debug("Getting metainfo from origin")

timer := s.stats.Timer("get_metainfo").Start()
mi, err := s.originCluster.GetMetaInfo(r.Context(), namespace, d)
mi, err := s.originCluster.GetMetaInfo(ctx, namespace, d)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "get metainfo from origin failed")
if serr, ok := err.(httputil.StatusError); ok {
// Propagate errors received from origin.
return handler.Errorf("origin: %s", serr.ResponseDump).Status(serr.Status)
Expand All @@ -44,11 +71,16 @@ func (s *Server) getMetaInfoHandler(w http.ResponseWriter, r *http.Request) erro

b, err := mi.Serialize()
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "serialize metainfo failed")
return fmt.Errorf("serialize metainfo: %s", err)
}
w.Header().Set("Content-Type", "application/json")
if _, err := w.Write(b); err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "write response failed")
return fmt.Errorf("write response: %s", err)
}
span.SetStatus(codes.Ok, "metainfo retrieved")
return nil
}
8 changes: 7 additions & 1 deletion tracker/trackerserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import (
"github.com/uber/kraken/utils/handler"
"github.com/uber/kraken/utils/listener"
"github.com/uber/kraken/utils/log"

"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel"
)

// Server serves Tracker endpoints.
Expand Down Expand Up @@ -76,12 +79,15 @@ func (s *Server) Handler() http.Handler {
r.Use(middleware.StatusCounter(s.stats))
r.Use(middleware.LatencyTimer(s.stats))

tracingMiddleware := otelhttp.NewMiddleware("kraken-tracker",
otelhttp.WithTracerProvider(otel.GetTracerProvider()))

r.Get("/health", handler.Wrap(s.healthHandler))
r.Get("/readiness", handler.Wrap(s.readinessCheckHandler))

r.Get("/announce", handler.Wrap(s.announceHandlerV1))
r.Post("/announce/{infohash}", handler.Wrap(s.announceHandlerV2))
r.Get("/namespace/{namespace}/blobs/{digest}/metainfo", handler.Wrap(s.getMetaInfoHandler))
r.With(tracingMiddleware).Get("/namespace/{namespace}/blobs/{digest}/metainfo", handler.Wrap(s.getMetaInfoHandler))

r.Mount("/debug", chimiddleware.Profiler())

Expand Down
Loading