Documentation
¶
Overview ¶
Package serverboot collects the startup boilerplate shared by the long-running substrate server binaries (ateapi, atelet, ateom-gvisor, ateom-microvm): slog wiring, OTel tracer + meter providers, a Prometheus /metrics server, a /readyz and /healthz server for the kubelet probes, and a couple of small helpers for startup fail-fast.
Index ¶
- Constants
- func Fatal(ctx context.Context, msg string, err error, additionalArgs ...any)
- func InitLogger()
- func InitLoggerWithWriter(w io.Writer)
- func InitLogging(ctx context.Context, opts LoggingOptions) (*sdklog.LoggerProvider, error)
- func InitMetrics(ctx context.Context, serviceName string) (*sdkmetric.MeterProvider, error)
- func InitMetricsBridged(ctx context.Context, serviceName string, reg interface{ ... }, ...) (mp *sdkmetric.MeterProvider, servePull bool, err error)
- func InitMetricsPushOnlyVia(ctx context.Context, serviceName string, conn *grpc.ClientConn) (*sdkmetric.MeterProvider, error)
- func InitTracing(ctx context.Context, opts TracingOptions) (*sdktrace.TracerProvider, error)
- func SetLogLevel(level string) error
- func ShutdownProvider(name string, shutdown func(context.Context) error)
- func StartHealthServer(ctx context.Context, addr string, readiness *Readiness)
- func StartMetricsServer(ctx context.Context, addr string)
- type Exporters
- type LoggingOptions
- type Readiness
- type TraceSampling
- type TracingOptions
Constants ¶
const ( ExporterOTLP = "otlp" ExporterConsole = "console" )
The exporter names the OTEL_*_EXPORTER variables use, for checking a resolved set with Has.
const ControlPlaneTraceRatio = 0.1
ControlPlaneTraceRatio is the default root sampling ratio for the control plane binaries: low volume, and their traces are what lifecycle debugging needs, so the default leans generous.
Variables ¶
This section is empty.
Functions ¶
func Fatal ¶
Fatal logs msg + err and exits with status 1. For startup-time fail-fast where there's no recovery path.
func InitLogger ¶
func InitLogger()
InitLogger sets the global slog logger to a JSON handler wrapped in contextlogging.NewHandler, writing to os.Stdout. Call once at process start.
func InitLoggerWithWriter ¶
InitLoggerWithWriter is InitLogger with an explicit destination. Use it to share one synchronized writer between the runtime logger and a separate writer (e.g. ateom's actor-log forwarder) so their lines don't interleave.
func InitLogging ¶ added in v0.2.0
func InitLogging(ctx context.Context, opts LoggingOptions) (*sdklog.LoggerProvider, error)
InitLogging registers a global LoggerProvider for the records components emit through internal/actorevent, and sets whether those records also go to stdout (console).
It returns (nil, nil) when the exporter does not include otlp, and leaves the OTel global alone: emitting then costs one Enabled check. Guard the shutdown on a nil provider, unlike InitTracing which always returns one.
The processor batches. These records sit on the actor resume and suspend path, and exporting inside the emit call would put a blocking gRPC round trip there, serialized across every emitting goroutine, so an unreachable collector would surface as control-plane latency. The cost is that an ungraceful exit loses the records still queued, unless console also wrote them to stdout.
func InitMetrics ¶
InitMetrics registers a global MeterProvider with both a Prometheus reader (exposed via StartMetricsServer's /metrics handler) and an OTLP periodic reader, the latter while OTEL_METRICS_EXPORTER selects otlp. The Prometheus reader registers on the default registry.
func InitMetricsBridged ¶ added in v0.4.0
func InitMetricsBridged(ctx context.Context, serviceName string, reg interface { promclient.Registerer promclient.Gatherer }, wrapProducer func(sdkmetric.Producer) sdkmetric.Producer) (mp *sdkmetric.MeterProvider, servePull bool, err error)
InitMetricsBridged is for a binary whose scraped endpoint serves a registry it does not own (atecontroller: controller-runtime's), so every metric reaches the backend exactly once on whichever path is active. With the OTLP export, reg is bridged onto the push and the OTel instruments stay off it, since the bridge would otherwise push them a second time. With prometheus alone, nothing is pushed and the OTel instruments register on reg, so its endpoint serves both.
servePull reports whether OTEL_METRICS_EXPORTER leaves the scraped endpoint on, which the caller must then serve from reg: unset, prometheus, or a list with it. otlp and none turn it off, and with none no reader is installed.
wrapProducer, when non-nil, wraps the bridge producer on the OTLP path, for a rewrite the push backend needs but the scraped endpoint does not.
func InitMetricsPushOnlyVia ¶
func InitMetricsPushOnlyVia(ctx context.Context, serviceName string, conn *grpc.ClientConn) (*sdkmetric.MeterProvider, error)
InitMetricsPushOnlyVia is InitMetrics without the Prometheus reader, for a binary that runs no metrics HTTP server of its own (ateom): a pull reader would collect into a registry nothing serves. conn is the metrics counterpart of TracingOptions.ExporterConn: ateom passes atelet's relay socket (internal/otlprelay) so the worker pod needs no network path of its own; a nil conn keeps the direct dial to OTEL_EXPORTER_OTLP_ENDPOINT.
The caller owns the connection: the meter provider's Shutdown does not close a connection it did not create.
Calling this at all marks the component relay-capable, so its metrics carry the relay attribute (see relayAttrs) either way — "relay" with a conn, "direct" without one. It is the metrics counterpart of TracingOptions.RelayCapable, implied rather than a parameter because only a caller that has a relay to pass reaches for this function in the first place.
func InitTracing ¶
func InitTracing(ctx context.Context, opts TracingOptions) (*sdktrace.TracerProvider, error)
InitTracing registers a global TracerProvider with the given options and the TraceContext text-map propagator.
func SetLogLevel ¶
SetLogLevel sets the minimum level of the serverboot loggers from a flag value: "debug", "info", "warn", or "error" (case-insensitive). Empty means unset and leaves the current level unchanged, so configs that never populate the field keep the default.
func ShutdownProvider ¶
ShutdownProvider invokes the OTel provider's Shutdown and logs any error. Designed to be deferred from main():
defer serverboot.ShutdownProvider("TracerProvider", tp.Shutdown)
func StartHealthServer ¶ added in v0.5.0
StartHealthServer runs an HTTP server exposing /readyz and /healthz for the kubelet probes. /readyz returns 200 while readiness is Ready and every check passes, and 503 after MarkNotReady or while a check fails. /healthz always returns 200, so liveness keeps succeeding while a draining server fails readiness. Blocks until the server stops; designed to be `go`-launched. A serve failure exits the process: a pod whose probes can never succeed never turns Ready, so dying loudly lets the kubelet restart it instead of leaving a pod that looks alive but never gets work.
func StartMetricsServer ¶
StartMetricsServer runs an HTTP server exposing only /metrics (Prometheus). Blocks until the server stops; designed to be `go`-launched. The kubelet probes use StartHealthServer, so a change to the metrics endpoint does not change the health checks. A serve failure exits the process: the probes no longer report a metrics server that cannot bind, so without the exit the only sign of the failure is one log line.
Types ¶
type Exporters ¶ added in v0.4.0
Exporters is the set of exporters an OTEL_*_EXPORTER variable selects. The empty set is none; nil means not chosen.
func ResolveLogsExporter ¶ added in v0.2.0
ResolveLogsExporter reads OTEL_LOGS_EXPORTER with the shared exporter rules. The default is none rather than the spec's otlp, so turning it on is one ConfigMap key per environment.
type LoggingOptions ¶ added in v0.2.0
type LoggingOptions struct {
// ServiceName is required; populates resource.semconv ServiceName.
ServiceName string
// Exporter is required; the empty set is none. Build it with
// ResolveLogsExporter.
Exporter Exporters
// ExporterConn and RelayCapable are the logs counterpart of the same fields
// on TracingOptions: ateom passes its relay connection and marks itself
// relay-capable so the resource carries ate.otlp.relay.
ExporterConn *grpc.ClientConn
RelayCapable bool
}
LoggingOptions configures InitLogging.
type Readiness ¶
type Readiness struct {
// contains filtered or unexported fields
}
Readiness is a predicate for process readiness. The zero value reports ready. Calling MarkNotReady flips it permanently to not ready, which causes /readyz to start returning "Service Unavailable" (503). Checks added with AddCheck make /readyz return 503 only while they fail.
func (*Readiness) AddCheck ¶ added in v0.5.0
AddCheck registers a dependency check that /readyz runs on every request. While it returns an error, or does not return within checkTimeout, /readyz returns 503, and it returns 200 again once the check passes. Liveness is unaffected. Check errors are logged when a check starts and stops failing, and never sent to the client.
func (*Readiness) MarkNotReady ¶
func (r *Readiness) MarkNotReady()
MarkNotReady makes /readyz return 503 from now on.
type TraceSampling ¶
type TraceSampling struct {
// contains filtered or unexported fields
}
TraceSampling is a resolved sampling policy. The root fraction is kept alongside the sampler because the atenet router must mirror it into Envoy's RandomSampling percent, which roots the data plane traces.
func ParentNeverSampling ¶
func ParentNeverSampling() TraceSampling
ParentNeverSampling is ParentBased(NeverSample()).
func ParentRatioSampling ¶
func ParentRatioSampling(ratio float64) TraceSampling
ParentRatioSampling is ParentBased(TraceIDRatioBased(ratio)), clamped to [0, 1].
func ResolveTraceSampling ¶
func ResolveTraceSampling(ctx context.Context, def TraceSampling) TraceSampling
ResolveTraceSampling applies OTEL_TRACES_SAMPLER / OTEL_TRACES_SAMPLER_ARG on top of the component default. serverboot resolves the env itself because an explicit WithSampler silences the SDK's env handling, and the SDK falls open to 100% sampling on invalid values where this keeps the default and logs. That includes a ratio sampler without an arg, which the spec reads as 1.0.
func (TraceSampling) RootSamplingPercent ¶
func (s TraceSampling) RootSamplingPercent() float64
RootSamplingPercent is the percentage (0 to 100) of parentless requests sampled at the root.
func (TraceSampling) Sampler ¶
func (s TraceSampling) Sampler() sdktrace.Sampler
type TracingOptions ¶
type TracingOptions struct {
// ServiceName is required; populates resource.semconv ServiceName.
ServiceName string
// Sampling is required. Build it with ResolveTraceSampling so
// OTEL_TRACES_SAMPLER / OTEL_TRACES_SAMPLER_ARG override the component
// default.
Sampling TraceSampling
// ExporterConn, when non-nil, is the connection the OTLP exporter sends
// over, instead of dialing OTEL_EXPORTER_OTLP_ENDPOINT itself. ateom passes
// the unix socket to atelet's relay (internal/otlprelay) so a worker pod
// exports without a network path of its own; nil keeps the direct dial.
//
// The caller owns the connection: the exporter's Shutdown does not close a
// connection it did not create.
ExporterConn *grpc.ClientConn
// RelayCapable marks a component that is meant to export through the relay,
// whether or not it managed to (see relayAttrs). Only the ateoms set it. It
// is separate from ExporterConn because a nil conn on its own cannot tell
// "the ateom tried and fell back" from "this component never had a relay".
RelayCapable bool
}
TracingOptions configures InitTracing.