mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-19 09:48:32 -05:00
tracing: Centralize our OpenTelemetry package imports
OpenTelemetry has various Go packages split across several Go modules that often need to be carefully upgraded together. And in particular, we are using the "semconv" package in conjunction with the OpenTelemetry SDK's "resource" package in a way that requires that they both agree on which version of the OpenTelemetry Semantic Conventions are being followed. To help avoid "dependency hell" situations when upgrading, this centralizes all of our direct calls into the OpenTelemetry SDK and tracing API into packages under internal/tracing, by exposing a few thin wrapper functions that other packages can use to access the same functionality indirectly. We only use a relatively small subset of the OpenTelemetry library surface area, so we don't need too many of these reexports and they should not represent a significant additional maintenance burden. For the semconv and resource interaction in particular this also factors that out into a separate helper function with a unit test, so we should notice quickly whenever they become misaligned. This complements the end-to-end test previously added in opentofu/opentofu#3447 to give us faster feedback about this particular problem, while the end-to-end test has the broader scope of making sure there aren't any errors at all when initializing OpenTelemetry tracing. Finally, this also replaces the constants we previously had in package traceaddrs with functions that return attribute.KeyValue values directly. This matches the API style used by the OpenTelemetry semconv packages, and makes the calls to these helpers from elsewhere in the system a little more concise. Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
This commit is contained in:
@@ -15,8 +15,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
orasRemote "oras.land/oras-go/v2/registry/remote"
|
orasRemote "oras.land/oras-go/v2/registry/remote"
|
||||||
orasAuth "oras.land/oras-go/v2/registry/remote/auth"
|
orasAuth "oras.land/oras-go/v2/registry/remote/auth"
|
||||||
orasCreds "oras.land/oras-go/v2/registry/remote/credentials"
|
orasCreds "oras.land/oras-go/v2/registry/remote/credentials"
|
||||||
@@ -27,6 +25,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/getproviders"
|
"github.com/opentofu/opentofu/internal/getproviders"
|
||||||
"github.com/opentofu/opentofu/internal/httpclient"
|
"github.com/opentofu/opentofu/internal/httpclient"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ociCredsPolicyBuilder is the type of a callback function that the [providerSource]
|
// ociCredsPolicyBuilder is the type of a callback function that the [providerSource]
|
||||||
@@ -77,9 +76,9 @@ func getOCIRepositoryStore(ctx context.Context, registryDomain, repositoryName s
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Authenticate to OCI Registry",
|
ctx, "Authenticate to OCI Registry",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.oci.registry.domain", registryDomain),
|
traceattrs.String("opentofu.oci.registry.domain", registryDomain),
|
||||||
otelAttr.String("opentofu.oci.repository.name", repositoryName),
|
traceattrs.String("opentofu.oci.repository.name", repositoryName),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -189,9 +188,9 @@ func (o ociCredentialsLookupEnv) QueryDockerCredentialHelper(ctx context.Context
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Query Docker-style credential helper",
|
ctx, "Query Docker-style credential helper",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.oci.docker_credential_helper.name", helperName),
|
traceattrs.String("opentofu.oci.docker_credential_helper.name", helperName),
|
||||||
otelAttr.String("opentofu.oci.registry.url", serverURL),
|
traceattrs.String("opentofu.oci.registry.url", serverURL),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -203,14 +202,14 @@ func (o ociCredentialsLookupEnv) QueryDockerCredentialHelper(ctx context.Context
|
|||||||
// than "Docker-style Credential Helper", but it's the
|
// than "Docker-style Credential Helper", but it's the
|
||||||
// same protocol nonetheless.
|
// same protocol nonetheless.
|
||||||
|
|
||||||
var executeSpan otelTrace.Span // ORAS tracing API can't directly propagate span from Start to Done
|
var executeSpan tracing.Span // ORAS tracing API can't directly propagate span from Start to Done
|
||||||
ctx = orasCredsTrace.WithExecutableTrace(ctx, &orasCredsTrace.ExecutableTrace{
|
ctx = orasCredsTrace.WithExecutableTrace(ctx, &orasCredsTrace.ExecutableTrace{
|
||||||
ExecuteStart: func(executableName, action string) {
|
ExecuteStart: func(executableName, action string) {
|
||||||
_, executeSpan = tracing.Tracer().Start(
|
_, executeSpan = tracing.Tracer().Start(
|
||||||
ctx, "Execute helper program",
|
ctx, "Execute helper program",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.oci.docker_credential_helper.executable", helperName),
|
traceattrs.String("opentofu.oci.docker_credential_helper.executable", helperName),
|
||||||
otelAttr.String("opentofu.oci.registry.url", serverURL),
|
traceattrs.String("opentofu.oci.registry.url", serverURL),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
log.Printf("[DEBUG] Executing docker-style credentials helper %q for %s", helperName, serverURL)
|
log.Printf("[DEBUG] Executing docker-style credentials helper %q for %s", helperName, serverURL)
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
This document describes how to use and implement tracing in OpenTofu Core using OpenTelemetry.
|
This document describes how to use and implement tracing in OpenTofu Core using OpenTelemetry.
|
||||||
|
|
||||||
> [!NOTE]
|
There's background information on OpenTofu's tracing implementation in [the OpenTelemetry Tracing RFC](https://github.com/opentofu/opentofu/blob/main/rfc/20250129-Tracing-For-Extra-Context.md)
|
||||||
> For background on the design decisions and motivation behind OpenTofu's tracing implementation, see the [OpenTelemetry Tracing RFC](https://github.com/opentofu/opentofu/blob/main/rfc/20250129-Tracing-For-Extra-Context.md).
|
|
||||||
|
|
||||||
> [!NOTE]
|
> [!WARNING]
|
||||||
> If you are upgrading any dependent libraries which pull in a new OTEL version, you *MUST* update the semconv version in tracing/init.go to the latest version.
|
> If you change which version of the `go.opentelemetry.io/otel/sdk` we have selected in our `go.mod`, you **must** make sure that `internal/tracing/traceattrs/semconv.go` imports the same subpackage of `go.opentelemetry.io/otel/semconv/*` that is used by the selected version of `go.opentelemetry.io/otel/sdk`.
|
||||||
> Failing to do this will result in an error "Could not initialize telemetry: failed to create resource: error detecting resource: conflicting Schema URL".
|
>
|
||||||
> This sets the *maximum* supported schema version in our OTEL context. Semconv is backwards compatible with older versions, but the newest must be specified.
|
> This is important because our tracing setup uses a blend of directly-constructed `semconv` attributes and attributes chosen indirectly through the `resource` package, and they must all be using the same version of the semantic conventions schema or there will be a "conflicting Schema URL" error at runtime.
|
||||||
|
>
|
||||||
|
> (Problems of this sort should be detected both by a unit test in `internal/tracing/traceattrs` and an end-to-end test that executes OpenTofu with tracing enabled.)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ Then configure OpenTofu as shown above and access the Jaeger UI at http://localh
|
|||||||
## Adding Tracing to OpenTofu Code
|
## Adding Tracing to OpenTofu Code
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> **For Contributors**: When adding tracing to OpenTofu, remember that the primary audience is **end users** who need to understand performance, not developers. Add spans sparingly to avoid polluting traces with too much detail.
|
> **For Contributors**: When adding tracing to OpenTofu, remember that the primary audience is **end users** who need to understand performance, not OpenTofu developers. Add spans sparingly to avoid polluting traces with too much detail.
|
||||||
|
|
||||||
### Basic Span Creation
|
### Basic Span Creation
|
||||||
|
|
||||||
@@ -69,19 +70,25 @@ Then configure OpenTofu as shown above and access the Jaeger UI at http://localh
|
|||||||
import (
|
import (
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute" // Note the alias
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func SomeFunction(ctx context.Context) error {
|
func SomeFunction(ctx context.Context) error {
|
||||||
// Create a new span
|
// Create a new span
|
||||||
ctx, span := tracing.Tracer().Start(ctx, "Human readable operation name")
|
ctx, span := tracing.Tracer().Start(ctx, "Human readable operation name",
|
||||||
|
tracing.SpanAttributes(
|
||||||
|
traceattrs.String("opentofu.some_attribute", "value")
|
||||||
|
),
|
||||||
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
// Add attributes to provide context
|
// Optionally add additional attributes after the span is created, if
|
||||||
span.SetAttributes(otelAttr.String("opentofu.some.attribute", "value"))
|
// they only need to appear in certain cases.
|
||||||
|
span.SetAttributes(traceattrs.String("opentofu.some_other_attribute", "value"))
|
||||||
|
|
||||||
// Using predefined attributes from traceattrs package
|
// Use the more specific attribute-construction helpers from package
|
||||||
span.SetAttributes(otelAttr.String(traceattrs.ProviderAddress, "hashicorp/aws"))
|
// traceattrs where they are relevant, to ensure we follow consistent
|
||||||
|
// semantic conventions for cross-cutting concerns.
|
||||||
|
span.SetAttributes(traceattrs.OpenTofuProviderAddress("hashicorp/aws"))
|
||||||
|
|
||||||
// Your function logic here...
|
// Your function logic here...
|
||||||
|
|
||||||
@@ -95,9 +102,14 @@ func SomeFunction(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!TIP]
|
OpenTelemetry has many different packages spread across a variety of different Go modules, and those different modules often need to be upgraded together to ensure consistent behavior and avoid errors at runtime.
|
||||||
> We should use the `otelAttr` alias for OpenTelemetry's attribute package to clearly distinguish it from OpenTofu's trace attribute constants in the `traceattrs` package.
|
|
||||||
> This convention makes the code more readable and prevents import conflicts.
|
Therefore we prefer to directly import `go.opentelemetry.io/otel/*` packages only from our packages under `internal/tracing`, and then reexport certain functions from our own packages so that we can manage all of the OpenTelemetry dependencies in a centralized place to minimize "dependency hell" problems when upgrading. Packages under `go.opentelemetry.io/contrib/instrumentation/*` are an exception because they tend to be more tightly-coupled to whatever they are instrumenting than to the other OpenTelemetry packages, and so it's better to import those from the same file that's importing whatever other package the instrumentation is being applied to.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Don't import `go.opentelemetry.io/otel/semconv/*` packages from anywhere except `internal/tracing/traceattrs/semconv.go`!
|
||||||
|
>
|
||||||
|
> If you want to use standard OpenTelemetry semantic conventions from other packages, use them indirectly through reexports in `package traceattrs` instead, so we can make sure there's only one file in OpenTofu deciding which version of semconv we are currently depending on.
|
||||||
|
|
||||||
### Tracing Conventions
|
### Tracing Conventions
|
||||||
|
|
||||||
@@ -110,17 +122,10 @@ func SomeFunction(ctx context.Context) error {
|
|||||||
|
|
||||||
#### Attributes
|
#### Attributes
|
||||||
|
|
||||||
- Prefer standard [OpenTelemetry semantic conventions](https://opentelemetry.io/docs/specs/semconv/) where applicable
|
- Prefer standard [OpenTelemetry semantic conventions](https://opentelemetry.io/docs/specs/semconv/) where applicable, using helper functions from [`internal/tracing/traceattrs`](https://pkg.go.dev/github.com/opentofu/opentofu/internal/tracing/traceattrs).
|
||||||
- Follow the [OpenTelemetry attribute naming convention](https://opentelemetry.io/docs/specs/semconv/general/naming/)
|
- Use `OpenTofu`-prefixed functions in [`internal/tracing/traceattrs`](https://pkg.go.dev/github.com/opentofu/opentofu/internal/tracing/traceattrs) for OpenTofu-specific cross-cutting concerns.
|
||||||
- Cross-cutting attributes are defined in `internal/tracing/traceattrs`
|
- It's okay to use one-off inline strings for attribute names specific to a single span, but make sure to still follow the [OpenTelemetry attribute naming conventions](https://opentelemetry.io/docs/specs/semconv/general/naming/) and use the `opentofu.` prefix for anything that is not a standardized semantic convention.
|
||||||
|
- If a particular subsystem of OpenTofu has some repeated conventions for attribute names, consider creating unexported string constants or attribute construction helper functions in the same package to centralize those naming conventions.
|
||||||
```go
|
|
||||||
// Good attribute names
|
|
||||||
"opentofu.provider.address" // For provider addresses
|
|
||||||
"opentofu.module.source" // For module sources
|
|
||||||
"opentofu.operation.target_count" // For operation-specific counts
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
#### Error Handling
|
#### Error Handling
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ import (
|
|||||||
"github.com/opentofu/svchost"
|
"github.com/opentofu/svchost"
|
||||||
"github.com/posener/complete"
|
"github.com/posener/complete"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/backend"
|
"github.com/opentofu/opentofu/internal/backend"
|
||||||
@@ -36,6 +34,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/tofu"
|
"github.com/opentofu/opentofu/internal/tofu"
|
||||||
"github.com/opentofu/opentofu/internal/tofumigrate"
|
"github.com/opentofu/opentofu/internal/tofumigrate"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
tfversion "github.com/opentofu/opentofu/version"
|
tfversion "github.com/opentofu/opentofu/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -164,8 +163,8 @@ func (c *InitCommand) Run(args []string) int {
|
|||||||
ShowLocalPaths: false, // since they are in a weird location for init
|
ShowLocalPaths: false, // since they are in a weird location for init
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(ctx, "From module", trace.WithAttributes(
|
ctx, span := tracing.Tracer().Start(ctx, "From module", tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.module_source", src),
|
traceattrs.OpenTofuModuleSource(src),
|
||||||
))
|
))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@@ -407,8 +406,8 @@ func (c *InitCommand) getModules(ctx context.Context, path, testsDir string, ear
|
|||||||
return false, false, nil
|
return false, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(ctx, "Get Modules", trace.WithAttributes(
|
ctx, span := tracing.Tracer().Start(ctx, "Get Modules", tracing.SpanAttributes(
|
||||||
otelAttr.Bool("opentofu.modules.upgrade", upgrade),
|
traceattrs.Bool("opentofu.modules.upgrade", upgrade),
|
||||||
))
|
))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,13 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/depsfile"
|
"github.com/opentofu/opentofu/internal/depsfile"
|
||||||
"github.com/opentofu/opentofu/internal/getproviders"
|
"github.com/opentofu/opentofu/internal/getproviders"
|
||||||
"github.com/opentofu/opentofu/internal/providercache"
|
"github.com/opentofu/opentofu/internal/providercache"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type providersLockChangeType string
|
type providersLockChangeType string
|
||||||
@@ -61,12 +60,12 @@ func (c *ProvidersLockCommand) Run(args []string) int {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
span.SetAttributes(otelAttr.StringSlice("opentofu.provider.lock.targetplatforms", optPlatforms))
|
span.SetAttributes(traceattrs.StringSlice("opentofu.provider.lock.targetplatforms", optPlatforms))
|
||||||
if fsMirrorDir != "" {
|
if fsMirrorDir != "" {
|
||||||
span.SetAttributes(otelAttr.String("opentofu.provider.lock.fsmirror", fsMirrorDir))
|
span.SetAttributes(traceattrs.String("opentofu.provider.lock.fsmirror", fsMirrorDir))
|
||||||
}
|
}
|
||||||
if netMirrorURL != "" {
|
if netMirrorURL != "" {
|
||||||
span.SetAttributes(otelAttr.String("opentofu.provider.lock.netmirror", netMirrorURL))
|
span.SetAttributes(traceattrs.String("opentofu.provider.lock.netmirror", netMirrorURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
var diags tfdiags.Diagnostics
|
var diags tfdiags.Diagnostics
|
||||||
@@ -88,7 +87,7 @@ func (c *ProvidersLockCommand) Run(args []string) int {
|
|||||||
if len(optPlatforms) == 0 {
|
if len(optPlatforms) == 0 {
|
||||||
platforms = []getproviders.Platform{getproviders.CurrentPlatform}
|
platforms = []getproviders.Platform{getproviders.CurrentPlatform}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.StringSlice("opentofu.provider.lock.targetplatforms", []string{getproviders.CurrentPlatform.String()}),
|
traceattrs.StringSlice("opentofu.provider.lock.targetplatforms", []string{getproviders.CurrentPlatform.String()}),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
platforms = make([]getproviders.Platform, 0, len(optPlatforms))
|
platforms = make([]getproviders.Platform, 0, len(optPlatforms))
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/backend"
|
"github.com/opentofu/opentofu/internal/backend"
|
||||||
"github.com/opentofu/opentofu/internal/cloud"
|
"github.com/opentofu/opentofu/internal/cloud"
|
||||||
"github.com/opentofu/opentofu/internal/cloud/cloudplan"
|
"github.com/opentofu/opentofu/internal/cloud/cloudplan"
|
||||||
@@ -29,6 +26,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tofu"
|
"github.com/opentofu/opentofu/internal/tofu"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Many of the methods we get data from can emit special error types if they're
|
// Many of the methods we get data from can emit special error types if they're
|
||||||
@@ -76,11 +74,11 @@ func (c *ShowCommand) Run(rawArgs []string) int {
|
|||||||
|
|
||||||
//nolint:ineffassign - As this is a high-level call, we want to ensure that we are correctly using the right ctx later on when
|
//nolint:ineffassign - As this is a high-level call, we want to ensure that we are correctly using the right ctx later on when
|
||||||
ctx, span := tracing.Tracer().Start(ctx, "Show",
|
ctx, span := tracing.Tracer().Start(ctx, "Show",
|
||||||
trace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.show.view", args.ViewType.String()),
|
traceattrs.String("opentofu.show.view", args.ViewType.String()),
|
||||||
otelAttr.String("opentofu.show.target", args.TargetType.String()),
|
traceattrs.String("opentofu.show.target", args.TargetType.String()),
|
||||||
otelAttr.String("opentofu.show.target_arg", args.TargetArg),
|
traceattrs.String("opentofu.show.target_arg", args.TargetArg),
|
||||||
otelAttr.Bool("opentofu.show.show_sensitive", args.ShowSensitive),
|
traceattrs.Bool("opentofu.show.show_sensitive", args.ShowSensitive),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|||||||
@@ -16,14 +16,13 @@ import (
|
|||||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/hashicorp/hcl/v2/hclwrite"
|
"github.com/hashicorp/hcl/v2/hclwrite"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.30.0"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/getproviders"
|
"github.com/opentofu/opentofu/internal/getproviders"
|
||||||
"github.com/opentofu/opentofu/internal/replacefile"
|
"github.com/opentofu/opentofu/internal/replacefile"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
"github.com/opentofu/opentofu/version"
|
"github.com/opentofu/opentofu/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -95,7 +94,9 @@ func loadLocks(loadParse func(*hclparse.Parser) (*hcl.File, hcl.Diagnostics)) (*
|
|||||||
// temporary files may be temporarily created in the same directory as the
|
// temporary files may be temporarily created in the same directory as the
|
||||||
// given filename during the operation.
|
// given filename during the operation.
|
||||||
func SaveLocksToFile(ctx context.Context, locks *Locks, filename string) tfdiags.Diagnostics {
|
func SaveLocksToFile(ctx context.Context, locks *Locks, filename string) tfdiags.Diagnostics {
|
||||||
_, span := tracing.Tracer().Start(ctx, "Save lockfile", trace.WithAttributes(semconv.FileName(filename)))
|
_, span := tracing.Tracer().Start(ctx, "Save lockfile", tracing.SpanAttributes(
|
||||||
|
traceattrs.FilePath(filename),
|
||||||
|
))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
src, diags := SaveLocksToBytes(locks)
|
src, diags := SaveLocksToBytes(locks)
|
||||||
@@ -105,7 +106,7 @@ func SaveLocksToFile(ctx context.Context, locks *Locks, filename string) tfdiags
|
|||||||
}
|
}
|
||||||
|
|
||||||
span.AddEvent("Serialized lockfile")
|
span.AddEvent("Serialized lockfile")
|
||||||
span.SetAttributes(semconv.FileSize(len(src)))
|
span.SetAttributes(traceattrs.FileSize(len(src)))
|
||||||
|
|
||||||
err := replacefile.AtomicWriteFile(filename, src, 0644)
|
err := replacefile.AtomicWriteFile(filename, src, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -10,12 +10,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"maps"
|
"maps"
|
||||||
|
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.30.0"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
getter "github.com/hashicorp/go-getter"
|
getter "github.com/hashicorp/go-getter"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/httpclient"
|
"github.com/opentofu/opentofu/internal/httpclient"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PackageFetcher is a low-level utility for fetching remote module packages
|
// PackageFetcher is a low-level utility for fetching remote module packages
|
||||||
@@ -90,7 +89,7 @@ func NewPackageFetcher(ctx context.Context, env PackageFetcherEnvironment) *Pack
|
|||||||
// getmodules.SplitPackageSubdir and getmodules.ExpandSubdirGlobs functions.
|
// getmodules.SplitPackageSubdir and getmodules.ExpandSubdirGlobs functions.
|
||||||
func (f *PackageFetcher) FetchPackage(ctx context.Context, instDir string, packageAddr string) error {
|
func (f *PackageFetcher) FetchPackage(ctx context.Context, instDir string, packageAddr string) error {
|
||||||
ctx, span := tracing.Tracer().Start(ctx, "Fetch Package",
|
ctx, span := tracing.Tracer().Start(ctx, "Fetch Package",
|
||||||
trace.WithAttributes(semconv.URLFull(packageAddr)),
|
tracing.SpanAttributes(traceattrs.URLFull(packageAddr)),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
err := f.getter.getWithGoGetter(ctx, instDir, packageAddr)
|
err := f.getter.getWithGoGetter(ctx, instDir, packageAddr)
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ import (
|
|||||||
getter "github.com/hashicorp/go-getter"
|
getter "github.com/hashicorp/go-getter"
|
||||||
ociDigest "github.com/opencontainers/go-digest"
|
ociDigest "github.com/opencontainers/go-digest"
|
||||||
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
orasContent "oras.land/oras-go/v2/content"
|
orasContent "oras.land/oras-go/v2/content"
|
||||||
orasRegistry "oras.land/oras-go/v2/registry"
|
orasRegistry "oras.land/oras-go/v2/registry"
|
||||||
|
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ociImageManifestArtifactType is the artifact type we expect for the image
|
// ociImageManifestArtifactType is the artifact type we expect for the image
|
||||||
@@ -71,9 +71,9 @@ func (g *ociDistributionGetter) Get(destDir string, url *url.URL) error {
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Fetch 'oci' module package",
|
ctx, "Fetch 'oci' module package",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.module.source", url.String()),
|
traceattrs.String("opentofu.module.source", url.String()),
|
||||||
otelAttr.String("opentofu.module.local_dir", destDir),
|
traceattrs.String("opentofu.module.local_dir", destDir),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -220,9 +220,9 @@ func (g *ociDistributionGetter) resolveRepositoryRef(url *url.URL) (*orasRegistr
|
|||||||
func (g *ociDistributionGetter) resolveManifestDescriptor(ctx context.Context, ref *orasRegistry.Reference, query url.Values, store OCIRepositoryStore) (desc ociv1.Descriptor, err error) {
|
func (g *ociDistributionGetter) resolveManifestDescriptor(ctx context.Context, ref *orasRegistry.Reference, query url.Values, store OCIRepositoryStore) (desc ociv1.Descriptor, err error) {
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Resolve reference",
|
ctx, "Resolve reference",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.oci.registry.domain", ref.Registry),
|
traceattrs.String("opentofu.oci.registry.domain", ref.Registry),
|
||||||
otelAttr.String("opentofu.oci.repository.name", ref.Repository),
|
traceattrs.String("opentofu.oci.repository.name", ref.Repository),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -279,7 +279,7 @@ func (g *ociDistributionGetter) resolveManifestDescriptor(ctx context.Context, r
|
|||||||
// If we're starting with a tag name then we need to query the
|
// If we're starting with a tag name then we need to query the
|
||||||
// repository to find out which digest is currently selected.
|
// repository to find out which digest is currently selected.
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String("opentofu.oci.reference.tag", wantTag),
|
traceattrs.String("opentofu.oci.reference.tag", wantTag),
|
||||||
)
|
)
|
||||||
desc, err = store.Resolve(ctx, wantTag)
|
desc, err = store.Resolve(ctx, wantTag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -294,7 +294,7 @@ func (g *ociDistributionGetter) resolveManifestDescriptor(ctx context.Context, r
|
|||||||
// and so we can't exercise this specific case from unit tests
|
// and so we can't exercise this specific case from unit tests
|
||||||
// using in-memory or on-disk fakes. :(
|
// using in-memory or on-disk fakes. :(
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String("opentofu.oci.reference.digest", wantDigest.String()),
|
traceattrs.String("opentofu.oci.reference.digest", wantDigest.String()),
|
||||||
)
|
)
|
||||||
desc, err = store.Resolve(ctx, wantDigest.String())
|
desc, err = store.Resolve(ctx, wantDigest.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -303,9 +303,9 @@ func (g *ociDistributionGetter) resolveManifestDescriptor(ctx context.Context, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String("oci.manifest.digest", desc.Digest.String()),
|
traceattrs.String("oci.manifest.digest", desc.Digest.String()),
|
||||||
otelAttr.String("opentofu.oci.manifest.media_type", desc.MediaType),
|
traceattrs.String("opentofu.oci.manifest.media_type", desc.MediaType),
|
||||||
otelAttr.Int64("opentofu.oci.manifest.size", desc.Size),
|
traceattrs.Int64("opentofu.oci.manifest.size", desc.Size),
|
||||||
)
|
)
|
||||||
|
|
||||||
// The initial request is only required to return a "plain" descriptor,
|
// The initial request is only required to return a "plain" descriptor,
|
||||||
@@ -326,9 +326,9 @@ func (g *ociDistributionGetter) resolveManifestDescriptor(ctx context.Context, r
|
|||||||
func fetchOCIImageManifest(ctx context.Context, desc ociv1.Descriptor, store OCIRepositoryStore) (*ociv1.Manifest, error) {
|
func fetchOCIImageManifest(ctx context.Context, desc ociv1.Descriptor, store OCIRepositoryStore) (*ociv1.Manifest, error) {
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Fetch manifest",
|
ctx, "Fetch manifest",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("oci.manifest.digest", desc.Digest.String()),
|
traceattrs.String("oci.manifest.digest", desc.Digest.String()),
|
||||||
otelAttr.Int64("opentofu.oci.manifest.size", desc.Size),
|
traceattrs.Int64("opentofu.oci.manifest.size", desc.Size),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -356,8 +356,8 @@ func fetchOCIImageManifest(ctx context.Context, desc ociv1.Descriptor, store OCI
|
|||||||
}
|
}
|
||||||
|
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String("opentofu.oci.manifest.media_type", desc.MediaType),
|
traceattrs.String("opentofu.oci.manifest.media_type", desc.MediaType),
|
||||||
otelAttr.String("opentofu.oci.manifest.artifact_type", desc.ArtifactType),
|
traceattrs.String("opentofu.oci.manifest.artifact_type", desc.ArtifactType),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Now we'll make sure that what we decoded seems vaguely sensible before we
|
// Now we'll make sure that what we decoded seems vaguely sensible before we
|
||||||
@@ -454,10 +454,10 @@ func selectOCILayerBlob(descs []ociv1.Descriptor) (ociv1.Descriptor, error) {
|
|||||||
func fetchOCIBlobToTemporaryFile(ctx context.Context, desc ociv1.Descriptor, store orasContent.Fetcher) (tempFile string, err error) {
|
func fetchOCIBlobToTemporaryFile(ctx context.Context, desc ociv1.Descriptor, store orasContent.Fetcher) (tempFile string, err error) {
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Fetch module package",
|
ctx, "Fetch module package",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.oci.blob.digest", desc.Digest.String()),
|
traceattrs.String("opentofu.oci.blob.digest", desc.Digest.String()),
|
||||||
otelAttr.String("opentofu.oci.blob.media_type", desc.MediaType),
|
traceattrs.String("opentofu.oci.blob.media_type", desc.MediaType),
|
||||||
otelAttr.Int64("opentofu.oci.blob.size", desc.Size),
|
traceattrs.Int64("opentofu.oci.blob.size", desc.Size),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import (
|
|||||||
|
|
||||||
"github.com/apparentlymart/go-versions/versions"
|
"github.com/apparentlymart/go-versions/versions"
|
||||||
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
orasErrors "oras.land/oras-go/v2/errdef"
|
orasErrors "oras.land/oras-go/v2/errdef"
|
||||||
orasRegistryErrors "oras.land/oras-go/v2/registry/remote/errcode"
|
orasRegistryErrors "oras.land/oras-go/v2/registry/remote/errcode"
|
||||||
|
|
||||||
@@ -163,8 +161,8 @@ func NewOCIRegistryMirrorSource(
|
|||||||
func (o *OCIRegistryMirrorSource) AvailableVersions(ctx context.Context, provider addrs.Provider) (VersionList, Warnings, error) {
|
func (o *OCIRegistryMirrorSource) AvailableVersions(ctx context.Context, provider addrs.Provider) (VersionList, Warnings, error) {
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Get available versions from oci_mirror",
|
ctx, "Get available versions from oci_mirror",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceattrs.ProviderAddress, provider.String()),
|
traceattrs.OpenTofuProviderAddress(provider.String()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -278,10 +276,10 @@ func errRepresentsOCIProviderNotFound(err error) bool {
|
|||||||
func (o *OCIRegistryMirrorSource) PackageMeta(ctx context.Context, provider addrs.Provider, version Version, target Platform) (PackageMeta, error) {
|
func (o *OCIRegistryMirrorSource) PackageMeta(ctx context.Context, provider addrs.Provider, version Version, target Platform) (PackageMeta, error) {
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Get metadata from oci_mirror",
|
ctx, "Get metadata from oci_mirror",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceattrs.ProviderAddress, provider.String()),
|
traceattrs.OpenTofuProviderAddress(provider.String()),
|
||||||
otelAttr.String(traceattrs.ProviderVersion, version.String()),
|
traceattrs.OpenTofuProviderVersion(version.String()),
|
||||||
otelAttr.String(traceattrs.TargetPlatform, target.String()),
|
traceattrs.OpenTofuTargetPlatform(target.String()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -476,8 +474,8 @@ type OCIRepositoryStore interface {
|
|||||||
func fetchOCIDescriptorForVersion(ctx context.Context, version versions.Version, store OCIRepositoryStore) (ociv1.Descriptor, error) {
|
func fetchOCIDescriptorForVersion(ctx context.Context, version versions.Version, store OCIRepositoryStore) (ociv1.Descriptor, error) {
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Resolve reference",
|
ctx, "Resolve reference",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceattrs.ProviderVersion, version.String()),
|
traceattrs.OpenTofuProviderVersion(version.String()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -495,9 +493,9 @@ func fetchOCIDescriptorForVersion(ctx context.Context, version versions.Version,
|
|||||||
return ociv1.Descriptor{}, prepErr(fmt.Errorf("resolving tag %q: %w", tagName, err))
|
return ociv1.Descriptor{}, prepErr(fmt.Errorf("resolving tag %q: %w", tagName, err))
|
||||||
}
|
}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String("oci.manifest.digest", desc.Digest.String()),
|
traceattrs.String("oci.manifest.digest", desc.Digest.String()),
|
||||||
otelAttr.String("opentofu.oci.reference.tag", tagName),
|
traceattrs.String("opentofu.oci.reference.tag", tagName),
|
||||||
otelAttr.String("opentofu.oci.manifest.media_type", desc.MediaType),
|
traceattrs.String("opentofu.oci.manifest.media_type", desc.MediaType),
|
||||||
)
|
)
|
||||||
// Not all store implementations can return the manifest's artifact type as part
|
// Not all store implementations can return the manifest's artifact type as part
|
||||||
// of the tag-resolution response, so we'll check this early if we can, but
|
// of the tag-resolution response, so we'll check this early if we can, but
|
||||||
@@ -507,7 +505,7 @@ func fetchOCIDescriptorForVersion(ctx context.Context, version versions.Version,
|
|||||||
// one way or another.)
|
// one way or another.)
|
||||||
if desc.ArtifactType != "" && desc.ArtifactType != ociIndexManifestArtifactType {
|
if desc.ArtifactType != "" && desc.ArtifactType != ociIndexManifestArtifactType {
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String("opentofu.oci.manifest.artifact_type", desc.ArtifactType),
|
traceattrs.String("opentofu.oci.manifest.artifact_type", desc.ArtifactType),
|
||||||
)
|
)
|
||||||
switch desc.ArtifactType {
|
switch desc.ArtifactType {
|
||||||
case "application/vnd.opentofu.provider-target":
|
case "application/vnd.opentofu.provider-target":
|
||||||
@@ -546,9 +544,9 @@ func fetchOCIDescriptorForVersion(ctx context.Context, version versions.Version,
|
|||||||
func fetchOCIIndexManifest(ctx context.Context, desc ociv1.Descriptor, store OCIRepositoryStore) (*ociv1.Index, error) {
|
func fetchOCIIndexManifest(ctx context.Context, desc ociv1.Descriptor, store OCIRepositoryStore) (*ociv1.Index, error) {
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Fetch index manifest",
|
ctx, "Fetch index manifest",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("oci.manifest.digest", desc.Digest.String()),
|
traceattrs.String("oci.manifest.digest", desc.Digest.String()),
|
||||||
otelAttr.Int64("opentofu.oci.manifest.size", desc.Size),
|
traceattrs.Int64("opentofu.oci.manifest.size", desc.Size),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -575,8 +573,8 @@ func fetchOCIIndexManifest(ctx context.Context, desc ociv1.Descriptor, store OCI
|
|||||||
return nil, prepErr(fmt.Errorf("invalid manifest content: %w", err))
|
return nil, prepErr(fmt.Errorf("invalid manifest content: %w", err))
|
||||||
}
|
}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String("opentofu.oci.manifest.media_type", manifest.MediaType),
|
traceattrs.String("opentofu.oci.manifest.media_type", manifest.MediaType),
|
||||||
otelAttr.String("opentofu.oci.manifest.artifact_type", manifest.ArtifactType),
|
traceattrs.String("opentofu.oci.manifest.artifact_type", manifest.ArtifactType),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Now we'll make sure that what we decoded seems vaguely sensible before we
|
// Now we'll make sure that what we decoded seems vaguely sensible before we
|
||||||
@@ -598,9 +596,9 @@ func fetchOCIIndexManifest(ctx context.Context, desc ociv1.Descriptor, store OCI
|
|||||||
func fetchOCIImageManifest(ctx context.Context, desc ociv1.Descriptor, store OCIRepositoryStore) (*ociv1.Manifest, error) {
|
func fetchOCIImageManifest(ctx context.Context, desc ociv1.Descriptor, store OCIRepositoryStore) (*ociv1.Manifest, error) {
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Fetch platform-specific manifest",
|
ctx, "Fetch platform-specific manifest",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("oci.manifest.digest", desc.Digest.String()),
|
traceattrs.String("oci.manifest.digest", desc.Digest.String()),
|
||||||
otelAttr.Int64("opentofu.oci.manifest.size", desc.Size),
|
traceattrs.Int64("opentofu.oci.manifest.size", desc.Size),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -627,8 +625,8 @@ func fetchOCIImageManifest(ctx context.Context, desc ociv1.Descriptor, store OCI
|
|||||||
return nil, prepErr(fmt.Errorf("invalid manifest content: %w", err))
|
return nil, prepErr(fmt.Errorf("invalid manifest content: %w", err))
|
||||||
}
|
}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String("opentofu.oci.manifest.media_type", manifest.MediaType),
|
traceattrs.String("opentofu.oci.manifest.media_type", manifest.MediaType),
|
||||||
otelAttr.String("opentofu.oci.manifest.artifact_type", manifest.ArtifactType),
|
traceattrs.String("opentofu.oci.manifest.artifact_type", manifest.ArtifactType),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Now we'll make sure that what we decoded seems vaguely sensible before we
|
// Now we'll make sure that what we decoded seems vaguely sensible before we
|
||||||
|
|||||||
@@ -14,12 +14,11 @@ import (
|
|||||||
|
|
||||||
"github.com/hashicorp/go-getter"
|
"github.com/hashicorp/go-getter"
|
||||||
"github.com/hashicorp/go-retryablehttp"
|
"github.com/hashicorp/go-retryablehttp"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/httpclient"
|
"github.com/opentofu/opentofu/internal/httpclient"
|
||||||
"github.com/opentofu/opentofu/internal/logging"
|
"github.com/opentofu/opentofu/internal/logging"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.30.0"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PackageHTTPURL is a provider package location accessible via HTTP.
|
// PackageHTTPURL is a provider package location accessible via HTTP.
|
||||||
@@ -53,8 +52,8 @@ func (p PackageHTTPURL) String() string { return p.URL }
|
|||||||
func (p PackageHTTPURL) InstallProviderPackage(ctx context.Context, meta PackageMeta, targetDir string, allowedHashes []Hash) (*PackageAuthenticationResult, error) {
|
func (p PackageHTTPURL) InstallProviderPackage(ctx context.Context, meta PackageMeta, targetDir string, allowedHashes []Hash) (*PackageAuthenticationResult, error) {
|
||||||
url := meta.Location.String()
|
url := meta.Location.String()
|
||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(ctx, "Install (http)", trace.WithAttributes(
|
ctx, span := tracing.Tracer().Start(ctx, "Install (http)", tracing.SpanAttributes(
|
||||||
semconv.URLFull(url),
|
traceattrs.URLFull(url),
|
||||||
))
|
))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/hashicorp/go-getter"
|
"github.com/hashicorp/go-getter"
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.30.0"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// We borrow the "unpack a zip file into a target directory" logic from
|
// We borrow the "unpack a zip file into a target directory" logic from
|
||||||
@@ -67,7 +67,7 @@ func (p PackageLocalArchive) InstallProviderPackage(ctx context.Context, meta Pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
filename := meta.Location.String()
|
filename := meta.Location.String()
|
||||||
span.SetAttributes(semconv.FilePath(filename))
|
span.SetAttributes(traceattrs.FilePath(filename))
|
||||||
|
|
||||||
// NOTE: Packages are immutable, but we may want to skip overwriting the existing
|
// NOTE: Packages are immutable, but we may want to skip overwriting the existing
|
||||||
// files in due to specific scenarios defined below.
|
// files in due to specific scenarios defined below.
|
||||||
|
|||||||
@@ -16,11 +16,10 @@ import (
|
|||||||
"github.com/hashicorp/go-getter"
|
"github.com/hashicorp/go-getter"
|
||||||
ociDigest "github.com/opencontainers/go-digest"
|
ociDigest "github.com/opencontainers/go-digest"
|
||||||
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
orasContent "oras.land/oras-go/v2/content"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
orasContent "oras.land/oras-go/v2/content"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ociPackageMediaType is the specific media type we're expecting for the blob
|
// ociPackageMediaType is the specific media type we're expecting for the blob
|
||||||
@@ -88,16 +87,16 @@ func (p PackageOCIBlobArchive) InstallProviderPackage(ctx context.Context, meta
|
|||||||
pkgDesc := p.blobDescriptor
|
pkgDesc := p.blobDescriptor
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Fetch provider package",
|
ctx, "Fetch provider package",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.oci.registry.domain", p.registryDomain),
|
traceattrs.String("opentofu.oci.registry.domain", p.registryDomain),
|
||||||
otelAttr.String("opentofu.oci.repository.name", p.repositoryName),
|
traceattrs.String("opentofu.oci.repository.name", p.repositoryName),
|
||||||
otelAttr.String("opentofu.oci.blob.digest", pkgDesc.Digest.String()),
|
traceattrs.String("opentofu.oci.blob.digest", pkgDesc.Digest.String()),
|
||||||
otelAttr.String("opentofu.oci.blob.media_type", pkgDesc.MediaType),
|
traceattrs.String("opentofu.oci.blob.media_type", pkgDesc.MediaType),
|
||||||
otelAttr.Int64("opentofu.oci.blob.size", pkgDesc.Size),
|
traceattrs.Int64("opentofu.oci.blob.size", pkgDesc.Size),
|
||||||
otelAttr.String("opentofu.provider.local_dir", targetDir),
|
traceattrs.String("opentofu.provider.local_dir", targetDir),
|
||||||
otelAttr.String(traceattrs.ProviderAddress, meta.Provider.String()),
|
traceattrs.OpenTofuProviderAddress(meta.Provider.String()),
|
||||||
otelAttr.String(traceattrs.ProviderVersion, meta.Version.String()),
|
traceattrs.OpenTofuProviderVersion(meta.Version.String()),
|
||||||
otelAttr.String(traceattrs.TargetPlatform, meta.TargetPlatform.String()),
|
traceattrs.OpenTofuTargetPlatform(meta.TargetPlatform.String()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ import (
|
|||||||
"github.com/hashicorp/go-retryablehttp"
|
"github.com/hashicorp/go-retryablehttp"
|
||||||
"github.com/opentofu/svchost"
|
"github.com/opentofu/svchost"
|
||||||
"github.com/opentofu/svchost/svcauth"
|
"github.com/opentofu/svchost/svcauth"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
@@ -67,8 +64,8 @@ func newRegistryClient(ctx context.Context, baseURL *url.URL, creds svcauth.Host
|
|||||||
func (c *registryClient) ProviderVersions(ctx context.Context, addr addrs.Provider) (map[string][]string, []string, error) {
|
func (c *registryClient) ProviderVersions(ctx context.Context, addr addrs.Provider) (map[string][]string, []string, error) {
|
||||||
ctx, span := tracing.Tracer().Start(ctx,
|
ctx, span := tracing.Tracer().Start(ctx,
|
||||||
"List Versions",
|
"List Versions",
|
||||||
trace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceattrs.ProviderAddress, addr.String()),
|
traceattrs.OpenTofuProviderAddress(addr.String()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -79,7 +76,7 @@ func (c *registryClient) ProviderVersions(ctx context.Context, addr addrs.Provid
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
endpointURL := c.baseURL.ResolveReference(endpointPath)
|
endpointURL := c.baseURL.ResolveReference(endpointPath)
|
||||||
span.SetAttributes(semconv.URLFull(endpointURL.String()))
|
span.SetAttributes(traceattrs.URLFull(endpointURL.String()))
|
||||||
req, err := retryablehttp.NewRequest("GET", endpointURL.String(), nil)
|
req, err := retryablehttp.NewRequest("GET", endpointURL.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@@ -167,9 +164,9 @@ func (c *registryClient) PackageMeta(ctx context.Context, provider addrs.Provide
|
|||||||
))
|
))
|
||||||
ctx, span := tracing.Tracer().Start(ctx,
|
ctx, span := tracing.Tracer().Start(ctx,
|
||||||
"Fetch metadata",
|
"Fetch metadata",
|
||||||
trace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceattrs.ProviderAddress, provider.String()),
|
traceattrs.OpenTofuProviderAddress(provider.String()),
|
||||||
otelAttr.String(traceattrs.ProviderVersion, version.String()),
|
traceattrs.OpenTofuProviderVersion(version.String()),
|
||||||
))
|
))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@@ -180,7 +177,7 @@ func (c *registryClient) PackageMeta(ctx context.Context, provider addrs.Provide
|
|||||||
}
|
}
|
||||||
endpointURL := c.baseURL.ResolveReference(endpointPath)
|
endpointURL := c.baseURL.ResolveReference(endpointPath)
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
semconv.URLFull(endpointURL.String()),
|
traceattrs.URLFull(endpointURL.String()),
|
||||||
)
|
)
|
||||||
|
|
||||||
req, err := retryablehttp.NewRequest("GET", endpointURL.String(), nil)
|
req, err := retryablehttp.NewRequest("GET", endpointURL.String(), nil)
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import (
|
|||||||
|
|
||||||
cleanhttp "github.com/hashicorp/go-cleanhttp"
|
cleanhttp "github.com/hashicorp/go-cleanhttp"
|
||||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
"github.com/opentofu/opentofu/version"
|
"github.com/opentofu/opentofu/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ func New(ctx context.Context) *http.Client {
|
|||||||
inner: cli.Transport,
|
inner: cli.Transport,
|
||||||
}
|
}
|
||||||
|
|
||||||
if span := otelTrace.SpanFromContext(ctx); span != nil && span.IsRecording() {
|
if span := tracing.SpanFromContext(ctx); span != nil && span.IsRecording() {
|
||||||
// We consider the presence of an active span -- that is, one whose
|
// We consider the presence of an active span -- that is, one whose
|
||||||
// presence is going to be reported to a trace collector outside of
|
// presence is going to be reported to a trace collector outside of
|
||||||
// the OpenTofu process -- as sufficient signal that generating
|
// the OpenTofu process -- as sufficient signal that generating
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ import (
|
|||||||
version "github.com/hashicorp/go-version"
|
version "github.com/hashicorp/go-version"
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/configs"
|
"github.com/opentofu/opentofu/internal/configs"
|
||||||
@@ -242,10 +240,11 @@ func (i *ModuleInstaller) moduleInstallWalker(_ context.Context, manifest modsdi
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(ctx,
|
ctx, span := tracing.Tracer().Start(ctx,
|
||||||
fmt.Sprintf("Install Module %q", req.Name),
|
fmt.Sprintf("Install Module %q", req.Name),
|
||||||
trace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceattrs.ModuleCallName, req.Name),
|
traceattrs.OpenTofuModuleCallName(req.Name),
|
||||||
otelAttr.String(traceattrs.ModuleSource, req.SourceAddr.String()),
|
traceattrs.OpenTofuModuleSource(req.SourceAddr.String()),
|
||||||
))
|
),
|
||||||
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
log.Printf("[DEBUG] Module installer: begin %s", key)
|
log.Printf("[DEBUG] Module installer: begin %s", key)
|
||||||
@@ -343,7 +342,7 @@ func (i *ModuleInstaller) moduleInstallWalker(_ context.Context, manifest modsdi
|
|||||||
|
|
||||||
case addrs.ModuleSourceLocal:
|
case addrs.ModuleSourceLocal:
|
||||||
log.Printf("[TRACE] ModuleInstaller: %s has local path %q", key, addr.String())
|
log.Printf("[TRACE] ModuleInstaller: %s has local path %q", key, addr.String())
|
||||||
span.SetAttributes(otelAttr.String("opentofu.module.source_type", "local"))
|
span.SetAttributes(traceattrs.String("opentofu.module.source_type", "local"))
|
||||||
mod, mDiags := i.installLocalModule(ctx, req, key, manifest, hooks)
|
mod, mDiags := i.installLocalModule(ctx, req, key, manifest, hooks)
|
||||||
mDiags = maybeImproveLocalInstallError(req, mDiags)
|
mDiags = maybeImproveLocalInstallError(req, mDiags)
|
||||||
diags = append(diags, mDiags...)
|
diags = append(diags, mDiags...)
|
||||||
@@ -351,7 +350,7 @@ func (i *ModuleInstaller) moduleInstallWalker(_ context.Context, manifest modsdi
|
|||||||
|
|
||||||
case addrs.ModuleSourceRegistry:
|
case addrs.ModuleSourceRegistry:
|
||||||
log.Printf("[TRACE] ModuleInstaller: %s is a registry module at %s", key, addr.String())
|
log.Printf("[TRACE] ModuleInstaller: %s is a registry module at %s", key, addr.String())
|
||||||
span.SetAttributes(otelAttr.String("opentofu.module.source_type", "registry"))
|
span.SetAttributes(traceattrs.String("opentofu.module.source_type", "registry"))
|
||||||
mod, v, mDiags := i.installRegistryModule(ctx, req, key, instPath, addr, manifest, hooks, fetcher)
|
mod, v, mDiags := i.installRegistryModule(ctx, req, key, instPath, addr, manifest, hooks, fetcher)
|
||||||
diags = append(diags, mDiags...)
|
diags = append(diags, mDiags...)
|
||||||
return mod, v, diags
|
return mod, v, diags
|
||||||
@@ -426,9 +425,9 @@ func (i *ModuleInstaller) installDescendentModules(ctx context.Context, rootMod
|
|||||||
func (i *ModuleInstaller) installLocalModule(ctx context.Context, req *configs.ModuleRequest, key string, manifest modsdir.Manifest, hooks ModuleInstallHooks) (*configs.Module, hcl.Diagnostics) {
|
func (i *ModuleInstaller) installLocalModule(ctx context.Context, req *configs.ModuleRequest, key string, manifest modsdir.Manifest, hooks ModuleInstallHooks) (*configs.Module, hcl.Diagnostics) {
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
|
|
||||||
_, span := tracing.Tracer().Start(ctx, "Install Local Module",
|
_, span := tracing.Tracer().Start(ctx, "Install Local Module", tracing.SpanAttributes(
|
||||||
trace.WithAttributes(otelAttr.String(traceattrs.ModuleCallName, req.Name)),
|
traceattrs.OpenTofuModuleCallName(req.Name),
|
||||||
trace.WithAttributes(otelAttr.String(traceattrs.ModuleSource, req.SourceAddr.String())),
|
traceattrs.OpenTofuModuleSource(req.SourceAddr.String())),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@@ -508,11 +507,11 @@ var versionRegexp = regexp.MustCompile(version.VersionRegexpRaw)
|
|||||||
func (i *ModuleInstaller) installRegistryModule(ctx context.Context, req *configs.ModuleRequest, key string, instPath string, addr addrs.ModuleSourceRegistry, manifest modsdir.Manifest, hooks ModuleInstallHooks, fetcher *getmodules.PackageFetcher) (*configs.Module, *version.Version, hcl.Diagnostics) {
|
func (i *ModuleInstaller) installRegistryModule(ctx context.Context, req *configs.ModuleRequest, key string, instPath string, addr addrs.ModuleSourceRegistry, manifest modsdir.Manifest, hooks ModuleInstallHooks, fetcher *getmodules.PackageFetcher) (*configs.Module, *version.Version, hcl.Diagnostics) {
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(ctx, "Install Registry Module",
|
ctx, span := tracing.Tracer().Start(ctx, "Install Registry Module", tracing.SpanAttributes(
|
||||||
trace.WithAttributes(otelAttr.String(traceattrs.ModuleCallName, req.Name)),
|
traceattrs.OpenTofuModuleCallName(req.Name),
|
||||||
trace.WithAttributes(otelAttr.String(traceattrs.ModuleSource, req.SourceAddr.String())),
|
traceattrs.OpenTofuModuleSource(req.SourceAddr.String()),
|
||||||
trace.WithAttributes(otelAttr.String(traceattrs.ModuleVersion, req.VersionConstraint.Required.String())),
|
traceattrs.OpenTofuModuleVersion(req.VersionConstraint.Required.String()),
|
||||||
)
|
))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
if i.reg == nil || fetcher == nil {
|
if i.reg == nil || fetcher == nil {
|
||||||
@@ -774,7 +773,7 @@ func (i *ModuleInstaller) installRegistryModule(ctx context.Context, req *config
|
|||||||
return nil, nil, diags
|
return nil, nil, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
span.SetAttributes(otelAttr.String(traceattrs.ModuleSource, realAddr.String()))
|
span.SetAttributes(traceattrs.OpenTofuModuleSource(realAddr.String()))
|
||||||
|
|
||||||
switch realAddr := realAddr.(type) {
|
switch realAddr := realAddr.(type) {
|
||||||
// Only a remote source address is allowed here: a registry isn't
|
// Only a remote source address is allowed here: a registry isn't
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/apparentlymart/go-versions/versions"
|
"github.com/apparentlymart/go-versions/versions"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
copydir "github.com/opentofu/opentofu/internal/copy"
|
copydir "github.com/opentofu/opentofu/internal/copy"
|
||||||
@@ -235,7 +233,7 @@ func (i *Installer) EnsureProviderVersions(ctx context.Context, locks *depsfile.
|
|||||||
// Step 3: For each provider version we've decided we need to install,
|
// Step 3: For each provider version we've decided we need to install,
|
||||||
// install its package into our target cache (possibly via the global cache).
|
// install its package into our target cache (possibly via the global cache).
|
||||||
targetPlatform := i.targetDir.targetPlatform // we inherit this to behave correctly in unit tests
|
targetPlatform := i.targetDir.targetPlatform // we inherit this to behave correctly in unit tests
|
||||||
span.SetAttributes(otelAttr.String(traceattrs.TargetPlatform, targetPlatform.String()))
|
span.SetAttributes(traceattrs.OpenTofuTargetPlatform(targetPlatform.String()))
|
||||||
span.SetName("Install Providers - " + targetPlatform.String())
|
span.SetName("Install Providers - " + targetPlatform.String())
|
||||||
authResults, err := i.ensureProviderVersionsInstall(ctx, locks, reqs, mode, need, targetPlatform, errs)
|
authResults, err := i.ensureProviderVersionsInstall(ctx, locks, reqs, mode, need, targetPlatform, errs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -449,10 +447,10 @@ func (i *Installer) ensureProviderVersionsInstall(
|
|||||||
for provider, version := range need {
|
for provider, version := range need {
|
||||||
traceCtx, span := tracing.Tracer().Start(ctx,
|
traceCtx, span := tracing.Tracer().Start(ctx,
|
||||||
fmt.Sprintf("Install Provider %q", provider.String()),
|
fmt.Sprintf("Install Provider %q", provider.String()),
|
||||||
trace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceattrs.ProviderAddress, provider.String()),
|
traceattrs.OpenTofuProviderAddress(provider.String()),
|
||||||
otelAttr.String(traceattrs.ProviderVersion, version.String()),
|
traceattrs.OpenTofuProviderVersion(version.String()),
|
||||||
otelAttr.String(traceattrs.TargetPlatform, targetPlatform.String()),
|
traceattrs.OpenTofuTargetPlatform(targetPlatform.String()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ import (
|
|||||||
"github.com/hashicorp/go-retryablehttp"
|
"github.com/hashicorp/go-retryablehttp"
|
||||||
"github.com/opentofu/svchost"
|
"github.com/opentofu/svchost"
|
||||||
"github.com/opentofu/svchost/disco"
|
"github.com/opentofu/svchost/disco"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/httpclient"
|
"github.com/opentofu/opentofu/internal/httpclient"
|
||||||
"github.com/opentofu/opentofu/internal/registry/regsrc"
|
"github.com/opentofu/opentofu/internal/registry/regsrc"
|
||||||
@@ -84,11 +82,9 @@ func (c *Client) Discover(ctx context.Context, host svchost.Hostname, serviceID
|
|||||||
|
|
||||||
// ModuleVersions queries the registry for a module, and returns the available versions.
|
// ModuleVersions queries the registry for a module, and returns the available versions.
|
||||||
func (c *Client) ModuleVersions(ctx context.Context, module *regsrc.Module) (*response.ModuleVersions, error) {
|
func (c *Client) ModuleVersions(ctx context.Context, module *regsrc.Module) (*response.ModuleVersions, error) {
|
||||||
ctx, span := tracing.Tracer().Start(ctx, "List Versions",
|
ctx, span := tracing.Tracer().Start(ctx, "List Versions", tracing.SpanAttributes(
|
||||||
trace.WithAttributes(
|
traceattrs.OpenTofuModuleCallName(module.RawName),
|
||||||
otelAttr.String("opentofu.module.name", module.RawName),
|
))
|
||||||
),
|
|
||||||
)
|
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
host, err := module.SvcHost()
|
host, err := module.SvcHost()
|
||||||
@@ -165,13 +161,11 @@ func (c *Client) addRequestCreds(ctx context.Context, host svchost.Hostname, req
|
|||||||
// ModuleLocation find the download location for a specific version module.
|
// ModuleLocation find the download location for a specific version module.
|
||||||
// This returns a string, because the final location may contain special go-getter syntax.
|
// This returns a string, because the final location may contain special go-getter syntax.
|
||||||
func (c *Client) ModuleLocation(ctx context.Context, module *regsrc.Module, version string) (string, error) {
|
func (c *Client) ModuleLocation(ctx context.Context, module *regsrc.Module, version string) (string, error) {
|
||||||
ctx, span := tracing.Tracer().Start(ctx, "Find Module Location",
|
ctx, span := tracing.Tracer().Start(ctx, "Find Module Location", tracing.SpanAttributes(
|
||||||
trace.WithAttributes(
|
traceattrs.OpenTofuModuleCallName(module.RawName),
|
||||||
otelAttr.String(traceattrs.ModuleCallName, module.RawName),
|
traceattrs.OpenTofuModuleSource(module.Module()),
|
||||||
otelAttr.String(traceattrs.ModuleSource, module.Module()),
|
traceattrs.OpenTofuModuleVersion(version),
|
||||||
otelAttr.String(traceattrs.ModuleVersion, version),
|
))
|
||||||
),
|
|
||||||
)
|
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
host, err := module.SvcHost()
|
host, err := module.SvcHost()
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import (
|
|||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/configs"
|
"github.com/opentofu/opentofu/internal/configs"
|
||||||
@@ -21,6 +19,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/states"
|
"github.com/opentofu/opentofu/internal/states"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ApplyOpts are the various options that affect the details of how OpenTofu
|
// ApplyOpts are the various options that affect the details of how OpenTofu
|
||||||
@@ -57,8 +56,8 @@ func (c *Context) Apply(ctx context.Context, plan *plans.Plan, config *configs.C
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, "Apply phase",
|
ctx, "Apply phase",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String("opentofu.plan.mode", plan.UIMode.UIName()),
|
traceattrs.String("opentofu.plan.mode", plan.UIMode.UIName()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
|
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
@@ -29,6 +27,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/states"
|
"github.com/opentofu/opentofu/internal/states"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PlanOpts are the various options that affect the details of how OpenTofu
|
// PlanOpts are the various options that affect the details of how OpenTofu
|
||||||
@@ -150,10 +149,10 @@ func (c *Context) Plan(ctx context.Context, config *configs.Config, prevRunState
|
|||||||
ctx, "Plan phase",
|
ctx, "Plan phase",
|
||||||
)
|
)
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String("opentofu.plan.mode", opts.Mode.UIName()),
|
traceattrs.String("opentofu.plan.mode", opts.Mode.UIName()),
|
||||||
otelAttr.StringSlice("opentofu.plan.target_addrs", tracing.StringSlice(span, slices.Values(opts.Targets))),
|
traceattrs.StringSlice("opentofu.plan.target_addrs", tracing.StringSlice(span, slices.Values(opts.Targets))),
|
||||||
otelAttr.StringSlice("opentofu.plan.exclude_addrs", tracing.StringSlice(span, slices.Values(opts.Excludes))),
|
traceattrs.StringSlice("opentofu.plan.exclude_addrs", tracing.StringSlice(span, slices.Values(opts.Excludes))),
|
||||||
otelAttr.StringSlice("opentofu.plan.force_replace_addrs", tracing.StringSlice(span, slices.Values(opts.ForceReplace))),
|
traceattrs.StringSlice("opentofu.plan.force_replace_addrs", tracing.StringSlice(span, slices.Values(opts.ForceReplace))),
|
||||||
// Additions here should typically be limited only to options that
|
// Additions here should typically be limited only to options that
|
||||||
// significantly change what provider-driven operations we'd perform
|
// significantly change what provider-driven operations we'd perform
|
||||||
// during the planning phase, since that's the main influence on how
|
// during the planning phase, since that's the main influence on how
|
||||||
|
|||||||
@@ -12,14 +12,13 @@ import (
|
|||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/configs/configschema"
|
"github.com/opentofu/opentofu/internal/configs/configschema"
|
||||||
"github.com/opentofu/opentofu/internal/providers"
|
"github.com/opentofu/opentofu/internal/providers"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// traceAttrProviderAddress is a standardized trace span attribute name that we
|
// traceAttrProviderAddress is a standardized trace span attribute name that we
|
||||||
@@ -127,10 +126,10 @@ func (n *NodeApplyableProvider) executeInstance(ctx context.Context, evalCtx Eva
|
|||||||
func (n *NodeApplyableProvider) ValidateProvider(ctx context.Context, evalCtx EvalContext, providerKey addrs.InstanceKey, provider providers.Interface) tfdiags.Diagnostics {
|
func (n *NodeApplyableProvider) ValidateProvider(ctx context.Context, evalCtx EvalContext, providerKey addrs.InstanceKey, provider providers.Interface) tfdiags.Diagnostics {
|
||||||
_, span := tracing.Tracer().Start(
|
_, span := tracing.Tracer().Start(
|
||||||
ctx, "Validate provider configuration",
|
ctx, "Validate provider configuration",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceAttrProviderAddr, n.Addr.Provider.String()),
|
traceattrs.String(traceAttrProviderAddr, n.Addr.Provider.String()),
|
||||||
otelAttr.String(traceAttrProviderConfigAddr, n.Addr.String()),
|
traceattrs.String(traceAttrProviderConfigAddr, n.Addr.String()),
|
||||||
otelAttr.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.Addr, providerKey)),
|
traceattrs.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.Addr, providerKey)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -193,10 +192,10 @@ func (n *NodeApplyableProvider) ValidateProvider(ctx context.Context, evalCtx Ev
|
|||||||
func (n *NodeApplyableProvider) ConfigureProvider(ctx context.Context, evalCtx EvalContext, providerKey addrs.InstanceKey, provider providers.Interface, verifyConfigIsKnown bool) tfdiags.Diagnostics {
|
func (n *NodeApplyableProvider) ConfigureProvider(ctx context.Context, evalCtx EvalContext, providerKey addrs.InstanceKey, provider providers.Interface, verifyConfigIsKnown bool) tfdiags.Diagnostics {
|
||||||
_, span := tracing.Tracer().Start(
|
_, span := tracing.Tracer().Start(
|
||||||
ctx, "Configure provider",
|
ctx, "Configure provider",
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceAttrProviderAddr, n.Addr.Provider.String()),
|
traceattrs.String(traceAttrProviderAddr, n.Addr.Provider.String()),
|
||||||
otelAttr.String(traceAttrProviderConfigAddr, n.Addr.String()),
|
traceattrs.String(traceAttrProviderConfigAddr, n.Addr.String()),
|
||||||
otelAttr.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.Addr, providerKey)),
|
traceattrs.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.Addr, providerKey)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/configs"
|
"github.com/opentofu/opentofu/internal/configs"
|
||||||
"github.com/opentofu/opentofu/internal/instances"
|
"github.com/opentofu/opentofu/internal/instances"
|
||||||
@@ -22,6 +19,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/states"
|
"github.com/opentofu/opentofu/internal/states"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodeApplyableResourceInstance represents a resource instance that is
|
// NodeApplyableResourceInstance represents a resource instance that is
|
||||||
@@ -126,8 +124,8 @@ func (n *NodeApplyableResourceInstance) Execute(ctx context.Context, evalCtx Eva
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, traceNameApplyResourceInstance,
|
ctx, traceNameApplyResourceInstance,
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceAttrResourceInstanceAddr, addr.String()),
|
traceattrs.String(traceAttrResourceInstanceAddr, addr.String()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -161,7 +159,7 @@ func (n *NodeApplyableResourceInstance) Execute(ctx context.Context, evalCtx Eva
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
traceattrs.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Eval info is different depending on what kind of resource this is
|
// Eval info is different depending on what kind of resource this is
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/dag"
|
"github.com/opentofu/opentofu/internal/dag"
|
||||||
@@ -22,6 +20,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/states"
|
"github.com/opentofu/opentofu/internal/states"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConcreteResourceInstanceDeposedNodeFunc is a callback type used to convert
|
// ConcreteResourceInstanceDeposedNodeFunc is a callback type used to convert
|
||||||
@@ -96,9 +95,9 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx context.Context, eva
|
|||||||
|
|
||||||
_, span := tracing.Tracer().Start(
|
_, span := tracing.Tracer().Start(
|
||||||
ctx, traceNamePlanResourceInstance,
|
ctx, traceNamePlanResourceInstance,
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceAttrResourceInstanceAddr, n.Addr.String()),
|
traceattrs.String(traceAttrResourceInstanceAddr, n.Addr.String()),
|
||||||
otelAttr.Bool(traceAttrPlanRefresh, !n.skipRefresh),
|
traceattrs.Bool(traceAttrPlanRefresh, !n.skipRefresh),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -108,7 +107,7 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx context.Context, eva
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
traceattrs.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Read the state for the deposed resource instance
|
// Read the state for the deposed resource instance
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/communicator/shared"
|
"github.com/opentofu/opentofu/internal/communicator/shared"
|
||||||
"github.com/opentofu/opentofu/internal/configs"
|
"github.com/opentofu/opentofu/internal/configs"
|
||||||
@@ -21,6 +18,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/states"
|
"github.com/opentofu/opentofu/internal/states"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodeDestroyResourceInstance represents a resource instance that is to be
|
// NodeDestroyResourceInstance represents a resource instance that is to be
|
||||||
@@ -157,8 +155,8 @@ func (n *NodeDestroyResourceInstance) Execute(ctx context.Context, evalCtx EvalC
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, traceNameApplyResourceInstance,
|
ctx, traceNameApplyResourceInstance,
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceAttrResourceInstanceAddr, addr.String()),
|
traceattrs.String(traceAttrResourceInstanceAddr, addr.String()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -172,7 +170,7 @@ func (n *NodeDestroyResourceInstance) Execute(ctx context.Context, evalCtx EvalC
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
traceattrs.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
||||||
)
|
)
|
||||||
diags = diags.Append(
|
diags = diags.Append(
|
||||||
n.managedResourceExecute(ctx, evalCtx),
|
n.managedResourceExecute(ctx, evalCtx),
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/dag"
|
"github.com/opentofu/opentofu/internal/dag"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/plans"
|
"github.com/opentofu/opentofu/internal/plans"
|
||||||
@@ -62,9 +61,9 @@ func (n *NodePlanDestroyableResourceInstance) Execute(ctx context.Context, evalC
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, traceNamePlanResourceInstance,
|
ctx, traceNamePlanResourceInstance,
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceAttrResourceInstanceAddr, addr.String()),
|
traceattrs.String(traceAttrResourceInstanceAddr, addr.String()),
|
||||||
otelAttr.Bool(traceAttrPlanRefresh, !n.skipRefresh),
|
traceattrs.Bool(traceAttrPlanRefresh, !n.skipRefresh),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -75,7 +74,7 @@ func (n *NodePlanDestroyableResourceInstance) Execute(ctx context.Context, evalC
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
traceattrs.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
||||||
)
|
)
|
||||||
|
|
||||||
switch addr.Resource.Resource.Mode {
|
switch addr.Resource.Resource.Mode {
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ import (
|
|||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/configs"
|
"github.com/opentofu/opentofu/internal/configs"
|
||||||
@@ -28,6 +26,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/states"
|
"github.com/opentofu/opentofu/internal/states"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodePlannableResourceInstance represents a _single_ resource
|
// NodePlannableResourceInstance represents a _single_ resource
|
||||||
@@ -93,10 +92,10 @@ func (n *NodePlannableResourceInstance) Execute(ctx context.Context, evalCtx Eva
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, traceNamePlanResourceInstance,
|
ctx, traceNamePlanResourceInstance,
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceAttrResourceInstanceAddr, addr.String()),
|
traceattrs.String(traceAttrResourceInstanceAddr, addr.String()),
|
||||||
otelAttr.Bool(traceAttrPlanRefresh, !n.skipRefresh),
|
traceattrs.Bool(traceAttrPlanRefresh, !n.skipRefresh),
|
||||||
otelAttr.Bool(traceAttrPlanPlanChanges, !n.skipPlanChanges),
|
traceattrs.Bool(traceAttrPlanPlanChanges, !n.skipPlanChanges),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -107,7 +106,7 @@ func (n *NodePlannableResourceInstance) Execute(ctx context.Context, evalCtx Eva
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
traceattrs.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Eval info is different depending on what kind of resource this is
|
// Eval info is different depending on what kind of resource this is
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/plans"
|
"github.com/opentofu/opentofu/internal/plans"
|
||||||
@@ -20,6 +18,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/states"
|
"github.com/opentofu/opentofu/internal/states"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodePlannableResourceInstanceOrphan represents a resource that is "applyable":
|
// NodePlannableResourceInstanceOrphan represents a resource that is "applyable":
|
||||||
@@ -63,10 +62,10 @@ func (n *NodePlannableResourceInstanceOrphan) Execute(ctx context.Context, evalC
|
|||||||
|
|
||||||
ctx, span := tracing.Tracer().Start(
|
ctx, span := tracing.Tracer().Start(
|
||||||
ctx, traceNamePlanResourceInstance,
|
ctx, traceNamePlanResourceInstance,
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceAttrResourceInstanceAddr, addr.String()),
|
traceattrs.String(traceAttrResourceInstanceAddr, addr.String()),
|
||||||
otelAttr.Bool(traceAttrPlanRefresh, !n.skipRefresh),
|
traceattrs.Bool(traceAttrPlanRefresh, !n.skipRefresh),
|
||||||
otelAttr.Bool(traceAttrPlanPlanChanges, !n.skipPlanChanges),
|
traceattrs.Bool(traceAttrPlanPlanChanges, !n.skipPlanChanges),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@@ -82,7 +81,7 @@ func (n *NodePlannableResourceInstanceOrphan) Execute(ctx context.Context, evalC
|
|||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
span.SetAttributes(
|
span.SetAttributes(
|
||||||
otelAttr.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
traceattrs.String(traceAttrProviderInstanceAddr, traceProviderInstanceAddr(n.ResolvedProvider.ProviderConfig, n.ResolvedProviderKey)),
|
||||||
)
|
)
|
||||||
diags = diags.Append(
|
diags = diags.Append(
|
||||||
n.managedResourceExecute(ctx, evalCtx),
|
n.managedResourceExecute(ctx, evalCtx),
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import (
|
|||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
otelAttr "go.opentelemetry.io/otel/attribute"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/addrs"
|
"github.com/opentofu/opentofu/internal/addrs"
|
||||||
"github.com/opentofu/opentofu/internal/communicator/shared"
|
"github.com/opentofu/opentofu/internal/communicator/shared"
|
||||||
@@ -26,6 +24,7 @@ import (
|
|||||||
"github.com/opentofu/opentofu/internal/provisioners"
|
"github.com/opentofu/opentofu/internal/provisioners"
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
"github.com/opentofu/opentofu/internal/tracing"
|
"github.com/opentofu/opentofu/internal/tracing"
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodeValidatableResource represents a resource that is used for validation
|
// NodeValidatableResource represents a resource that is used for validation
|
||||||
@@ -54,8 +53,8 @@ func (n *NodeValidatableResource) Path() addrs.ModuleInstance {
|
|||||||
func (n *NodeValidatableResource) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
func (n *NodeValidatableResource) Execute(ctx context.Context, evalCtx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
|
||||||
_, span := tracing.Tracer().Start(
|
_, span := tracing.Tracer().Start(
|
||||||
ctx, traceNameValidateResource,
|
ctx, traceNameValidateResource,
|
||||||
otelTrace.WithAttributes(
|
tracing.SpanAttributes(
|
||||||
otelAttr.String(traceAttrConfigResourceAddr, n.Addr.String()),
|
traceattrs.String(traceAttrConfigResourceAddr, n.Addr.String()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|||||||
@@ -15,15 +15,21 @@ import (
|
|||||||
"go.opentelemetry.io/contrib/exporters/autoexport"
|
"go.opentelemetry.io/contrib/exporters/autoexport"
|
||||||
"go.opentelemetry.io/otel"
|
"go.opentelemetry.io/otel"
|
||||||
"go.opentelemetry.io/otel/propagation"
|
"go.opentelemetry.io/otel/propagation"
|
||||||
"go.opentelemetry.io/otel/sdk"
|
|
||||||
"go.opentelemetry.io/otel/sdk/resource"
|
|
||||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||||
|
|
||||||
// This *MUST* always be updated to the latest version when OTEL dependencies are updated in OpenTofu
|
// ---------------------------------------------------------------------
|
||||||
// Failing to do so will prevent OpenTofu from initializing tracing.
|
// DO NOT IMPORT ANY "go.opentelemetry.io/otel/semconv/*" PACKAGES HERE!
|
||||||
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
// ---------------------------------------------------------------------
|
||||||
|
// Instead, use semconv indirectly through wrappers and reexports in
|
||||||
|
// ./traceattrs/semconv.go, because we need to coordinate our chosen
|
||||||
|
// semconv version with the OTel SDK's "resource" package.
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/version"
|
// The version number at the end of this package math MUST match the
|
||||||
|
// semconv version imported by the "go.opentelemetry.io/otel/sdk/resource",
|
||||||
|
// so we will typically need to update this each time we upgrade
|
||||||
|
// the module "go.opentelemetry.io/otel/sdk".
|
||||||
|
|
||||||
|
"github.com/opentofu/opentofu/internal/tracing/traceattrs"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -107,26 +113,7 @@ func OpenTelemetryInit(ctx context.Context) (context.Context, error) {
|
|||||||
serviceName = envServiceName
|
serviceName = envServiceName
|
||||||
}
|
}
|
||||||
|
|
||||||
otelResource, err := resource.New(context.Background(),
|
otelResource, err := traceattrs.NewResource(ctx, serviceName)
|
||||||
// Use built-in detectors to simplify the collation of the racing information
|
|
||||||
resource.WithOS(),
|
|
||||||
resource.WithHost(),
|
|
||||||
resource.WithProcess(),
|
|
||||||
resource.WithSchemaURL(semconv.SchemaURL),
|
|
||||||
resource.WithAttributes(),
|
|
||||||
|
|
||||||
// Add custom service attributes
|
|
||||||
resource.WithAttributes(
|
|
||||||
semconv.ServiceName(serviceName),
|
|
||||||
semconv.ServiceVersion(version.Version),
|
|
||||||
|
|
||||||
// We add in the telemetry SDK information so that we don't end up with
|
|
||||||
// duplicate schema urls that clash
|
|
||||||
semconv.TelemetrySDKName("opentelemetry"),
|
|
||||||
semconv.TelemetrySDKLanguageGo,
|
|
||||||
semconv.TelemetrySDKVersion(sdk.Version()),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, fmt.Errorf("failed to create resource: %w", err)
|
return ctx, fmt.Errorf("failed to create resource: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
42
internal/tracing/traceattrs/generic.go
Normal file
42
internal/tracing/traceattrs/generic.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (c) The OpenTofu Authors
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright (c) 2023 HashiCorp, Inc.
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
package traceattrs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String wraps [attribute.String] just so that we can keep most of our direct
|
||||||
|
// OpenTelemetry package imports centralized in this package where it's
|
||||||
|
// easier to keep our version selections consistent.
|
||||||
|
func String(name string, val string) attribute.KeyValue {
|
||||||
|
return attribute.String(name, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSlice wraps [attribute.StringSlice] just so that we can keep most of
|
||||||
|
// our direct OpenTelemetry package imports centralized in this package where
|
||||||
|
// it's easier to keep our version selections consistent.
|
||||||
|
//
|
||||||
|
// If the items you want to report are not yet assembled into a string slice,
|
||||||
|
// consider using [tracing.StringSlice] with an [iter.Seq[string]] argument
|
||||||
|
// to skip constructing the slice when tracing isn't enabled.
|
||||||
|
func StringSlice(name string, val []string) attribute.KeyValue {
|
||||||
|
return attribute.StringSlice(name, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool wraps [attribute.Bool] just so that we can keep most of our direct
|
||||||
|
// OpenTelemetry package imports centralized in this package where it's
|
||||||
|
// easier to keep our version selections consistent.
|
||||||
|
func Bool(name string, val bool) attribute.KeyValue {
|
||||||
|
return attribute.Bool(name, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64 wraps [attribute.Int64] just so that we can keep most of our direct
|
||||||
|
// OpenTelemetry package imports centralized in this package where it's
|
||||||
|
// easier to keep our version selections consistent.
|
||||||
|
func Int64(name string, val int64) attribute.KeyValue {
|
||||||
|
return attribute.Int64(name, val)
|
||||||
|
}
|
||||||
82
internal/tracing/traceattrs/opentofu.go
Normal file
82
internal/tracing/traceattrs/opentofu.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright (c) The OpenTofu Authors
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright (c) 2023 HashiCorp, Inc.
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
package traceattrs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This file contains some functions representing OpenTofu-specific semantic
|
||||||
|
// conventions, which we use alongside the general OpenTelemetry-specified
|
||||||
|
// semantic conventions.
|
||||||
|
//
|
||||||
|
// These functions tend to take strings that are expected to be the canonical
|
||||||
|
// string representation of some more specific type from elsewhere in OpenTofu,
|
||||||
|
// but we make the caller produce the string representation rather than doing it
|
||||||
|
// inline because this package needs to avoid importing any other packages
|
||||||
|
// from this codebase so that the rest of OpenTofu can use this package without
|
||||||
|
// creating import cycles.
|
||||||
|
//
|
||||||
|
// We only create functions in here for attribute names that we want to use
|
||||||
|
// consistently across many different callers. For one-off attribute names that
|
||||||
|
// are only used in a single kind of span, use the generic functions like
|
||||||
|
// [String], [StringSlice], etc, instead.
|
||||||
|
|
||||||
|
// OpenTofuProviderAddress returns an attribute definition for indicating
|
||||||
|
// which provider is relevant to a particular trace span.
|
||||||
|
//
|
||||||
|
// The given address should be the result of calling [addrs.Provider.String].
|
||||||
|
func OpenTofuProviderAddress(addr string) attribute.KeyValue {
|
||||||
|
return attribute.String("opentofu.provider.address", addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenTofuProviderVersion returns an attribute definition for indicating
|
||||||
|
// which version of a provider is relevant to a particular trace span.
|
||||||
|
//
|
||||||
|
// The given address should be the result of calling
|
||||||
|
// [getproviders.Version.String]. This should typically be used alongside
|
||||||
|
// [OpenTofuProviderAddress] to indicate which provider the version number is
|
||||||
|
// for.
|
||||||
|
func OpenTofuProviderVersion(v string) attribute.KeyValue {
|
||||||
|
return attribute.String("opentofu.provider.version", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenTofuTargetPlatform returns an attribute definition for indicating
|
||||||
|
// which target platform is relevant to a particular trace span.
|
||||||
|
//
|
||||||
|
// The given address should be the result of calling
|
||||||
|
// [getproviders.Platform.String].
|
||||||
|
func OpenTofuTargetPlatform(platform string) attribute.KeyValue {
|
||||||
|
return attribute.String("opentofu.target_platform", platform)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenTofuModuleCallName returns an attribute definition for indicating
|
||||||
|
// the name of a module call that's relevant to a particular trace span.
|
||||||
|
//
|
||||||
|
// The given address should be something that would be valid in the
|
||||||
|
// [addrs.ModuleCall.Name] field.
|
||||||
|
func OpenTofuModuleCallName(name string) attribute.KeyValue {
|
||||||
|
return attribute.String("opentofu.module.name", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenTofuModuleSource returns an attribute definition for indicating
|
||||||
|
// which module source address is relevant to a particular trace span.
|
||||||
|
//
|
||||||
|
// The given address should be the result of calling
|
||||||
|
// [addrs.ModuleSource.String], or any other syntax-compatible representation.
|
||||||
|
func OpenTofuModuleSource(addr string) attribute.KeyValue {
|
||||||
|
return attribute.String("opentofu.module.source", addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenTofuModuleVersion returns an attribute definition for indicating
|
||||||
|
// which version of a module is relevant to a particular trace span.
|
||||||
|
//
|
||||||
|
// The given address should be either the result of calling
|
||||||
|
// [getproviders.Version.String], or the String method from the "Version" type
|
||||||
|
// from HashiCorp's "go-version" library.
|
||||||
|
func OpenTofuModuleVersion(v string) attribute.KeyValue {
|
||||||
|
return attribute.String("opentofu.module.version", v)
|
||||||
|
}
|
||||||
90
internal/tracing/traceattrs/semconv.go
Normal file
90
internal/tracing/traceattrs/semconv.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
// Copyright (c) The OpenTofu Authors
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright (c) 2023 HashiCorp, Inc.
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
package traceattrs
|
||||||
|
|
||||||
|
// This file contains wrappers and reexports of some symbols from the
|
||||||
|
// OpenTelemetry "semconv" package and the "resource" package from the
|
||||||
|
// OpenTelemetry SDK, which we centralize here because their version numbers
|
||||||
|
// must be coordinated carefully to avoid runtime panics of mismatched versions.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
"go.opentelemetry.io/otel/sdk"
|
||||||
|
"go.opentelemetry.io/otel/sdk/resource"
|
||||||
|
|
||||||
|
// The version number at the end of this package path MUST match the
|
||||||
|
// semconv version imported by the "go.opentelemetry.io/otel/sdk/resource",
|
||||||
|
// because we also use some semconv symbols indirectly through that
|
||||||
|
// package, and so we need to update this each time we upgrade the module
|
||||||
|
// "go.opentelemetry.io/otel/sdk".
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
|
||||||
|
|
||||||
|
"github.com/opentofu/opentofu/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewResource constructs a *resource.Resource that should be used when
|
||||||
|
// constructing our global tracer provider.
|
||||||
|
//
|
||||||
|
// This is factored out here because its correct behavior depends on correctly
|
||||||
|
// matching our import of an "go.opentelemetry.io/otel/semconv/*" package
|
||||||
|
// for direct attribute definitions with the version used indirectly by
|
||||||
|
// "go.opentelemetry.io/otel/sdk/resource". If they don't match then this
|
||||||
|
// function will fail with an error.
|
||||||
|
//
|
||||||
|
// The unit test [TestNewResource] runs this function in isolation so we can
|
||||||
|
// make sure it succeeds without having to actually initialize the telemetry
|
||||||
|
// system.
|
||||||
|
func NewResource(ctx context.Context, serviceName string) (*resource.Resource, error) {
|
||||||
|
return resource.New(ctx,
|
||||||
|
// Use built-in detectors to simplify the collation of the tracing information
|
||||||
|
resource.WithOS(),
|
||||||
|
resource.WithHost(),
|
||||||
|
resource.WithProcess(),
|
||||||
|
resource.WithSchemaURL(semconv.SchemaURL),
|
||||||
|
resource.WithAttributes(),
|
||||||
|
|
||||||
|
// Add custom service attributes
|
||||||
|
resource.WithAttributes(
|
||||||
|
semconv.ServiceName(serviceName),
|
||||||
|
semconv.ServiceVersion(version.Version),
|
||||||
|
|
||||||
|
// We add in the telemetry SDK information so that we don't end up with
|
||||||
|
// duplicate schema urls that clash
|
||||||
|
semconv.TelemetrySDKName("opentelemetry"),
|
||||||
|
semconv.TelemetrySDKLanguageGo,
|
||||||
|
semconv.TelemetrySDKVersion(sdk.Version()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLFull returns an attribute representing an absolute URL associated with
|
||||||
|
// a trace span, using the attribute name defined by our currently-selected
|
||||||
|
// version of the OpenTelemetry semantic conventions.
|
||||||
|
//
|
||||||
|
// This wraps [semconv.URLFull].
|
||||||
|
func URLFull(val string) attribute.KeyValue {
|
||||||
|
return semconv.URLFull(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilePath returns an attribute representing an absolute file path associated
|
||||||
|
// with a trace span, using the attribute name defined by our currently-selected
|
||||||
|
// version of the OpenTelemetry semantic conventions.
|
||||||
|
//
|
||||||
|
// This wraps [semconv.FilePath].
|
||||||
|
func FilePath(val string) attribute.KeyValue {
|
||||||
|
return semconv.FilePath(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileSize returns an attribute representing the size in bytes of a file
|
||||||
|
// associated with a trace span, using the attribute name defined by our
|
||||||
|
// currently-selected version of the OpenTelemetry semantic conventions.
|
||||||
|
//
|
||||||
|
// This wraps [semconv.FileSize].
|
||||||
|
func FileSize(val int) attribute.KeyValue {
|
||||||
|
return semconv.FileSize(val)
|
||||||
|
}
|
||||||
18
internal/tracing/traceattrs/semconv_test.go
Normal file
18
internal/tracing/traceattrs/semconv_test.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// Copyright (c) The OpenTofu Authors
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright (c) 2023 HashiCorp, Inc.
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
package traceattrs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewResource(t *testing.T) {
|
||||||
|
_, err := NewResource(t.Context(), "test-service")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create OpenTelemetry SDK resource: %s", err)
|
||||||
|
t.Errorf("If the above error message is about conflicting schema versions, then make sure that the semconv package imported in semconv.go matches the semconv package imported by \"go.opentelemetry.io/otel/sdk/resource\".")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// Copyright (c) The OpenTofu Authors
|
|
||||||
// SPDX-License-Identifier: MPL-2.0
|
|
||||||
// Copyright (c) 2023 HashiCorp, Inc.
|
|
||||||
// SPDX-License-Identifier: MPL-2.0
|
|
||||||
|
|
||||||
package traceattrs
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Common attributes names used across the codebase
|
|
||||||
|
|
||||||
ProviderAddress = "opentofu.provider.address"
|
|
||||||
ProviderVersion = "opentofu.provider.version"
|
|
||||||
|
|
||||||
TargetPlatform = "opentofu.target_platform"
|
|
||||||
|
|
||||||
ModuleCallName = "opentofu.module.name"
|
|
||||||
ModuleSource = "opentofu.module.source"
|
|
||||||
ModuleVersion = "opentofu.module.version"
|
|
||||||
)
|
|
||||||
@@ -14,9 +14,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel"
|
"go.opentelemetry.io/otel"
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/codes"
|
"go.opentelemetry.io/otel/codes"
|
||||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||||
@@ -119,3 +119,26 @@ func extractImportPath(fullName string) string {
|
|||||||
|
|
||||||
return fullName[:lastSlash+dotAfterSlash]
|
return fullName[:lastSlash+dotAfterSlash]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Span is an alias for [trace.Span] just to centralize all of our direct
|
||||||
|
// imports of OpenTelemetry packages into our tracing packages, to help
|
||||||
|
// avoid dependency hell.
|
||||||
|
type Span = trace.Span
|
||||||
|
|
||||||
|
// SpanFromContext returns the trace span asssociated with the given context,
|
||||||
|
// or nil if there is no associated span.
|
||||||
|
//
|
||||||
|
// This is a wrapper around [trace.SpanFromContext] just to centralize all of
|
||||||
|
// our imports of OpenTelemetry packages into our tracing packages, to help
|
||||||
|
// avoid dependency hell.
|
||||||
|
func SpanFromContext(ctx context.Context) trace.Span {
|
||||||
|
return trace.SpanFromContext(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SpanAttributes wraps [trace.WithAttributes] just so that we can minimize
|
||||||
|
// how many different OpenTofu packages directly import the OpenTelemetry
|
||||||
|
// packages, because we tend to need to control which versions we're using
|
||||||
|
// quite closely to avoid dependency hell.
|
||||||
|
func SpanAttributes(attrs ...attribute.KeyValue) trace.SpanStartEventOption {
|
||||||
|
return trace.WithAttributes(attrs...)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user