Telemetry system

This commit is contained in:
2026-06-02 19:27:09 +02:00
parent e9230e6240
commit d73343457d
2 changed files with 113 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
package telemetry
import (
"context"
"errors"
"log/slog"
"strings"
"go.opentelemetry.io/contrib/bridges/otelslog"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/log/global"
sdklog "go.opentelemetry.io/otel/sdk/log"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/sdk/trace"
)
func newResource(serviceName string) *resource.Resource {
return resource.NewWithAttributes(
resource.Default().SchemaURL(),
attribute.String("service.name", serviceName),
)
}
// Init sets up OpenTelemetry tracing, metrics, and logs via OTLP Push.
// It returns a shutdown function that should be deferred in main.
func Init(ctx context.Context, endpoint string, serviceName string) (func(context.Context) error, error) {
res := newResource(serviceName)
var shutdownFuncs []func(context.Context) error
shutdown := func(ctx context.Context) error {
var err error
for _, fn := range shutdownFuncs {
if fnErr := fn(ctx); fnErr != nil {
err = errors.Join(err, fnErr)
}
}
return err
}
var traceOpts []otlptracehttp.Option
var metricOpts []otlpmetrichttp.Option
var logOpts []otlploghttp.Option
if endpoint != "" {
endpoint = strings.TrimSuffix(endpoint, "/")
traceOpts = append(traceOpts, otlptracehttp.WithEndpointURL(endpoint+"/v1/traces"))
metricOpts = append(metricOpts, otlpmetrichttp.WithEndpointURL(endpoint+"/v1/metrics"))
logOpts = append(logOpts, otlploghttp.WithEndpointURL(endpoint+"/v1/logs"))
} else {
// Default to insecure localhost if no endpoint is specified
traceOpts = append(traceOpts, otlptracehttp.WithInsecure())
metricOpts = append(metricOpts, otlpmetrichttp.WithInsecure())
logOpts = append(logOpts, otlploghttp.WithInsecure())
}
// Trace setup
traceExporter, err := otlptracehttp.New(ctx, traceOpts...)
if err != nil {
return shutdown, err
}
tp := trace.NewTracerProvider(
trace.WithBatcher(traceExporter),
trace.WithResource(res),
)
otel.SetTracerProvider(tp)
shutdownFuncs = append(shutdownFuncs, tp.Shutdown)
// Metrics setup
metricExporter, err := otlpmetrichttp.New(ctx, metricOpts...)
if err != nil {
return shutdown, err
}
mp := metric.NewMeterProvider(
metric.WithReader(metric.NewPeriodicReader(metricExporter)),
metric.WithResource(res),
)
otel.SetMeterProvider(mp)
shutdownFuncs = append(shutdownFuncs, mp.Shutdown)
// Logs setup
logExporter, err := otlploghttp.New(ctx, logOpts...)
if err != nil {
return shutdown, err
}
lp := sdklog.NewLoggerProvider(
sdklog.WithProcessor(sdklog.NewBatchProcessor(logExporter)),
sdklog.WithResource(res),
)
global.SetLoggerProvider(lp)
shutdownFuncs = append(shutdownFuncs, lp.Shutdown)
// Route slog to OpenTelemetry
slog.SetDefault(otelslog.NewLogger(serviceName))
return shutdown, nil
}

12
k6.js Normal file
View File

@@ -0,0 +1,12 @@
import http from "k6/http";
import { sleep } from "k6";
export const options = {
iterations: 100,
};
export default function () {
http.get("http://localhost:3001/abcdefghij");
sleep(0.2);
}