Getting Started | OpenTelemetry net/httpサーバのサンプル https://github.com/open-telemetry/opentelemetry-go-contrib/blob/2dc32c101833e4d556ceb2ea1ece3712dce7a728/instrumentation/net/http/otelhttp/example/server/server.go 公式のotel-collector初期化サンプル https://github.com/open-telemetry/opentelemetry-go/blob/499785e13488854518260065716ec1094bf69f12/example/otel-collector/main.go package main import ( "context" "fmt" "log" "os" "os/signal" "time" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/propagation" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.26.0" "go.opentelemetry.io/otel/trace" ) var serviceName = semconv.ServiceNameKey.String("test-service") // Initialize a gRPC connection to be used by both the tracer and meter // providers. func initConn() (*grpc.ClientConn, error) { // It connects the OpenTelemetry Collector through local gRPC connection. // You may replace `localhost:4317` with your endpoint. conn, err := grpc.NewClient("localhost:4317", // Note the use of insecure transport here. TLS is recommended in production. grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { return nil, fmt.Errorf("failed to create gRPC connection to collector: %w", err) } return conn, err } // Initializes an OTLP exporter, and configures the corresponding trace provider. func initTracerProvider(ctx context.Context, res *resource.Resource, conn *grpc.ClientConn) (func(context.Context) error, error) { // Set up a trace exporter traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithGRPCConn(conn)) if err != nil { return nil, fmt.Errorf("failed to create trace exporter: %w", err) } // Register the trace exporter with a TracerProvider, using a batch // span processor to aggregate spans before export. bsp := sdktrace.NewBatchSpanProcessor(traceExporter) tracerProvider := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithResource(res), sdktrace.WithSpanProcessor(bsp), ) otel.SetTracerProvider(tracerProvider) // Set global propagator to tracecontext (the default is no-op). otel.SetTextMapPropagator(propagation.TraceContext{}) // Shutdown will flush any remaining spans and shut down the exporter. return tracerProvider.Shutdown, nil } // Initializes an OTLP exporter, and configures the corresponding meter provider. func initMeterProvider(ctx context.Context, res *resource.Resource, conn *grpc.ClientConn) (func(context.Context) error, error) { metricExporter, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithGRPCConn(conn)) if err != nil { return nil, fmt.Errorf("failed to create metrics exporter: %w", err) } meterProvider := sdkmetric.NewMeterProvider( sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExporter)), sdkmetric.WithResource(res), ) otel.SetMeterProvider(meterProvider) return meterProvider.Shutdown, nil } func main() { log.Printf("Waiting for connection...") ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() conn, err := initConn() if err != nil { log.Fatal(err) } res, err := resource.New(ctx, resource.WithAttributes( // The service name used to display traces in backends serviceName, ), ) if err != nil { log.Fatal(err) } shutdownTracerProvider, err := initTracerProvider(ctx, res, conn) if err != nil { log.Fatal(err) } defer func() { if err := shutdownTracerProvider(ctx); err != nil { log.Fatalf("failed to shutdown TracerProvider: %s", err) } }() shutdownMeterProvider, err := initMeterProvider(ctx, res, conn) if err != nil { log.Fatal(err) } defer func() { if err := shutdownMeterProvider(ctx); err != nil { log.Fatalf("failed to shutdown MeterProvider: %s", err) } }() tracer := otel.Tracer("test-tracer") meter := otel.Meter("test-meter") // Attributes represent additional key-value descriptors that can be bound // to a metric observer or recorder. commonAttrs := []attribute.KeyValue{ attribute.String("attrA", "chocolate"), attribute.String("attrB", "raspberry"), attribute.String("attrC", "vanilla"), } runCount, err := meter.Int64Counter("run", metric.WithDescription("The number of times the iteration ran")) if err != nil { log.Fatal(err) } // Work begins ctx, span := tracer.Start( ctx, "CollectorExporter-Example", trace.WithAttributes(commonAttrs...)) defer span.End() for i := 0; i < 10; i++ { _, iSpan := tracer.Start(ctx, fmt.Sprintf("Sample-%d", i)) runCount.Add(ctx, 1, metric.WithAttributes(commonAttrs...)) log.Printf("Doing really hard work (%d / 10)\n", i+1) <-time.After(time.Second) iSpan.End() } log.Printf("Done!") }