Spitfirev1.0.0 · Yenilikler

Sürüm: 1.0.0Bu dokümantasyon Spitfire 1.0.0 içindir.

Go servisini OTel ile bağlamak

Go derlenen bir dil, yüklenecek bir ajan yok: servise bir dosya ve iki satır ekleyip yeniden derlersiniz. Bundan sonra servis trace, metrik ve log'larını gönderir; adresler ve token'lar diğer rehberlerdeki gibi ortamdan gelir. Değerler ve genel kurallar: Servisleri OTel ile bağlamak: genel. Koda dokunamıyorsanız: Kod değiştirmeden: OTel eBPF.

Sürüm tablosu

Go go.opentelemetry.io/otel (sdk, sdk/metric) otel/log, otel/sdk/log contrib (autoexport, otelhttp, runtime) otelslog
1.26 ve sonrası v1.47.0 v1.47.0 v0.72.0 v0.21.0
1.25 v1.46.0 v0.22.0 v0.71.0 v0.20.1
1.24 v1.41.0 v0.17.0 v0.66.0 v0.16.0
1.23 ve öncesi desteklenmiyor – – –

Sürümünüzü bulun: servisin go.mod dosyasındaki go satırı (ya da derleme makinesinde go version).

Aşağıdaki komutlarda 1.26 satırı yazılıdır; 1.25 ya da 1.24'te o satırın sürümlerini yazın. Bir satırdaki modüller birlikte yayımlanır: satırları karıştırmayın.

Doğrulandı: 2026-11-03. Kaynak: desteklenen Go sürümleri, Go başlangıç belgesi, autoexport (ortam değişkenleri), her modülün go satırı.

Gerekenler

  • Spitfire adresi https://<spitfire> ve OTLP alıcısı anahtarı sfotlp_…
  • Tower adresi http://<tower>:4318 ve Collector token'ı sfcol_…
  • Protokol http/protobuf
  • Servis adı <service-name>, sürümü <service-version>, ortamı <environment>
  • Özel CA varsa CA dosyası /etc/spitfire-otel/ca.pem
  • Proxy varsa Tower ve Spitfire NO_PROXY içinde
  • Örnekleme parentbased_traceidratio, 0.1
  • Servisin kaynak kodu ve derlendiği makine

Linux (systemd)

  1. Servisin main.go dosyasının yanında otel.go dosyasını oluşturun, şunu yapıştırın (paket main değilse ilk satırı değiştirin):
go
package main

import (
	"context"
	"errors"
	"log/slog"
	"os"

	"go.opentelemetry.io/contrib/bridges/otelslog"
	"go.opentelemetry.io/contrib/exporters/autoexport"
	"go.opentelemetry.io/contrib/instrumentation/runtime"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/log/global"
	"go.opentelemetry.io/otel/propagation"
	sdklog "go.opentelemetry.io/otel/sdk/log"
	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

// setupOTel: IS_OTEL_ENABLED=true turns OTel on; any other value leaves it
// off. Addresses, tokens, sampling and the service name come from the
// OTEL_* environment values. Call the returned function on shutdown.
func setupOTel(ctx context.Context) (func(context.Context) error, error) {
	if os.Getenv("IS_OTEL_ENABLED") != "true" {
		return func(context.Context) error { return nil }, nil
	}
	spans, err := autoexport.NewSpanExporter(ctx)
	if err != nil {
		return nil, err
	}
	tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(spans))
	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))

	reader, err := autoexport.NewMetricReader(ctx)
	if err != nil {
		return nil, err
	}
	mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader))
	otel.SetMeterProvider(mp)
	if err := runtime.Start(); err != nil { // Go runtime metrics (memory, GC, goroutines)
		return nil, err
	}

	logs, err := autoexport.NewLogExporter(ctx)
	if err != nil {
		return nil, err
	}
	lp := sdklog.NewLoggerProvider(sdklog.WithProcessor(sdklog.NewBatchProcessor(logs)))
	global.SetLoggerProvider(lp)
	// slog records go to Spitfire (with the trace ID) instead of stdout;
	// delete this line to keep them on stdout.
	slog.SetDefault(otelslog.NewLogger(os.Getenv("OTEL_SERVICE_NAME")))

	return func(ctx context.Context) error {
		return errors.Join(tp.Shutdown(ctx), mp.Shutdown(ctx), lp.Shutdown(ctx))
	}, nil
}
  1. main içinde önce bunu çağırın ve HTTP handler'ını (burada mux) otelhttp ile sarın; gelen traceparent başlıkları böylece Spitfire'ın trace'ini sürdürür:
go
shutdown, err := setupOTel(ctx)
if err != nil {
	log.Fatal(err)
}
defer shutdown(context.Background())

handler := otelhttp.NewHandler(mux, "http.server",
	otelhttp.WithSpanNameFormatter(func(_ string, r *http.Request) string { return r.Method + " " + r.URL.Path }))
// http.ListenAndServe(":8080", handler)

