Documentation
¶
Overview ¶
Package otlprelay carries ateom's OTLP telemetry to the collector over a unix socket served by atelet, so a worker pod needs no network path of its own to export spans and metrics.
Motivation. ateom runs inside the worker pod that hosts the actor, and until now exported OTLP straight to the collector over the pod's network (the endpoint is injected by atecontroller, see workerpool_apply.go). That has four costs the relay removes:
- Blast radius. The pod runs untrusted agent code. Exporting over the pod network means the pod must be allowed egress to the collector, which is reachable to anything that escapes the sandbox. A unix socket cannot leave the node, so the pod can be denied network egress entirely.
- Connection count. Worker pods are heavily oversubscribed, so a node runs many ateoms, each holding its own gRPC connection to the collector. They collapse into atelet's single per-node connection.
- Interference. ateom installs a transparent redirect of actor egress to its own atunnel listener; its own outbound traffic has to stay clear of the rules it installs. A unix socket is not IP traffic and cannot be caught.
- Shutdown loss. Teardown frees the actor's network and then the pod goes away, which is exactly when the spans describing teardown are still queued in the batch processor. atelet outlives the worker pod.
The relay forwards the OTLP request message verbatim rather than decoding it into SDK records and re-exporting. Verbatim pass-through keeps each ateom's own resource (service.name, service.instance.id, pod attributes) intact, so its spans stay attributed to ateom instead of being absorbed into atelet's. Restricting this pass-through to verified ateom sources ensures that future actor telemetry requiring identity rewrites (#761) will be added as an explicit rewriting path alongside this forwarder; see ateomServices.
Verbatim applies to the payload, not to the call around it. The request's metadata is dropped and replaced with the headers atelet resolves from its own OTEL_EXPORTER_OTLP_HEADERS, since the upstream leg is atelet's connection and authenticating it is atelet's business; see upstreamContext.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Dial ¶
Dial opens the ateom half of the relay: a gRPC connection over atelet's unix socket, to be handed to the OTLP exporters via serverboot's ExporterConn.
It returns (nil, nil) when sockPath is empty or absent, which the caller reads as "export directly instead". The existence check is what makes the fallback deterministic at startup: grpc.NewClient is lazy, so a connection to a missing socket would be created happily and only fail later, per export, with the telemetry already lost. Losing spans is not worth failing ateom over either, hence a fallback rather than an error.
The connection is plaintext by design. A unix socket cannot leave the node, so there is no transport to protect; access is controlled by the socket's file permissions instead (see socketMode).
Types ¶
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the atelet half of the relay: an OTLP receiver on a unix socket that forwards to the real collector over the node's network.
func NewServer ¶
NewServer builds a relay that forwards to the collector named by the standard OTLP endpoint environment variables. It returns (nil, nil) when sockPath is empty (the relay is switched off) or when no endpoint is configured: a relay with nowhere to forward to would accept an ateom's spans and drop them, which is worse than ateom finding no socket and falling back to a direct export.