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 + /readyz HTTP surface, 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{ ... }, ...) (*sdkmetric.MeterProvider, 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 StartMetricsServer(ctx context.Context, opts MetricsServerOptions)
- func StartReadinessServer(ctx context.Context, addr string, readiness *Readiness)
- type Exporters
- type LoggingOptions
- type MetricsServerOptions
- 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 unless OTEL_METRICS_EXPORTER is "none". 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) (*sdkmetric.MeterProvider, 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 OTEL_METRICS_EXPORTER=none nothing is pushed and the OTel instruments register on reg, so its endpoint serves both.
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 StartMetricsServer ¶
func StartMetricsServer(ctx context.Context, opts MetricsServerOptions)
StartMetricsServer runs an HTTP server exposing /metrics (Prometheus) and optionally /readyz and /healthz. Blocks until http.ListenAndServe returns; designed to be `go`-launched.
func StartReadinessServer ¶
StartReadinessServer runs an HTTP server exposing only /readyz. Blocks until http.ListenAndServe returns; designed to be `go`-launched. A serve failure exits the process: a worker whose readiness endpoint cannot come up never turns Ready and never registers, so dying loudly lets the kubelet restart it instead of leaving a pod that looks alive but can never receive work.
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 MetricsServerOptions ¶
type MetricsServerOptions struct {
// Addr is the TCP listen address (e.g. ":9090").
Addr string
// Readiness, if non-nil, enables a /readyz handler: 200 while
// Ready, 503 after MarkNotReady. A zero-value Readiness never
// flips, giving a static 200 for binaries with no drain sequence.
// Nil serves no /readyz at all.
Readiness *Readiness
// EnableHealthz adds an always-200 /healthz for liveness probes,
// which must keep succeeding while a draining server fails /readyz.
EnableHealthz bool
}
MetricsServerOptions configures StartMetricsServer.
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).
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.