Add a thin wrapper around otel Span object

Signed-off-by: Swagat Bora <sbora@amazon.com>
This commit is contained in:
Swagat Bora 2022-11-09 21:47:44 +00:00
parent d4b3b54540
commit 7def13dde3
16 changed files with 168 additions and 146 deletions

View File

@ -82,7 +82,6 @@ func clientWithTrace() error {
defer cancel() defer cancel()
ctx, span := tracing.StartSpan(ctx, "OPERATION NAME") ctx, span := tracing.StartSpan(ctx, "OPERATION NAME")
defer tracing.StopSpan(span) defer span.End()
... ...
} }
```

View File

@ -97,9 +97,7 @@ const (
runtimeRunhcsV1 = "io.containerd.runhcs.v1" runtimeRunhcsV1 = "io.containerd.runhcs.v1"
// name prefix for CRI sbserver specific spans // name prefix for CRI sbserver specific spans
criSbServerSpanPrefix = "pkg.cri.sbserver" criSpanPrefix = "pkg.cri.sbserver"
spanDelimiter = "."
) )
// makeSandboxName generates sandbox name from sandbox metadata. The name // makeSandboxName generates sandbox name from sandbox metadata. The name
@ -506,10 +504,3 @@ func copyResourcesToStatus(spec *runtimespec.Spec, status containerstore.Status)
} }
return status return status
} }
func makeSpanName(funcName string) string {
return strings.Join([]string{
criSbServerSpanPrefix,
funcName,
}, spanDelimiter)
}

View File

@ -94,7 +94,7 @@ import (
// PullImage pulls an image with authentication config. // PullImage pulls an image with authentication config.
func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest) (*runtime.PullImageResponse, error) { func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest) (*runtime.PullImageResponse, error) {
span := tracing.CurrentSpan(ctx) span := tracing.SpanFromContext(ctx)
imageRef := r.GetImage().GetImage() imageRef := r.GetImage().GetImage()
namedRef, err := distribution.ParseDockerRef(imageRef) namedRef, err := distribution.ParseDockerRef(imageRef)
if err != nil { if err != nil {
@ -136,8 +136,8 @@ func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest)
} }
log.G(ctx).Debugf("PullImage %q with snapshotter %s", ref, snapshotter) log.G(ctx).Debugf("PullImage %q with snapshotter %s", ref, snapshotter)
span.SetAttributes( span.SetAttributes(
tracing.SpanAttribute("image.ref", ref), tracing.Attribute("image.ref", ref),
tracing.SpanAttribute("snapshotter.name", snapshotter), tracing.Attribute("snapshotter.name", snapshotter),
) )
pullOpts := []containerd.RemoteOpt{ pullOpts := []containerd.RemoteOpt{

View File

@ -34,7 +34,7 @@ import (
// Remove the whole image no matter the it's image id or reference. This is the // Remove the whole image no matter the it's image id or reference. This is the
// semantic defined in CRI now. // semantic defined in CRI now.
func (c *criService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequest) (*runtime.RemoveImageResponse, error) { func (c *criService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequest) (*runtime.RemoveImageResponse, error) {
span := tracing.CurrentSpan(ctx) span := tracing.SpanFromContext(ctx)
image, err := c.localResolve(r.GetImage().GetImage()) image, err := c.localResolve(r.GetImage().GetImage())
if err != nil { if err != nil {
if errdefs.IsNotFound(err) { if errdefs.IsNotFound(err) {
@ -44,7 +44,7 @@ func (c *criService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequ
} }
return nil, fmt.Errorf("can not resolve %q locally: %w", r.GetImage().GetImage(), err) return nil, fmt.Errorf("can not resolve %q locally: %w", r.GetImage().GetImage(), err)
} }
span.SetAttributes(tracing.SpanAttribute("image.id", image.ID)) span.SetAttributes(tracing.Attribute("image.id", image.ID))
// Remove all image references. // Remove all image references.
for i, ref := range image.References { for i, ref := range image.References {
var opts []images.DeleteOpt var opts []images.DeleteOpt

View File

@ -34,7 +34,7 @@ import (
// TODO(random-liu): We should change CRI to distinguish image id and image spec. (See // TODO(random-liu): We should change CRI to distinguish image id and image spec. (See
// kubernetes/kubernetes#46255) // kubernetes/kubernetes#46255)
func (c *criService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequest) (*runtime.ImageStatusResponse, error) { func (c *criService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequest) (*runtime.ImageStatusResponse, error) {
span := tracing.CurrentSpan(ctx) span := tracing.SpanFromContext(ctx)
image, err := c.localResolve(r.GetImage().GetImage()) image, err := c.localResolve(r.GetImage().GetImage())
if err != nil { if err != nil {
if errdefs.IsNotFound(err) { if errdefs.IsNotFound(err) {
@ -44,7 +44,7 @@ func (c *criService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequ
} }
return nil, fmt.Errorf("can not resolve %q locally: %w", r.GetImage().GetImage(), err) return nil, fmt.Errorf("can not resolve %q locally: %w", r.GetImage().GetImage(), err)
} }
span.SetAttributes(tracing.SpanAttribute("image.id", image.ID)) span.SetAttributes(tracing.Attribute("image.id", image.ID))
// TODO(random-liu): [P0] Make sure corresponding snapshot exists. What if snapshot // TODO(random-liu): [P0] Make sure corresponding snapshot exists. What if snapshot
// doesn't exist? // doesn't exist?

View File

@ -932,8 +932,8 @@ func (in *instrumentedService) PullImage(ctx context.Context, r *runtime.PullIma
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("PullImage")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "PullImage"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Infof("PullImage %q", r.GetImage().GetImage()) log.G(ctx).Infof("PullImage %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -942,7 +942,7 @@ func (in *instrumentedService) PullImage(ctx context.Context, r *runtime.PullIma
log.G(ctx).Infof("PullImage %q returns image reference %q", log.G(ctx).Infof("PullImage %q returns image reference %q",
r.GetImage().GetImage(), res.GetImageRef()) r.GetImage().GetImage(), res.GetImageRef())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err = in.c.PullImage(ctrdutil.WithNamespace(ctx), r) res, err = in.c.PullImage(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -952,8 +952,8 @@ func (in *instrumentedAlphaService) PullImage(ctx context.Context, r *runtime_al
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("PullImage")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "PullImage"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Infof("PullImage %q", r.GetImage().GetImage()) log.G(ctx).Infof("PullImage %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -962,7 +962,7 @@ func (in *instrumentedAlphaService) PullImage(ctx context.Context, r *runtime_al
log.G(ctx).Infof("PullImage %q returns image reference %q", log.G(ctx).Infof("PullImage %q returns image reference %q",
r.GetImage().GetImage(), res.GetImageRef()) r.GetImage().GetImage(), res.GetImageRef())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.PullImageRequest var v1r runtime.PullImageRequest
@ -993,8 +993,8 @@ func (in *instrumentedService) ListImages(ctx context.Context, r *runtime.ListIm
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ListImages")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ListImages"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Tracef("ListImages with filter %+v", r.GetFilter()) log.G(ctx).Tracef("ListImages with filter %+v", r.GetFilter())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1003,7 +1003,7 @@ func (in *instrumentedService) ListImages(ctx context.Context, r *runtime.ListIm
log.G(ctx).Tracef("ListImages with filter %+v returns image list %+v", log.G(ctx).Tracef("ListImages with filter %+v returns image list %+v",
r.GetFilter(), res.GetImages()) r.GetFilter(), res.GetImages())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err = in.c.ListImages(ctrdutil.WithNamespace(ctx), r) res, err = in.c.ListImages(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -1013,8 +1013,8 @@ func (in *instrumentedAlphaService) ListImages(ctx context.Context, r *runtime_a
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ListImages")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ListImages"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Tracef("ListImages with filter %+v", r.GetFilter()) log.G(ctx).Tracef("ListImages with filter %+v", r.GetFilter())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1023,7 +1023,7 @@ func (in *instrumentedAlphaService) ListImages(ctx context.Context, r *runtime_a
log.G(ctx).Tracef("ListImages with filter %+v returns image list %+v", log.G(ctx).Tracef("ListImages with filter %+v returns image list %+v",
r.GetFilter(), res.GetImages()) r.GetFilter(), res.GetImages())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.ListImagesRequest var v1r runtime.ListImagesRequest
@ -1054,8 +1054,8 @@ func (in *instrumentedService) ImageStatus(ctx context.Context, r *runtime.Image
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ImageStatus")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ImageStatus"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Tracef("ImageStatus for %q", r.GetImage().GetImage()) log.G(ctx).Tracef("ImageStatus for %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1064,7 +1064,7 @@ func (in *instrumentedService) ImageStatus(ctx context.Context, r *runtime.Image
log.G(ctx).Tracef("ImageStatus for %q returns image status %+v", log.G(ctx).Tracef("ImageStatus for %q returns image status %+v",
r.GetImage().GetImage(), res.GetImage()) r.GetImage().GetImage(), res.GetImage())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err = in.c.ImageStatus(ctrdutil.WithNamespace(ctx), r) res, err = in.c.ImageStatus(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -1074,8 +1074,8 @@ func (in *instrumentedAlphaService) ImageStatus(ctx context.Context, r *runtime_
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ImageStatus")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ImageStatus"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Tracef("ImageStatus for %q", r.GetImage().GetImage()) log.G(ctx).Tracef("ImageStatus for %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1084,7 +1084,7 @@ func (in *instrumentedAlphaService) ImageStatus(ctx context.Context, r *runtime_
log.G(ctx).Tracef("ImageStatus for %q returns image status %+v", log.G(ctx).Tracef("ImageStatus for %q returns image status %+v",
r.GetImage().GetImage(), res.GetImage()) r.GetImage().GetImage(), res.GetImage())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.ImageStatusRequest var v1r runtime.ImageStatusRequest
@ -1115,8 +1115,8 @@ func (in *instrumentedService) RemoveImage(ctx context.Context, r *runtime.Remov
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("RemoveImage")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "RemoveImage"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Infof("RemoveImage %q", r.GetImage().GetImage()) log.G(ctx).Infof("RemoveImage %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1124,7 +1124,7 @@ func (in *instrumentedService) RemoveImage(ctx context.Context, r *runtime.Remov
} else { } else {
log.G(ctx).Infof("RemoveImage %q returns successfully", r.GetImage().GetImage()) log.G(ctx).Infof("RemoveImage %q returns successfully", r.GetImage().GetImage())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err := in.c.RemoveImage(ctrdutil.WithNamespace(ctx), r) res, err := in.c.RemoveImage(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -1134,8 +1134,8 @@ func (in *instrumentedAlphaService) RemoveImage(ctx context.Context, r *runtime_
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("RemoveImage")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "RemoveImage"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Infof("RemoveImage %q", r.GetImage().GetImage()) log.G(ctx).Infof("RemoveImage %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1143,7 +1143,7 @@ func (in *instrumentedAlphaService) RemoveImage(ctx context.Context, r *runtime_
} else { } else {
log.G(ctx).Infof("RemoveImage %q returns successfully", r.GetImage().GetImage()) log.G(ctx).Infof("RemoveImage %q returns successfully", r.GetImage().GetImage())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.RemoveImageRequest var v1r runtime.RemoveImageRequest
@ -1174,8 +1174,8 @@ func (in *instrumentedService) ImageFsInfo(ctx context.Context, r *runtime.Image
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ImageFsInfo")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ImageFsInfo"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Debugf("ImageFsInfo") log.G(ctx).Debugf("ImageFsInfo")
defer func() { defer func() {
if err != nil { if err != nil {
@ -1183,7 +1183,7 @@ func (in *instrumentedService) ImageFsInfo(ctx context.Context, r *runtime.Image
} else { } else {
log.G(ctx).Debugf("ImageFsInfo returns filesystem info %+v", res.ImageFilesystems) log.G(ctx).Debugf("ImageFsInfo returns filesystem info %+v", res.ImageFilesystems)
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err = in.c.ImageFsInfo(ctrdutil.WithNamespace(ctx), r) res, err = in.c.ImageFsInfo(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -1193,8 +1193,8 @@ func (in *instrumentedAlphaService) ImageFsInfo(ctx context.Context, r *runtime_
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ImageFsInfo")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ImageFsInfo"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Debugf("ImageFsInfo") log.G(ctx).Debugf("ImageFsInfo")
defer func() { defer func() {
if err != nil { if err != nil {
@ -1202,7 +1202,7 @@ func (in *instrumentedAlphaService) ImageFsInfo(ctx context.Context, r *runtime_
} else { } else {
log.G(ctx).Debugf("ImageFsInfo returns filesystem info %+v", res.ImageFilesystems) log.G(ctx).Debugf("ImageFsInfo returns filesystem info %+v", res.ImageFilesystems)
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.ImageFsInfoRequest var v1r runtime.ImageFsInfoRequest

View File

@ -94,9 +94,7 @@ const (
runtimeRunhcsV1 = "io.containerd.runhcs.v1" runtimeRunhcsV1 = "io.containerd.runhcs.v1"
// name prefix for CRI server specific spans // name prefix for CRI server specific spans
criServerSpanPrefix = "pkg.cri.server" criSpanPrefix = "pkg.cri.server"
spanDelimiter = "."
) )
// makeSandboxName generates sandbox name from sandbox metadata. The name // makeSandboxName generates sandbox name from sandbox metadata. The name
@ -515,10 +513,3 @@ func copyResourcesToStatus(spec *runtimespec.Spec, status containerstore.Status)
} }
return status return status
} }
func makeSpanName(funcName string) string {
return strings.Join([]string{
criServerSpanPrefix,
funcName,
}, spanDelimiter)
}

View File

@ -94,7 +94,7 @@ import (
// PullImage pulls an image with authentication config. // PullImage pulls an image with authentication config.
func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest) (*runtime.PullImageResponse, error) { func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest) (*runtime.PullImageResponse, error) {
span := tracing.CurrentSpan(ctx) span := tracing.SpanFromContext(ctx)
imageRef := r.GetImage().GetImage() imageRef := r.GetImage().GetImage()
namedRef, err := distribution.ParseDockerRef(imageRef) namedRef, err := distribution.ParseDockerRef(imageRef)
if err != nil { if err != nil {
@ -136,8 +136,8 @@ func (c *criService) PullImage(ctx context.Context, r *runtime.PullImageRequest)
} }
log.G(ctx).Debugf("PullImage %q with snapshotter %s", ref, snapshotter) log.G(ctx).Debugf("PullImage %q with snapshotter %s", ref, snapshotter)
span.SetAttributes( span.SetAttributes(
tracing.SpanAttribute("image.ref", ref), tracing.Attribute("image.ref", ref),
tracing.SpanAttribute("snapshotter.name", snapshotter), tracing.Attribute("snapshotter.name", snapshotter),
) )
pullOpts := []containerd.RemoteOpt{ pullOpts := []containerd.RemoteOpt{
containerd.WithSchema1Conversion, //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. containerd.WithSchema1Conversion, //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility.

View File

@ -34,7 +34,7 @@ import (
// Remove the whole image no matter the it's image id or reference. This is the // Remove the whole image no matter the it's image id or reference. This is the
// semantic defined in CRI now. // semantic defined in CRI now.
func (c *criService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequest) (*runtime.RemoveImageResponse, error) { func (c *criService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequest) (*runtime.RemoveImageResponse, error) {
span := tracing.CurrentSpan(ctx) span := tracing.SpanFromContext(ctx)
image, err := c.localResolve(r.GetImage().GetImage()) image, err := c.localResolve(r.GetImage().GetImage())
if err != nil { if err != nil {
if errdefs.IsNotFound(err) { if errdefs.IsNotFound(err) {
@ -44,7 +44,7 @@ func (c *criService) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequ
} }
return nil, fmt.Errorf("can not resolve %q locally: %w", r.GetImage().GetImage(), err) return nil, fmt.Errorf("can not resolve %q locally: %w", r.GetImage().GetImage(), err)
} }
span.SetAttributes(tracing.SpanAttribute("image.id", image.ID)) span.SetAttributes(tracing.Attribute("image.id", image.ID))
// Remove all image references. // Remove all image references.
for i, ref := range image.References { for i, ref := range image.References {
var opts []images.DeleteOpt var opts []images.DeleteOpt

View File

@ -34,7 +34,7 @@ import (
// TODO(random-liu): We should change CRI to distinguish image id and image spec. (See // TODO(random-liu): We should change CRI to distinguish image id and image spec. (See
// kubernetes/kubernetes#46255) // kubernetes/kubernetes#46255)
func (c *criService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequest) (*runtime.ImageStatusResponse, error) { func (c *criService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequest) (*runtime.ImageStatusResponse, error) {
span := tracing.CurrentSpan(ctx) span := tracing.SpanFromContext(ctx)
image, err := c.localResolve(r.GetImage().GetImage()) image, err := c.localResolve(r.GetImage().GetImage())
if err != nil { if err != nil {
if errdefs.IsNotFound(err) { if errdefs.IsNotFound(err) {
@ -44,7 +44,7 @@ func (c *criService) ImageStatus(ctx context.Context, r *runtime.ImageStatusRequ
} }
return nil, fmt.Errorf("can not resolve %q locally: %w", r.GetImage().GetImage(), err) return nil, fmt.Errorf("can not resolve %q locally: %w", r.GetImage().GetImage(), err)
} }
span.SetAttributes(tracing.SpanAttribute("image.id", image.ID)) span.SetAttributes(tracing.Attribute("image.id", image.ID))
// TODO(random-liu): [P0] Make sure corresponding snapshot exists. What if snapshot // TODO(random-liu): [P0] Make sure corresponding snapshot exists. What if snapshot
// doesn't exist? // doesn't exist?

View File

@ -932,8 +932,8 @@ func (in *instrumentedService) PullImage(ctx context.Context, r *runtime.PullIma
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("PullImage")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "PullImage"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Infof("PullImage %q", r.GetImage().GetImage()) log.G(ctx).Infof("PullImage %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -942,7 +942,7 @@ func (in *instrumentedService) PullImage(ctx context.Context, r *runtime.PullIma
log.G(ctx).Infof("PullImage %q returns image reference %q", log.G(ctx).Infof("PullImage %q returns image reference %q",
r.GetImage().GetImage(), res.GetImageRef()) r.GetImage().GetImage(), res.GetImageRef())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err = in.c.PullImage(ctrdutil.WithNamespace(ctx), r) res, err = in.c.PullImage(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -952,8 +952,8 @@ func (in *instrumentedAlphaService) PullImage(ctx context.Context, r *runtime_al
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("PullImage")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "PullImage"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Infof("PullImage %q", r.GetImage().GetImage()) log.G(ctx).Infof("PullImage %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -962,7 +962,7 @@ func (in *instrumentedAlphaService) PullImage(ctx context.Context, r *runtime_al
log.G(ctx).Infof("PullImage %q returns image reference %q", log.G(ctx).Infof("PullImage %q returns image reference %q",
r.GetImage().GetImage(), res.GetImageRef()) r.GetImage().GetImage(), res.GetImageRef())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.PullImageRequest var v1r runtime.PullImageRequest
@ -993,8 +993,8 @@ func (in *instrumentedService) ListImages(ctx context.Context, r *runtime.ListIm
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ListImages")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ListImages"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Tracef("ListImages with filter %+v", r.GetFilter()) log.G(ctx).Tracef("ListImages with filter %+v", r.GetFilter())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1003,7 +1003,7 @@ func (in *instrumentedService) ListImages(ctx context.Context, r *runtime.ListIm
log.G(ctx).Tracef("ListImages with filter %+v returns image list %+v", log.G(ctx).Tracef("ListImages with filter %+v returns image list %+v",
r.GetFilter(), res.GetImages()) r.GetFilter(), res.GetImages())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err = in.c.ListImages(ctrdutil.WithNamespace(ctx), r) res, err = in.c.ListImages(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -1013,8 +1013,8 @@ func (in *instrumentedAlphaService) ListImages(ctx context.Context, r *runtime_a
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ListImages")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ListImages"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Tracef("ListImages with filter %+v", r.GetFilter()) log.G(ctx).Tracef("ListImages with filter %+v", r.GetFilter())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1023,7 +1023,7 @@ func (in *instrumentedAlphaService) ListImages(ctx context.Context, r *runtime_a
log.G(ctx).Tracef("ListImages with filter %+v returns image list %+v", log.G(ctx).Tracef("ListImages with filter %+v returns image list %+v",
r.GetFilter(), res.GetImages()) r.GetFilter(), res.GetImages())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.ListImagesRequest var v1r runtime.ListImagesRequest
@ -1054,8 +1054,8 @@ func (in *instrumentedService) ImageStatus(ctx context.Context, r *runtime.Image
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ImageStatus")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ImageStatus"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Tracef("ImageStatus for %q", r.GetImage().GetImage()) log.G(ctx).Tracef("ImageStatus for %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1064,7 +1064,7 @@ func (in *instrumentedService) ImageStatus(ctx context.Context, r *runtime.Image
log.G(ctx).Tracef("ImageStatus for %q returns image status %+v", log.G(ctx).Tracef("ImageStatus for %q returns image status %+v",
r.GetImage().GetImage(), res.GetImage()) r.GetImage().GetImage(), res.GetImage())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err = in.c.ImageStatus(ctrdutil.WithNamespace(ctx), r) res, err = in.c.ImageStatus(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -1074,8 +1074,8 @@ func (in *instrumentedAlphaService) ImageStatus(ctx context.Context, r *runtime_
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ImageStatus")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ImageStatus"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Tracef("ImageStatus for %q", r.GetImage().GetImage()) log.G(ctx).Tracef("ImageStatus for %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1084,7 +1084,7 @@ func (in *instrumentedAlphaService) ImageStatus(ctx context.Context, r *runtime_
log.G(ctx).Tracef("ImageStatus for %q returns image status %+v", log.G(ctx).Tracef("ImageStatus for %q returns image status %+v",
r.GetImage().GetImage(), res.GetImage()) r.GetImage().GetImage(), res.GetImage())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.ImageStatusRequest var v1r runtime.ImageStatusRequest
@ -1115,8 +1115,8 @@ func (in *instrumentedService) RemoveImage(ctx context.Context, r *runtime.Remov
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("RemoveImage")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "RemoveImage"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Infof("RemoveImage %q", r.GetImage().GetImage()) log.G(ctx).Infof("RemoveImage %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1124,7 +1124,7 @@ func (in *instrumentedService) RemoveImage(ctx context.Context, r *runtime.Remov
} else { } else {
log.G(ctx).Infof("RemoveImage %q returns successfully", r.GetImage().GetImage()) log.G(ctx).Infof("RemoveImage %q returns successfully", r.GetImage().GetImage())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err := in.c.RemoveImage(ctrdutil.WithNamespace(ctx), r) res, err := in.c.RemoveImage(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -1134,8 +1134,8 @@ func (in *instrumentedAlphaService) RemoveImage(ctx context.Context, r *runtime_
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("RemoveImage")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "RemoveImage"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Infof("RemoveImage %q", r.GetImage().GetImage()) log.G(ctx).Infof("RemoveImage %q", r.GetImage().GetImage())
defer func() { defer func() {
if err != nil { if err != nil {
@ -1143,7 +1143,7 @@ func (in *instrumentedAlphaService) RemoveImage(ctx context.Context, r *runtime_
} else { } else {
log.G(ctx).Infof("RemoveImage %q returns successfully", r.GetImage().GetImage()) log.G(ctx).Infof("RemoveImage %q returns successfully", r.GetImage().GetImage())
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.RemoveImageRequest var v1r runtime.RemoveImageRequest
@ -1174,8 +1174,8 @@ func (in *instrumentedService) ImageFsInfo(ctx context.Context, r *runtime.Image
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ImageFsInfo")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ImageFsInfo"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Debugf("ImageFsInfo") log.G(ctx).Debugf("ImageFsInfo")
defer func() { defer func() {
if err != nil { if err != nil {
@ -1183,7 +1183,7 @@ func (in *instrumentedService) ImageFsInfo(ctx context.Context, r *runtime.Image
} else { } else {
log.G(ctx).Debugf("ImageFsInfo returns filesystem info %+v", res.ImageFilesystems) log.G(ctx).Debugf("ImageFsInfo returns filesystem info %+v", res.ImageFilesystems)
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
res, err = in.c.ImageFsInfo(ctrdutil.WithNamespace(ctx), r) res, err = in.c.ImageFsInfo(ctrdutil.WithNamespace(ctx), r)
return res, errdefs.ToGRPC(err) return res, errdefs.ToGRPC(err)
@ -1193,8 +1193,8 @@ func (in *instrumentedAlphaService) ImageFsInfo(ctx context.Context, r *runtime_
if err := in.checkInitialized(); err != nil { if err := in.checkInitialized(); err != nil {
return nil, err return nil, err
} }
ctx, span := tracing.StartSpan(ctx, makeSpanName("ImageFsInfo")) ctx, span := tracing.StartSpan(ctx, tracing.Name(criSpanPrefix, "ImageFsInfo"))
defer tracing.StopSpan(span) defer span.End()
log.G(ctx).Debugf("ImageFsInfo") log.G(ctx).Debugf("ImageFsInfo")
defer func() { defer func() {
if err != nil { if err != nil {
@ -1202,7 +1202,7 @@ func (in *instrumentedAlphaService) ImageFsInfo(ctx context.Context, r *runtime_
} else { } else {
log.G(ctx).Debugf("ImageFsInfo returns filesystem info %+v", res.ImageFilesystems) log.G(ctx).Debugf("ImageFsInfo returns filesystem info %+v", res.ImageFilesystems)
} }
tracing.SetSpanStatus(span, err) span.SetStatus(err)
}() }()
// converts request and response for earlier CRI version to call and get response from the current version // converts request and response for earlier CRI version to call and get response from the current version
var v1r runtime.ImageFsInfoRequest var v1r runtime.ImageFsInfoRequest

View File

@ -48,6 +48,7 @@ import (
const ( const (
labelSnapshotRef = "containerd.io/snapshot.ref" labelSnapshotRef = "containerd.io/snapshot.ref"
unpackSpanPrefix = "pkg.unpack.unpacker"
) )
// Result returns information about the unpacks which were completed. // Result returns information about the unpacks which were completed.
@ -162,11 +163,11 @@ func (u *Unpacker) Unpack(h images.Handler) images.Handler {
layers = map[digest.Digest][]ocispec.Descriptor{} layers = map[digest.Digest][]ocispec.Descriptor{}
) )
return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
ctx, span := tracing.StartSpan(ctx, "pkg.unpack.unpacker.UnpackHandler") ctx, span := tracing.StartSpan(ctx, tracing.Name(unpackSpanPrefix, "UnpackHandler"))
defer span.End() defer span.End()
span.SetAttributes( span.SetAttributes(
tracing.SpanAttribute("descriptor.media.type", desc.MediaType), tracing.Attribute("descriptor.media.type", desc.MediaType),
tracing.SpanAttribute("descriptor.digest", desc.Digest.String())) tracing.Attribute("descriptor.digest", desc.Digest.String()))
unlock, err := u.lockBlobDescriptor(ctx, desc) unlock, err := u.lockBlobDescriptor(ctx, desc)
if err != nil { if err != nil {
return nil, err return nil, err
@ -185,7 +186,7 @@ func (u *Unpacker) Unpack(h images.Handler) images.Handler {
// the config // the config
for i, child := range children { for i, child := range children {
span.SetAttributes( span.SetAttributes(
tracing.SpanAttribute("descriptor.child."+strconv.Itoa(i), []string{child.MediaType, child.Digest.String()}), tracing.Attribute("descriptor.child."+strconv.Itoa(i), []string{child.MediaType, child.Digest.String()}),
) )
if images.IsLayerType(child.MediaType) { if images.IsLayerType(child.MediaType) {
manifestLayers = append(manifestLayers, child) manifestLayers = append(manifestLayers, child)
@ -232,7 +233,7 @@ func (u *Unpacker) unpack(
layers []ocispec.Descriptor, layers []ocispec.Descriptor,
) error { ) error {
ctx := u.ctx ctx := u.ctx
ctx, layerSpan := tracing.StartSpan(ctx, "pkg.unpack.unpacker.unpack") ctx, layerSpan := tracing.StartSpan(ctx, tracing.Name(unpackSpanPrefix, "unpack"))
defer layerSpan.End() defer layerSpan.End()
p, err := content.ReadBlob(ctx, u.content, config) p, err := content.ReadBlob(ctx, u.content, config)
if err != nil { if err != nil {
@ -409,14 +410,14 @@ func (u *Unpacker) unpack(
} }
for i, desc := range layers { for i, desc := range layers {
_, layerSpan := tracing.StartSpan(ctx, "pkg.unpack.unpacker.unpackLayer") _, layerSpan := tracing.StartSpan(ctx, tracing.Name(unpackSpanPrefix, "unpackLayer"))
layerSpan.SetAttributes( layerSpan.SetAttributes(
tracing.SpanAttribute("layer.media.type", desc.MediaType), tracing.Attribute("layer.media.type", desc.MediaType),
tracing.SpanAttribute("layer.media.size", desc.Size), tracing.Attribute("layer.media.size", desc.Size),
tracing.SpanAttribute("layer.media.digest", desc.Digest.String()), tracing.Attribute("layer.media.digest", desc.Digest.String()),
) )
if err := doUnpackFn(i, desc); err != nil { if err := doUnpackFn(i, desc); err != nil {
layerSpan.RecordError(err) layerSpan.SetStatus(err)
layerSpan.End() layerSpan.End()
return err return err
} }
@ -445,11 +446,11 @@ func (u *Unpacker) unpack(
func (u *Unpacker) fetch(ctx context.Context, h images.Handler, layers []ocispec.Descriptor, done []chan struct{}) error { func (u *Unpacker) fetch(ctx context.Context, h images.Handler, layers []ocispec.Descriptor, done []chan struct{}) error {
eg, ctx2 := errgroup.WithContext(ctx) eg, ctx2 := errgroup.WithContext(ctx)
for i, desc := range layers { for i, desc := range layers {
ctx2, layerSpan := tracing.StartSpan(ctx2, "pkg.unpack.unpacker.fetchLayer") ctx2, layerSpan := tracing.StartSpan(ctx2, tracing.Name(unpackSpanPrefix, "fetchLayer"))
layerSpan.SetAttributes( layerSpan.SetAttributes(
tracing.SpanAttribute("layer.media.type", desc.MediaType), tracing.Attribute("layer.media.type", desc.MediaType),
tracing.SpanAttribute("layer.media.size", desc.Size), tracing.Attribute("layer.media.size", desc.Size),
tracing.SpanAttribute("layer.media.digest", desc.Digest.String()), tracing.Attribute("layer.media.digest", desc.Digest.String()),
) )
desc := desc desc := desc
i := i i := i

38
pull.go
View File

@ -33,11 +33,15 @@ import (
"golang.org/x/sync/semaphore" "golang.org/x/sync/semaphore"
) )
const (
pullSpanPrefix = "pull"
)
// Pull downloads the provided content into containerd's content store // Pull downloads the provided content into containerd's content store
// and returns a platform specific image object // and returns a platform specific image object
func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Image, retErr error) { func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Image, retErr error) {
ctx, span := tracing.StartSpan(ctx, "pull.Pull") ctx, span := tracing.StartSpan(ctx, tracing.Name(pullSpanPrefix, "Pull"))
defer tracing.StopSpan(span) defer span.End()
pullCtx := defaultRemoteContext() pullCtx := defaultRemoteContext()
@ -63,11 +67,11 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
} }
span.SetAttributes( span.SetAttributes(
tracing.SpanAttribute("image.ref", ref), tracing.Attribute("image.ref", ref),
tracing.SpanAttribute("unpack", pullCtx.Unpack), tracing.Attribute("unpack", pullCtx.Unpack),
tracing.SpanAttribute("max.concurrent.downloads", pullCtx.MaxConcurrentDownloads), tracing.Attribute("max.concurrent.downloads", pullCtx.MaxConcurrentDownloads),
tracing.SpanAttribute("max.concurrent.upload.layers", pullCtx.MaxConcurrentUploadedLayers), tracing.Attribute("max.concurrent.upload.layers", pullCtx.MaxConcurrentUploadedLayers),
tracing.SpanAttribute("platforms.count", len(pullCtx.Platforms)), tracing.Attribute("platforms.count", len(pullCtx.Platforms)),
) )
ctx, done, err := c.WithLease(ctx) ctx, done, err := c.WithLease(ctx)
@ -83,7 +87,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to resolve snapshotter: %w", err) return nil, fmt.Errorf("unable to resolve snapshotter: %w", err)
} }
span.SetAttributes(tracing.SpanAttribute("snapshotter.name", snapshotterName)) span.SetAttributes(tracing.Attribute("snapshotter.name", snapshotterName))
var uconfig UnpackConfig var uconfig UnpackConfig
for _, opt := range pullCtx.UnpackOpts { for _, opt := range pullCtx.UnpackOpts {
if err := opt(ctx, &uconfig); err != nil { if err := opt(ctx, &uconfig); err != nil {
@ -141,13 +145,13 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
// download). // download).
var ur unpack.Result var ur unpack.Result
if unpacker != nil { if unpacker != nil {
_, unpackSpan := tracing.StartSpan(ctx, "pull.UnpackWait") _, unpackSpan := tracing.StartSpan(ctx, tracing.Name(pullSpanPrefix, "UnpackWait"))
if ur, err = unpacker.Wait(); err != nil { if ur, err = unpacker.Wait(); err != nil {
unpackSpan.RecordError(err) unpackSpan.SetStatus(err)
tracing.StopSpan(unpackSpan) unpackSpan.End()
return nil, err return nil, err
} }
tracing.StopSpan(unpackSpan) unpackSpan.End()
} }
img, err = c.createNewImage(ctx, img) img, err = c.createNewImage(ctx, img)
@ -156,7 +160,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
} }
i := NewImageWithPlatform(c, img, pullCtx.PlatformMatcher) i := NewImageWithPlatform(c, img, pullCtx.PlatformMatcher)
span.SetAttributes(tracing.SpanAttribute("image.ref", i.Name())) span.SetAttributes(tracing.Attribute("image.ref", i.Name()))
if unpacker != nil && ur.Unpacks == 0 { if unpacker != nil && ur.Unpacks == 0 {
// Unpack was tried previously but nothing was unpacked // Unpack was tried previously but nothing was unpacked
@ -170,8 +174,8 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (_ Ima
} }
func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, limit int) (images.Image, error) { func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, limit int) (images.Image, error) {
ctx, span := tracing.StartSpan(ctx, "pull.fetch") ctx, span := tracing.StartSpan(ctx, tracing.Name(pullSpanPrefix, "fetch"))
defer tracing.StopSpan(span) defer span.End()
store := c.ContentStore() store := c.ContentStore()
name, desc, err := rCtx.Resolver.Resolve(ctx, ref) name, desc, err := rCtx.Resolver.Resolve(ctx, ref)
if err != nil { if err != nil {
@ -275,8 +279,8 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim
} }
func (c *Client) createNewImage(ctx context.Context, img images.Image) (images.Image, error) { func (c *Client) createNewImage(ctx context.Context, img images.Image) (images.Image, error) {
ctx, span := tracing.StartSpan(ctx, "pull.createNewImage") ctx, span := tracing.StartSpan(ctx, tracing.Name(pullSpanPrefix, "pull.createNewImage"))
defer tracing.StopSpan(span) defer span.End()
is := c.ImageService() is := c.ImageService()
for { for {
if created, err := is.Create(ctx, img); err != nil { if created, err := is.Create(ctx, img); err != nil {

View File

@ -571,18 +571,18 @@ func (r *request) do(ctx context.Context) (*http.Response, error) {
} }
_, httpSpan := tracing.StartSpan( _, httpSpan := tracing.StartSpan(
ctx, ctx,
"remotes.docker.resolver.HTTPRequest", tracing.Name("remotes.docker.resolver", "HTTPRequest"),
oteltrace.WithSpanKind(oteltrace.SpanKindClient), oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(semconv.HTTPClientAttributesFromHTTPRequest(req)...), oteltrace.WithAttributes(semconv.HTTPClientAttributesFromHTTPRequest(req)...),
) )
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
httpSpan.RecordError(err) httpSpan.SetStatus(err)
tracing.StopSpan(httpSpan) httpSpan.End()
return nil, fmt.Errorf("failed to do request: %w", err) return nil, fmt.Errorf("failed to do request: %w", err)
} }
httpSpan.SetAttributes(semconv.HTTPAttributesFromHTTPStatusCode(resp.StatusCode)...) httpSpan.SetAttributes(semconv.HTTPAttributesFromHTTPStatusCode(resp.StatusCode)...)
tracing.StopSpan(httpSpan) httpSpan.End()
log.G(ctx).WithFields(responseFields(resp)).Debug("fetch response received") log.G(ctx).WithFields(responseFields(resp)).Debug("fetch response received")
return resp, nil return resp, nil
} }

View File

@ -19,10 +19,19 @@ package tracing
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"strings"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
) )
const (
spanDelimiter = "."
)
func makeSpanName(names ...string) string {
return strings.Join(names, spanDelimiter)
}
func any(k string, v interface{}) attribute.KeyValue { func any(k string, v interface{}) attribute.KeyValue {
if v == nil { if v == nil {
return attribute.String(k, "<nil>") return attribute.String(k, "<nil>")

View File

@ -25,35 +25,62 @@ import (
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
) )
// StartSpan starts child span in a context. // StartSan starts child span in a context.
func StartSpan(ctx context.Context, opName string, opts ...trace.SpanStartOption) (context.Context, trace.Span) { func StartSpan(ctx context.Context, opName string, opts ...trace.SpanStartOption) (context.Context, *Span) {
tracer := otel.Tracer("")
if parent := trace.SpanFromContext(ctx); parent != nil && parent.SpanContext().IsValid() { if parent := trace.SpanFromContext(ctx); parent != nil && parent.SpanContext().IsValid() {
return parent.TracerProvider().Tracer("").Start(ctx, opName, opts...) tracer = parent.TracerProvider().Tracer("")
} }
return otel.Tracer("").Start(ctx, opName, opts...) ctx, span := tracer.Start(ctx, opName, opts...)
return ctx, &Span{otelSpan: span}
} }
// StopSpan ends the span specified // SpanFromContext returns the current Span from the context.
func StopSpan(span trace.Span) { func SpanFromContext(ctx context.Context) *Span {
span.End() return &Span{
otelSpan: trace.SpanFromContext(ctx),
}
} }
// CurrentSpan returns current span from context or noopSpan if no span exists. // Span is wrapper around otel trace.Span.
func CurrentSpan(ctx context.Context) trace.Span { // Span is the individual component of a trace. It represents a
return trace.SpanFromContext(ctx) // single named and timed operation of a workflow that is traced.
type Span struct {
otelSpan trace.Span
}
// End completes the span.
func (s *Span) End() {
s.otelSpan.End()
}
// AddEvent adds an event with provided name and options.
func (s *Span) AddEvent(name string, options ...trace.EventOption) {
s.otelSpan.AddEvent(name, options...)
} }
// SetSpanStatus sets the status of the current span. // SetSpanStatus sets the status of the current span.
// If an error is encountered, it records the error and sets span status to Error. // If an error is encountered, it records the error and sets span status to Error.
func SetSpanStatus(span trace.Span, err error) { func (s *Span) SetStatus(err error) {
if err != nil { if err != nil {
span.RecordError(err) s.otelSpan.RecordError(err)
span.SetStatus(codes.Error, err.Error()) s.otelSpan.SetStatus(codes.Error, err.Error())
} else { } else {
span.SetStatus(codes.Ok, "") s.otelSpan.SetStatus(codes.Ok, "")
} }
} }
func SpanAttribute(k string, v interface{}) attribute.KeyValue { // SetAttributes sets kv as attributes of the span.
func (s *Span) SetAttributes(kv ...attribute.KeyValue) {
s.otelSpan.SetAttributes(kv...)
}
// Name sets the span name by joining a list of strings in dot separated format.
func Name(names ...string) string {
return makeSpanName(names...)
}
// Attribute takes a key value pair and returns attribute.KeyValue type.
func Attribute(k string, v interface{}) attribute.KeyValue {
return any(k, v) return any(k, v)
} }