Import go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp. Servisin başka servislere yaptığı çağrılarda trace'in sürmesi için &http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)} kullanın.

  1. Modülün klasöründe (go.mod'un olduğu yer) modülleri ekleyin ve servisi yeniden derleyin:
bash
go get go.opentelemetry.io/otel@v1.47.0 \
  go.opentelemetry.io/otel/sdk@v1.47.0 \
  go.opentelemetry.io/otel/sdk/metric@v1.47.0 \
  go.opentelemetry.io/otel/sdk/log@v1.47.0 \
  go.opentelemetry.io/otel/log@v1.47.0 \
  go.opentelemetry.io/contrib/exporters/autoexport@v0.72.0 \
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.72.0 \
  go.opentelemetry.io/contrib/instrumentation/runtime@v0.72.0 \
  go.opentelemetry.io/contrib/bridges/otelslog@v0.21.0
go mod tidy
  1. Diğer kütüphaneler (isteğe bağlı): gRPC sunucu ve istemcileri için otelgrpc.NewServerHandler() / otelgrpc.NewClientHandler() (grpc.StatsHandler(…)), veritabanı çağrıları için sql.Open yerine otelsql.Open:
bash
go get go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@v0.72.0
go get github.com/XSAM/otelsql@v0.44.0
  1. Klasörü, ardından /etc/spitfire-otel/<service-name>.env dosyasını oluşturun, şunu yapıştırın:
bash
sudo mkdir -p /etc/spitfire-otel
bash
IS_OTEL_ENABLED=true
OTEL_SERVICE_NAME=<service-name>
OTEL_RESOURCE_ATTRIBUTES=service.version=<service-version>,deployment.environment=<environment>
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://<spitfire>/otlp/v1/traces
OTEL_EXPORTER_OTLP_TRACES_HEADERS=authorization=sfotlp_…
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://<spitfire>/otlp/v1/logs
OTEL_EXPORTER_OTLP_LOGS_HEADERS=authorization=sfotlp_…
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://<tower>:4318/v1/metrics
OTEL_EXPORTER_OTLP_METRICS_HEADERS=authorization=sfcol_…
OTEL_TRACES_EXPORTER=otlp
OTEL_METRICS_EXPORTER=otlp
OTEL_LOGS_EXPORTER=otlp
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1
NO_PROXY=<tower>,<spitfire>
#OTEL_EXPORTER_OTLP_CERTIFICATE=/etc/spitfire-otel/ca.pem
  1. İzni kısın: sudo chmod 600 /etc/spitfire-otel/<service-name>.env
  2. sudo systemctl edit <unit> açın, şunu yapıştırın:
ini
[Service]
EnvironmentFile=/etc/spitfire-otel/<service-name>.env
  1. Yeni binary'yi yerine koyup yeniden başlatın: sudo systemctl daemon-reload && sudo systemctl restart <unit>
  2. Başladığını görün: journalctl -u <unit> -n 50 çıktısında setupOTel hatası olmamalı (servis bu hatayla durur).
Not

Go için otel-run dosyası gerekmez: setupOTel IS_OTEL_ENABLED değerini kendisi okur.

Docker

  1. Kod değişikliklerini yapın (Linux 1–4. adım); Dockerfile'a yeni satır gerekmez, modüller binary'nin içine derlenir. go.mod ve go.sum önceden olduğu gibi derleme aşamasına kopyalanmalı.
  2. Ortam dosyasını (Linux 5. adım) Docker makinesinde /etc/spitfire-otel/<service-name>.env olarak kaydedin.
  3. Çalıştırın: docker run --env-file /etc/spitfire-otel/<service-name>.env … ya da compose'da servisin altına env_file: /etc/spitfire-otel/<service-name>.env.
  4. Ortam dosyası değişince konteyneri yeniden oluşturun (restart yetmez): docker compose up -d --force-recreate <service>
Not

scratch image'ında CA sertifikaları yoktur: https://<spitfire> ile gönderim başarısız olur. gcr.io/distroless/static-debian12 kullanın ya da derleme aşamasından /etc/ssl/certs/ca-certificates.crt dosyasını kopyalayın.

Kubernetes

  1. Image'ı Docker bölümündeki gibi hazırlayın.
  2. Ortam dosyasını (Linux 5. adım) <service-name>.env olarak kaydedip Secret yapın:
bash
kubectl create secret generic <service-name>-otel --from-env-file=<service-name>.env \
  --dry-run=client -o yaml | kubectl apply -f -
  1. Deployment'ta container'ın altına ekleyin:
yaml
envFrom:
  - secretRef:
      name: <service-name>-otel
  1. Yeniden başlatın: kubectl rollout restart deployment/<deployment>

Windows (servis)

  1. Kod değişikliklerini yapın (Linux 1–4. adım) ve .exe'yi yeniden derleyin.
  2. Yönetici PowerShell'de <windows-service> yerine servisin adını (Get-Service listesindeki Name) yazıp çalıştırın:
powershell
$Service = "<windows-service>"
$IS_OTEL_ENABLED = "true"
$Otel = @(
  "IS_OTEL_ENABLED=$IS_OTEL_ENABLED",
  "OTEL_SERVICE_NAME=<service-name>",
  "OTEL_RESOURCE_ATTRIBUTES=service.version=<service-version>,deployment.environment=<environment>",
  "OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf",
  "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://<spitfire>/otlp/v1/traces",
  "OTEL_EXPORTER_OTLP_TRACES_HEADERS=authorization=sfotlp_…",
  "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://<spitfire>/otlp/v1/logs",
  "OTEL_EXPORTER_OTLP_LOGS_HEADERS=authorization=sfotlp_…",
  "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://<tower>:4318/v1/metrics",
  "OTEL_EXPORTER_OTLP_METRICS_HEADERS=authorization=sfcol_…",
  "OTEL_TRACES_EXPORTER=otlp",
  "OTEL_METRICS_EXPORTER=otlp",
  "OTEL_LOGS_EXPORTER=otlp",
  "OTEL_TRACES_SAMPLER=parentbased_traceidratio",
  "OTEL_TRACES_SAMPLER_ARG=0.1",
  "NO_PROXY=<tower>,<spitfire>"
)
# Private CA: $Otel += "OTEL_EXPORTER_OTLP_CERTIFICATE=C:\spitfire-otel\ca.pem"
$Key = "HKLM:\SYSTEM\CurrentControlSet\Services\$Service"
$Keep = @((Get-ItemProperty $Key).Environment | Where-Object { $_ -and $_ -notmatch '^(IS_OTEL_ENABLED|OTEL_|NO_PROXY)=' })
Set-ItemProperty $Key -Name Environment -Type MultiString -Value ($Keep + $Otel)
Restart-Service -Name $Service -Force

Kod değiştirmeden: OTel eBPF

Kod değiştirilemiyorsa OpenTelemetry eBPF Instrumentation (OBI) süreci dışarıdan izler ve HTTP ile gRPC sunucu/istemci span'leri ve metrikleri üretir. SDK'dan azını görür: servisin içindeki span'ler, log'lar ve özel metrikler yoktur. Yalnız Linux.

Konu Gereksinim
Sürüm otel/ebpf-instrument:v1.0.0
Çekirdek BTF'li Linux 5.8 ve sonrası (/sys/kernel/btf/vmlinux var); backport'lu RHEL 8 4.18 çekirdekleri de çalışır
Mimari amd64, arm64
Yetki root (--privileged) ve servisin süreç alanı (--pid=host ya da --pid=container:<service>)

Servisin yanında çalıştırın (Docker; 8080: servisin dinlediği port):

bash
docker run -d --name <service-name>-obi --privileged --pid=container:<service> \
  -e OTEL_EBPF_OPEN_PORT=8080 \
  -e OTEL_SERVICE_NAME=<service-name> \
  -e OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
  -e OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://<spitfire>/otlp/v1/traces \
  -e OTEL_EXPORTER_OTLP_TRACES_HEADERS=authorization=sfotlp_… \
  -e OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://<tower>:4318/v1/metrics \
  -e OTEL_EXPORTER_OTLP_METRICS_HEADERS=authorization=sfcol_… \
  otel/ebpf-instrument:v1.0.0

Kapatmak için o konteyneri durdurun: docker rm -f <service-name>-obi. Kubernetes'te DaemonSet olarak çalışır; bkz. OBI belgesi.

Not

OBI Spitfire'ın kendi testlerinde yoktur (Linux çekirdeğinde yetkili konteyner ister); yukarıdaki SDK adımları vardır. Kaynak: OBI gereksinimleri, doğrulandı 2026-11-03.

Kapatma ve kaldırma

  1. Kapatmak: ortam dosyasında (Windows'ta betikte) IS_OTEL_ENABLED=false yapın ve servisi yeniden başlatın (Linux 8. adım, Docker 4. adım, Kubernetes 4. adım ya da Windows betiğini yeniden çalıştırın). Kod kalır; setupOTel o zaman bir şey yapmaz.
  2. Kaldırmak: otel.go dosyasını, setupOTel ve otelhttp satırlarını silin, go mod tidy çalıştırıp yeniden derleyin; sudo systemctl revert <unit> ve sudo rm -r /etc/spitfire-otel; Windows'ta servisin Environment değerinden OTel satırlarını silin.

Sık karşılaşılan sorunlar

Belirti Neden Çözüm
go: go.opentelemetry.io/otel@v1.47.0 requires go >= 1.26.0 (ya da go daha yeni bir toolchain indiriyor) Sürümler daha yeni bir Go için Sürüm tablosundan kendi satırınızın sürümlerini yazın
otel/log kaynaklı ambiguous import ya da undefined İki satırın sürümleri karışmış Bütün modülleri aynı satırdan yazıp go mod tidy çalıştırın
Span'ler geliyor ama her istek ayrı bir trace Handler sarılmamış ya da traceparent'ı bir proxy siliyor En dıştaki handler'ı otelhttp.NewHandler ile sarın (Linux 2. adım)
x509: certificate signed by unknown authority Özel CA ya da image'da CA sertifikası yok OTEL_EXPORTER_OTLP_CERTIFICATE satırını açın; scratch'te Docker notuna bakın
Trace ya da metrik gelmiyor Adres, token ya da ağ Doğrulama adımlarını uygulayın

İlgili sayfalar