mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-19 17:59:05 -05:00
Most OpenTofu executions will not have tracing enabled, so it's important that we don't waste time calculating data for trace attributes that will immediately get discarded without being recorded. This commit establishes the first of possibly multiple utilities that take a span and then compute a result only if that span is actually going to be recorded somewhere. This first one is intended for populating StringSlice attributes from collections of objects that implement fmt.Stringer. Both the conversion to string and the construction of the final slice are likely to cause memory allocation, so we'd rather not do any of that work unless trace collection is actually enabled. Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
45 lines
1.4 KiB
Go
45 lines
1.4 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package tracing
|
|
|
|
import (
|
|
"fmt"
|
|
"iter"
|
|
|
|
"go.opentelemetry.io/otel/trace"
|
|
)
|
|
|
|
// This file contains utilities that are not directly related to tracing but
|
|
// that are useful for transforming data to include in trace attributes, etc.
|
|
//
|
|
// These functions all take a span object as their first argument so that
|
|
// they can skip performing expensive work when the span is not actually
|
|
// recording. The documentation of each function describes how its behavior
|
|
// differs when the span is not recording.
|
|
|
|
// StringSlice takes a sequence of any type that implements [fmt.Stringer]
|
|
// and returns a slice containing the results of calling the String method
|
|
// on each item in that sequence.
|
|
//
|
|
// If the given span is not recording then this immediately returns nil
|
|
// without consuming the iterator at all.
|
|
//
|
|
// Use [slices.Values] to use the elements of an existing slice. For example:
|
|
//
|
|
// span.SetAttributes(
|
|
// otelAttr.StringSlice("example", tracing.StringSlice(span, slices.Values(opts.Targets))),
|
|
// )
|
|
func StringSlice[E fmt.Stringer](span trace.Span, items iter.Seq[E]) []string {
|
|
if !span.IsRecording() {
|
|
return nil // shortcut for when tracing is not enabled
|
|
}
|
|
var ret []string
|
|
for item := range items {
|
|
ret = append(ret, item.String())
|
|
}
|
|
return ret
|
|
}
|