serverboot

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 37 Imported by: 0

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

View Source
const (
	ExporterOTLP    = "otlp"
	ExporterConsole = "console"
)

The exporter names the OTEL_*_EXPORTER variables use, for checking a resolved set with Has.

View Source
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

func Fatal(ctx context.Context, msg string, err error, additionalArgs ...any)

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

func InitLoggerWithWriter(w io.Writer)

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

func InitMetrics(ctx context.Context, serviceName string) (*sdkmetric.MeterProvider, error)

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

func SetLogLevel(level string) error

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

func ShutdownProvider(name string, shutdown func(context.Context) error)

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

func StartHealthServer(ctx context.Context, addr string, readiness *Readiness)

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

func StartMetricsServer(ctx context.Context, addr string)

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

type Exporters map[string]bool

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

func ResolveLogsExporter(ctx context.Context) Exporters

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.

func (Exporters) Has added in v0.4.0

func (e Exporters) Has(name string) bool

Has reports whether name is selected.

func (Exporters) String added in v0.4.0

func (e Exporters) String() string

String lists the names in order, or none.

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

func (r *Readiness) AddCheck(name string, check func(context.Context) error)

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.

func (*Readiness) Ready

func (r *Readiness) Ready() bool

Ready reports whether MarkNotReady has not been called. It does not run the checks added with AddCheck.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL