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>:4318ve 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_PROXYiçinde - Örnekleme
parentbased_traceidratio,0.1 - Servisin kaynak kodu ve derlendiği makine
Linux (systemd)
- Servisin
main.godosyasının yanındaotel.godosyasını oluşturun, şunu yapıştırın (paketmaindeğilse ilk satırı değiştirin):
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
}mainiçinde önce bunu çağırın ve HTTP handler'ını (buradamux)otelhttpile sarın; gelentraceparentbaşlıkları böylece Spitfire'ın trace'ini sürdürür:
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.
- Modülün klasöründe (
go.mod'un olduğu yer) modülleri ekleyin ve servisi yeniden derleyin:
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- 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çinsql.Openyerineotelsql.Open:
go get go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@v0.72.0
go get github.com/XSAM/otelsql@v0.44.0- Klasörü, ardından
/etc/spitfire-otel/<service-name>.envdosyasını oluşturun, şunu yapıştırın:
sudo mkdir -p /etc/spitfire-otelIS_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- İzni kısın:
sudo chmod 600 /etc/spitfire-otel/<service-name>.env sudo systemctl edit <unit>açın, şunu yapıştırın:
[Service]
EnvironmentFile=/etc/spitfire-otel/<service-name>.env- Yeni binary'yi yerine koyup yeniden başlatın:
sudo systemctl daemon-reload && sudo systemctl restart <unit> - Başladığını görün:
journalctl -u <unit> -n 50çıktısındasetupOTelhatası olmamalı (servis bu hatayla durur).
Go için otel-run dosyası gerekmez: setupOTel IS_OTEL_ENABLED değerini kendisi okur.
Docker
- 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.modvego.sumönceden olduğu gibi derleme aşamasına kopyalanmalı. - Ortam dosyasını (Linux 5. adım) Docker makinesinde
/etc/spitfire-otel/<service-name>.envolarak kaydedin. - Çalıştırın:
docker run --env-file /etc/spitfire-otel/<service-name>.env …ya da compose'da servisin altınaenv_file: /etc/spitfire-otel/<service-name>.env. - Ortam dosyası değişince konteyneri yeniden oluşturun (
restartyetmez):docker compose up -d --force-recreate <service>
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
- Image'ı Docker bölümündeki gibi hazırlayın.
- Ortam dosyasını (Linux 5. adım)
<service-name>.envolarak kaydedip Secret yapın:
kubectl create secret generic <service-name>-otel --from-env-file=<service-name>.env \
--dry-run=client -o yaml | kubectl apply -f -- Deployment'ta container'ın altına ekleyin:
envFrom:
- secretRef:
name: <service-name>-otel- Yeniden başlatın:
kubectl rollout restart deployment/<deployment>
Windows (servis)
- Kod değişikliklerini yapın (Linux 1–4. adım) ve
.exe'yi yeniden derleyin. - Yönetici PowerShell'de
<windows-service>yerine servisin adını (Get-Servicelistesindeki Name) yazıp çalıştırın:
$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 -ForceKod 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):
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.0Kapatmak için o konteyneri durdurun: docker rm -f <service-name>-obi. Kubernetes'te DaemonSet
olarak çalışır; bkz. OBI belgesi.
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
- Kapatmak: ortam dosyasında (Windows'ta betikte)
IS_OTEL_ENABLED=falseyapı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;setupOTelo zaman bir şey yapmaz. - Kaldırmak:
otel.godosyasını,setupOTelveotelhttpsatırlarını silin,go mod tidyçalıştırıp yeniden derleyin;sudo systemctl revert <unit>vesudo rm -r /etc/spitfire-otel; Windows'ta servisinEnvironmentdeğ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 |