CPU replicas start on half the machine's CPUs, not all of them: two busy llama.cpp servers each spinning on all 8 vCPUs fell to 0.8 tok/s apiece, where at 4 threads they keep 5.5. llamacpp.threads sets it per node. Inference requests can be traced over OTLP/HTTP (tracing.endpoint), with admission, schedule and upstream spans and traceparent sent to the engine. Security: onboarding no longer puts the cluster root in the system trust store and removes it where it was; the mirror's mutual-TLS API can be limited to named certificates (--api-client); init.log no longer keeps the administrator's password; a warning when auth is off on a public listen; the recorded actor is sanitised and sudo-aware; Ray's dashboard is off, and the remaining engine gaps are documented. reconciler.go and agent.go are split by topic, the status mapping of each failure is tested, and the plan's checklist is brought up to date. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
73 lines
2.3 KiB
Go
73 lines
2.3 KiB
Go
package obs
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
"os"
|
|
"time"
|
|
|
|
"go.opentelemetry.io/otel"
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
|
"go.opentelemetry.io/otel/propagation"
|
|
"go.opentelemetry.io/otel/sdk/resource"
|
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
|
)
|
|
|
|
// TracingOptions says where traces go.
|
|
type TracingOptions struct {
|
|
Endpoint string // http(s)://host:4318; empty reads OTEL_EXPORTER_OTLP_ENDPOINT
|
|
SampleRatio float64 // of traces the caller did not already decide; zero takes 1
|
|
Service string
|
|
Version string
|
|
}
|
|
|
|
// SetupTracing installs the global tracer provider and the W3C propagator,
|
|
// and returns what flushes it on the way out. With no endpoint it installs
|
|
// nothing, and every span is the no-op one: tracing that is off costs a
|
|
// function call per span.
|
|
func SetupTracing(ctx context.Context, o TracingOptions) (func(context.Context) error, error) {
|
|
noop := func(context.Context) error { return nil }
|
|
endpoint := o.Endpoint
|
|
if endpoint == "" {
|
|
endpoint = os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT")
|
|
}
|
|
if endpoint == "" {
|
|
return noop, nil
|
|
}
|
|
u, err := url.Parse(endpoint)
|
|
if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" {
|
|
return noop, fmt.Errorf("tracing endpoint %q is not an http(s) address", endpoint)
|
|
}
|
|
opts := []otlptracehttp.Option{otlptracehttp.WithEndpoint(u.Host)}
|
|
if u.Scheme == "http" {
|
|
opts = append(opts, otlptracehttp.WithInsecure())
|
|
}
|
|
if u.Path != "" && u.Path != "/" {
|
|
opts = append(opts, otlptracehttp.WithURLPath(u.Path))
|
|
}
|
|
exp, err := otlptracehttp.New(ctx, opts...)
|
|
if err != nil {
|
|
return noop, err
|
|
}
|
|
ratio := o.SampleRatio
|
|
if ratio <= 0 || ratio > 1 {
|
|
ratio = 1
|
|
}
|
|
res := resource.NewSchemaless(
|
|
attribute.String("service.name", o.Service),
|
|
attribute.String("service.version", o.Version),
|
|
)
|
|
tp := sdktrace.NewTracerProvider(
|
|
sdktrace.WithBatcher(exp, sdktrace.WithBatchTimeout(5*time.Second)),
|
|
sdktrace.WithResource(res),
|
|
// A caller that sent a sampled traceparent has already decided; the
|
|
// ratio is for requests that arrive without one.
|
|
sdktrace.WithSampler(sdktrace.ParentBased(sdktrace.TraceIDRatioBased(ratio))),
|
|
)
|
|
otel.SetTracerProvider(tp)
|
|
otel.SetTextMapPropagator(propagation.TraceContext{})
|
|
return tp.Shutdown, nil
|
|
}
|