From 09d5d8836b00c5b87fbaefbd0e109bbadcd19ef0 Mon Sep 17 00:00:00 2001 From: Chelsea Mafrica Date: Fri, 10 Sep 2021 15:01:31 -0700 Subject: [PATCH] runtime: tracing: Change method for adding tags In later versions of OpenTelemetry label.Any() is deprecated. Create addTag() to handle type assertions of values. Change AddTag() to variadic function that accepts multiple keys and values. Fixes #2547 Signed-off-by: Chelsea Mafrica --- src/runtime/pkg/katautils/create.go | 8 +- src/runtime/pkg/katautils/hook.go | 5 +- .../pkg/katautils/katatrace/tracing.go | 78 ++++++++++++++++++- src/runtime/virtcontainers/kata_agent.go | 2 +- src/runtime/virtcontainers/network.go | 11 ++- src/runtime/virtcontainers/qemu.go | 12 +-- src/runtime/virtcontainers/sandbox.go | 3 +- 7 files changed, 93 insertions(+), 26 deletions(-) diff --git a/src/runtime/pkg/katautils/create.go b/src/runtime/pkg/katautils/create.go index 143b2e3367..98079c53aa 100644 --- a/src/runtime/pkg/katautils/create.go +++ b/src/runtime/pkg/katautils/create.go @@ -112,7 +112,7 @@ func SetEphemeralStorageType(ociSpec specs.Spec) specs.Spec { func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeConfig oci.RuntimeConfig, rootFs vc.RootFs, containerID, bundlePath, console string, disableOutput, systemdCgroup bool) (_ vc.VCSandbox, _ vc.Process, err error) { span, ctx := katatrace.Trace(ctx, nil, "CreateSandbox", createTracingTags) - katatrace.AddTag(span, "container_id", containerID) + katatrace.AddTags(span, "container_id", containerID) defer span.End() sandboxConfig, err := oci.SandboxConfig(ociSpec, runtimeConfig, bundlePath, containerID, console, disableOutput, systemdCgroup) @@ -167,7 +167,7 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeCo sid := sandbox.ID() kataUtilsLogger = kataUtilsLogger.WithField("sandbox", sid) - katatrace.AddTag(span, "sandbox_id", sid) + katatrace.AddTags(span, "sandbox_id", sid) containers := sandbox.GetAllContainers() if len(containers) != 1 { @@ -211,7 +211,7 @@ func CreateContainer(ctx context.Context, sandbox vc.VCSandbox, ociSpec specs.Sp var c vc.VCContainer span, ctx := katatrace.Trace(ctx, nil, "CreateContainer", createTracingTags) - katatrace.AddTag(span, "container_id", containerID) + katatrace.AddTags(span, "container_id", containerID) defer span.End() ociSpec = SetEphemeralStorageType(ociSpec) @@ -237,7 +237,7 @@ func CreateContainer(ctx context.Context, sandbox vc.VCSandbox, ociSpec specs.Sp return vc.Process{}, err } - katatrace.AddTag(span, "sandbox_id", sandboxID) + katatrace.AddTags(span, "sandbox_id", sandboxID) c, err = sandbox.CreateContainer(ctx, contConfig) if err != nil { diff --git a/src/runtime/pkg/katautils/hook.go b/src/runtime/pkg/katautils/hook.go index 7933a182e1..62eb81169c 100644 --- a/src/runtime/pkg/katautils/hook.go +++ b/src/runtime/pkg/katautils/hook.go @@ -35,8 +35,7 @@ func hookLogger() *logrus.Entry { func runHook(ctx context.Context, hook specs.Hook, cid, bundlePath string) error { span, _ := katatrace.Trace(ctx, hookLogger(), "runHook", hookTracingTags) defer span.End() - katatrace.AddTag(span, "path", hook.Path) - katatrace.AddTag(span, "args", hook.Args) + katatrace.AddTags(span, "path", hook.Path, "args", hook.Args) state := specs.State{ Pid: syscall.Gettid(), @@ -93,7 +92,7 @@ func runHook(ctx context.Context, hook specs.Hook, cid, bundlePath string) error func runHooks(ctx context.Context, hooks []specs.Hook, cid, bundlePath, hookType string) error { span, ctx := katatrace.Trace(ctx, hookLogger(), "runHooks", hookTracingTags) - katatrace.AddTag(span, "type", hookType) + katatrace.AddTags(span, "type", hookType) defer span.End() for _, hook := range hooks { diff --git a/src/runtime/pkg/katautils/katatrace/tracing.go b/src/runtime/pkg/katautils/katatrace/tracing.go index f7f5f40c30..2c8b3945c2 100644 --- a/src/runtime/pkg/katautils/katatrace/tracing.go +++ b/src/runtime/pkg/katautils/katatrace/tracing.go @@ -7,6 +7,7 @@ package katatrace import ( "context" + "encoding/json" "github.com/sirupsen/logrus" "go.opentelemetry.io/otel" @@ -163,8 +164,77 @@ func Trace(parent context.Context, logger *logrus.Entry, name string, tags ...ma return span, ctx } -// AddTag adds an additional key-value pair to a tracing span. This can be used to -// provide dynamic tags that are determined at runtime. -func AddTag(span otelTrace.Span, key string, value interface{}) { - span.SetAttributes(label.Any(key, value)) +func addTag(span otelTrace.Span, key string, value interface{}) { + // do not append tags if tracing is disabled + if !tracing { + return + } + if value == nil { + span.SetAttributes(label.String(key, "nil")) + return + } + + switch value := value.(type) { + case string: + span.SetAttributes(label.String(key, value)) + case bool: + span.SetAttributes(label.Bool(key, value)) + case int: + span.SetAttributes(label.Int(key, value)) + case int8: + span.SetAttributes(label.Int(key, int(value))) + case int16: + span.SetAttributes(label.Int(key, int(value))) + case int32: + span.SetAttributes(label.Int32(key, value)) + case int64: + span.SetAttributes(label.Int64(key, value)) + case uint: + span.SetAttributes(label.Uint(key, value)) + case uint8: + span.SetAttributes(label.Uint(key, uint(value))) + case uint16: + span.SetAttributes(label.Uint(key, uint(value))) + case uint32: + span.SetAttributes(label.Uint32(key, value)) + case uint64: + span.SetAttributes(label.Uint64(key, value)) + case float32: + span.SetAttributes(label.Float32(key, value)) + case float64: + span.SetAttributes(label.Float64(key, value)) + default: + content, err := json.Marshal(value) + if content == nil && err == nil { + span.SetAttributes(label.String(key, "nil")) + } else if content != nil && err == nil { + span.SetAttributes(label.String(key, string(content))) + } else { + kataTraceLogger.WithField("type", "bug").Error("span attribute value error") + } + } +} + +// AddTag adds additional key-value pairs to a tracing span. This can be used to provide +// dynamic tags that are determined at runtime and tags with a non-string value. +// Must have an even number of keyValues with keys being strings. +func AddTags(span otelTrace.Span, keyValues ...interface{}) { + if !tracing { + return + } + if len(keyValues) < 2 { + kataTraceLogger.WithField("type", "bug").Error("not enough inputs for attributes") + return + } else if len(keyValues)%2 != 0 { + kataTraceLogger.WithField("type", "bug").Error("number of attribute keyValues is not even") + return + } + for i := 0; i < len(keyValues); i++ { + if key, ok := keyValues[i].(string); ok { + addTag(span, key, keyValues[i+1]) + } else { + kataTraceLogger.WithField("type", "bug").Error("key in attributes is not a string") + } + i++ + } } diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index b553159fba..cd0336ee8d 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -344,7 +344,7 @@ func (k *kataAgent) internalConfigure(ctx context.Context, h Hypervisor, id stri } k.keepConn = config.LongLiveConn - katatrace.AddTag(span, "socket", k.vmSocket) + katatrace.AddTags(span, "socket", k.vmSocket) return nil } diff --git a/src/runtime/virtcontainers/network.go b/src/runtime/virtcontainers/network.go index c682418f3b..bf2b09a3ae 100644 --- a/src/runtime/virtcontainers/network.go +++ b/src/runtime/virtcontainers/network.go @@ -1304,10 +1304,10 @@ func getNetworkTrace(networkType EndpointType) func(ctx context.Context, name st return func(ctx context.Context, name string, endpoint interface{}) (otelTrace.Span, context.Context) { span, ctx := katatrace.Trace(ctx, networkLogger(), name, networkTracingTags) if networkType != "" { - katatrace.AddTag(span, "type", string(networkType)) + katatrace.AddTags(span, "type", string(networkType)) } if endpoint != nil { - katatrace.AddTag(span, "endpoint", endpoint) + katatrace.AddTags(span, "endpoint", endpoint) } return span, ctx } @@ -1315,7 +1315,7 @@ func getNetworkTrace(networkType EndpointType) func(ctx context.Context, name st func closeSpan(span otelTrace.Span, err error) { if err != nil { - katatrace.AddTag(span, "error", err) + katatrace.AddTags(span, "error", err.Error()) } span.End() } @@ -1333,15 +1333,14 @@ func (n *Network) Run(ctx context.Context, networkNSPath string, cb func() error // Add adds all needed interfaces inside the network namespace. func (n *Network) Add(ctx context.Context, config *NetworkConfig, s *Sandbox, hotplug bool) ([]Endpoint, error) { span, ctx := n.trace(ctx, "Add") - katatrace.AddTag(span, "type", config.InterworkingModel.GetModel()) + katatrace.AddTags(span, "type", config.InterworkingModel.GetModel()) defer span.End() endpoints, err := createEndpointsFromScan(config.NetNSPath, config) if err != nil { return endpoints, err } - katatrace.AddTag(span, "endpoints", endpoints) - katatrace.AddTag(span, "hotplug", hotplug) + katatrace.AddTags(span, "endpoints", endpoints, "hotplug", hotplug) err = doNetNS(config.NetNSPath, func(_ ns.NetNS) error { for _, endpoint := range endpoints { diff --git a/src/runtime/virtcontainers/qemu.go b/src/runtime/virtcontainers/qemu.go index 25c9b093f2..e3e6ade866 100644 --- a/src/runtime/virtcontainers/qemu.go +++ b/src/runtime/virtcontainers/qemu.go @@ -1726,8 +1726,8 @@ func (q *qemu) hotplugDevice(ctx context.Context, devInfo interface{}, devType D } func (q *qemu) HotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) { - span, ctx := katatrace.Trace(ctx, q.Logger(), "HotplugAddDevice", qemuTracingTags, map[string]string{"sandbox_id": q.id}) - katatrace.AddTag(span, "device", devInfo) + span, ctx := katatrace.Trace(ctx, q.Logger(), "HotplugAddDevice", qemuTracingTags) + katatrace.AddTags(span, "sandbox_id", q.id, "device", devInfo) defer span.End() data, err := q.hotplugDevice(ctx, devInfo, devType, AddDevice) @@ -1739,8 +1739,8 @@ func (q *qemu) HotplugAddDevice(ctx context.Context, devInfo interface{}, devTyp } func (q *qemu) HotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) { - span, ctx := katatrace.Trace(ctx, q.Logger(), "HotplugRemoveDevice", qemuTracingTags, map[string]string{"sandbox_id": q.id}) - katatrace.AddTag(span, "device", devInfo) + span, ctx := katatrace.Trace(ctx, q.Logger(), "HotplugRemoveDevice", qemuTracingTags) + katatrace.AddTags(span, "sandbox_id", q.id, "device", devInfo) defer span.End() data, err := q.hotplugDevice(ctx, devInfo, devType, RemoveDevice) @@ -1968,8 +1968,8 @@ func (q *qemu) ResumeVM(ctx context.Context) error { // addDevice will add extra devices to Qemu command line. func (q *qemu) AddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error { var err error - span, _ := katatrace.Trace(ctx, q.Logger(), "AddDevice", qemuTracingTags, map[string]string{"sandbox_id": q.id}) - katatrace.AddTag(span, "device", devInfo) + span, _ := katatrace.Trace(ctx, q.Logger(), "AddDevice", qemuTracingTags) + katatrace.AddTags(span, "sandbox_id", q.id, "device", devInfo) defer span.End() switch v := devInfo.(type) { diff --git a/src/runtime/virtcontainers/sandbox.go b/src/runtime/virtcontainers/sandbox.go index 66f1a367ba..6b34d597c6 100644 --- a/src/runtime/virtcontainers/sandbox.go +++ b/src/runtime/virtcontainers/sandbox.go @@ -822,8 +822,7 @@ func (s *Sandbox) createNetwork(ctx context.Context) error { NetNsCreated: s.config.NetworkConfig.NetNsCreated, } - katatrace.AddTag(span, "networkNS", s.networkNS) - katatrace.AddTag(span, "NetworkConfig", s.config.NetworkConfig) + katatrace.AddTags(span, "networkNS", s.networkNS, "NetworkConfig", s.config.NetworkConfig) // In case there is a factory, network interfaces are hotplugged // after vm is started.