Files
zeekay 57d6230871 feat: ZAP is the only transport — drop OTLP, gRPC and protobuf
The OTLP exporter was already gone from the code: exporter_default.go returns
errLegacyOTLPDisabled and nothing imports an exporter package. go.mod still
required otlptrace, otlptracegrpc, otlptracehttp, proto/otlp, protobuf and grpc,
so every consumer of this module pulled gRPC and protobuf to reach code that
cannot run. That is why 131 modules in the workspace list google.golang.org/grpc
while none of their own source imports it.

Those requires are gone. This module now builds with no OTLP, no protobuf and no
gRPC in its graph at all.

ExporterType follows: Disabled and ZAP, nothing else. Keeping GRPC and HTTP as
values advertised transports that could not be constructed — ExporterTypeFromString
would accept "grpc", and the exporter would then fail at use. It now refuses them
at parse time, which is where a wrong config should be caught, and the tests
assert the rejection rather than the old acceptance.
2026-07-26 18:48:02 -07:00

98 lines
2.6 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package trace
import (
"context"
"io"
"time"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/trace"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)
const (
tracerExportTimeout = 10 * time.Second
// [tracerProviderShutdownTimeout] is longer than [tracerExportTimeout] so
// in-flight exports can finish before the tracer provider shuts down.
tracerProviderShutdownTimeout = 15 * time.Second
)
type Config struct {
ExporterConfig `json:"exporterConfig"`
// The fraction of traces to sample.
// If >= 1 always samples.
// If <= 0 never samples.
TraceSampleRate float64 `json:"traceSampleRate"`
AppName string `json:"appName"`
Version string `json:"version"`
}
type Tracer interface {
trace.Tracer
io.Closer
}
type tracer struct {
trace.Tracer
tp *sdktrace.TracerProvider
}
func (t *tracer) Close() error {
ctx, cancel := context.WithTimeout(context.Background(), tracerProviderShutdownTimeout)
defer cancel()
return t.tp.Shutdown(ctx)
}
// New returns a Tracer configured per config.
//
// ExporterConfig.Type semantics:
// - Disabled → Noop tracer, zero allocations on span ops.
// - ZAP → ZAP-native exporter — the only real export path. Ships
// spans as JSON inside ZAP envelopes to a collector at
// config.Endpoint (default 127.0.0.1:4317). No protobuf,
// no OTLP, no grpc.
// - anything else → removed. Returns an error directing callers to ZAP.
func New(config Config) (Tracer, error) {
if config.ExporterConfig.Type == Disabled {
return Noop, nil
}
var (
exporter sdktrace.SpanExporter
err error
)
switch config.ExporterConfig.Type {
case ZAP:
exporter, err = newZAPNativeExporter(config.ExporterConfig, config.AppName, config.Version)
default:
exporter, err = newExporter(config.ExporterConfig)
}
if err != nil {
return nil, err
}
tracerProviderOpts := []sdktrace.TracerProviderOption{
sdktrace.WithBatcher(exporter, sdktrace.WithExportTimeout(tracerExportTimeout)),
sdktrace.WithResource(resource.NewWithAttributes(semconv.SchemaURL,
attribute.String("version", config.Version),
semconv.ServiceNameKey.String(config.AppName),
)),
sdktrace.WithSampler(sdktrace.TraceIDRatioBased(config.TraceSampleRate)),
}
tracerProvider := sdktrace.NewTracerProvider(tracerProviderOpts...)
return &tracer{
Tracer: tracerProvider.Tracer(config.AppName),
tp: tracerProvider,
}, nil
}