github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/telemetry.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  
     7  	"github.com/terramate-io/tf/version"
     8  	"go.opentelemetry.io/contrib/exporters/autoexport"
     9  	"go.opentelemetry.io/otel"
    10  	"go.opentelemetry.io/otel/propagation"
    11  	"go.opentelemetry.io/otel/sdk/resource"
    12  	sdktrace "go.opentelemetry.io/otel/sdk/trace"
    13  	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
    14  	"go.opentelemetry.io/otel/trace"
    15  )
    16  
    17  // If this environment variable is set to "otlp" when running Terraform CLI
    18  // then we'll enable an experimental OTLP trace exporter.
    19  //
    20  // BEWARE! This is not a committed external interface.
    21  //
    22  // Everything about this is experimental and subject to change in future
    23  // releases. Do not depend on anything about the structure of this output.
    24  // This mechanism might be removed altogether if a different strategy seems
    25  // better based on experience with this experiment.
    26  const openTelemetryExporterEnvVar = "OTEL_TRACES_EXPORTER"
    27  
    28  // tracer is the OpenTelemetry tracer to use for traces in package main only.
    29  var tracer trace.Tracer
    30  
    31  func init() {
    32  	tracer = otel.Tracer("github.com/hashicorp/terraform")
    33  }
    34  
    35  // openTelemetryInit initializes the optional OpenTelemetry exporter.
    36  //
    37  // By default we don't export telemetry information at all, since Terraform is
    38  // a CLI tool and so we don't assume we're running in an environment with
    39  // a telemetry collector available.
    40  //
    41  // However, for those running Terraform in automation we allow setting
    42  // the standard OpenTelemetry environment variable OTEL_TRACES_EXPORTER=otlp
    43  // to enable an OTLP exporter, which is in turn configured by all of the
    44  // standard OTLP exporter environment variables:
    45  //
    46  //	https://opentelemetry.io/docs/specs/otel/protocol/exporter/#configuration-options
    47  //
    48  // We don't currently support any other telemetry export protocols, because
    49  // OTLP has emerged as a de-facto standard and each other exporter we support
    50  // means another relatively-heavy external dependency. OTLP happens to use
    51  // protocol buffers and gRPC, which Terraform would depend on for other reasons
    52  // anyway.
    53  func openTelemetryInit() error {
    54  	// We'll check the environment variable ourselves first, because the
    55  	// "autoexport" helper we're about to use is built under the assumption
    56  	// that exporting should always be enabled and so will expect to find
    57  	// an OTLP server on localhost if no environment variables are set at all.
    58  	if os.Getenv(openTelemetryExporterEnvVar) != "otlp" {
    59  		return nil // By default we just discard all telemetry calls
    60  	}
    61  
    62  	otelResource := resource.NewWithAttributes(
    63  		semconv.SchemaURL,
    64  		semconv.ServiceNameKey.String("Terraform CLI"),
    65  		semconv.ServiceVersionKey.String(version.Version),
    66  	)
    67  
    68  	// If the environment variable was set to explicitly enable telemetry
    69  	// then we'll enable it, using the "autoexport" library to automatically
    70  	// handle the details based on the other OpenTelemetry standard environment
    71  	// variables.
    72  	exp, err := autoexport.NewSpanExporter(context.Background())
    73  	if err != nil {
    74  		return err
    75  	}
    76  	sp := sdktrace.NewSimpleSpanProcessor(exp)
    77  	provider := sdktrace.NewTracerProvider(
    78  		sdktrace.WithSpanProcessor(sp),
    79  		sdktrace.WithResource(otelResource),
    80  	)
    81  	otel.SetTracerProvider(provider)
    82  
    83  	pgtr := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})
    84  	otel.SetTextMapPropagator(pgtr)
    85  
    86  	return nil
    87  }