options

package
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2026 License: MIT Imports: 42 Imported by: 0

Documentation

Overview

Package options defines the configuration option structs for onexmesh, following the onex IOptions convention: each option implements Validate and AddFlags (with a full prefix), and is combined into a ServerOptions root.

Index

Constants

View Source
const MetadataKeyEnv = "env"

MetadataKeyEnv is the instance metadata key carrying MeshOptions.Env. It is exported so a discovery client can filter on it without repeating the literal.

Variables

This section is empty.

Functions

func ProtocolUsesGRPC

func ProtocolUsesGRPC(protocol string) bool

ProtocolUsesGRPC reports whether the protocol includes gRPC.

func ProtocolUsesHTTP

func ProtocolUsesHTTP(protocol string) bool

ProtocolUsesHTTP reports whether the protocol includes HTTP.

Types

type ConfigOptions

type ConfigOptions struct {
	Type      string   `mapstructure:"type"` // none, file, polaris
	FilePaths []string `mapstructure:"file-paths"`

	// Polaris config center.
	PolarisAddresses []string `mapstructure:"polaris-addresses"`
	PolarisNamespace string   `mapstructure:"polaris-namespace"`
	PolarisFileGroup string   `mapstructure:"polaris-file-group"`
	PolarisFileName  string   `mapstructure:"polaris-file-name"`
}

ConfigOptions selects and configures the configuration center backend.

func NewConfigOptions

func NewConfigOptions() *ConfigOptions

NewConfigOptions returns default config options.

func (*ConfigOptions) AddFlags

func (o *ConfigOptions) AddFlags(fs *pflag.FlagSet, prefix string)

func (*ConfigOptions) Validate

func (o *ConfigOptions) Validate() []error

type IOptions

type IOptions interface {
	// Validate validates all required options, returning all errors.
	Validate() []error
	// AddFlags registers flags with the given full prefix.
	AddFlags(fs *pflag.FlagSet, fullPrefix string)
}

IOptions is implemented by every option struct. AddFlags receives a full prefix (e.g. "mesh", "otel") and appends its own field names to build flags like --otel.endpoint.

type MeshOptions

type MeshOptions struct {
	ServiceName string `mapstructure:"service-name"`
	Protocol    string `mapstructure:"protocol"` // "grpc", "http", or "both"
	GRPCAddr    string `mapstructure:"grpc-addr"`
	HTTPAddr    string `mapstructure:"http-addr"`
	// Host is the address peers reach this instance on, used for registration
	// only; it has nothing to do with what the listener binds. Empty means
	// "work it out" — see AdvertiseHost.
	Host string `mapstructure:"host"`
	// Port overrides the registered port. Zero — the default — registers the
	// port actually listened on, which is almost always what is wanted.
	Port int `mapstructure:"port"`
	// Env names the deployment environment (dev/test/stg/prod). It is published
	// as the "env" instance metadata so one registry namespace can hold several
	// environments without a caller mistaking a developer's laptop for a
	// production replica.
	Env string `mapstructure:"env"`
	// Version is the service version, published so a caller can pin or canary.
	Version string `mapstructure:"version"`
	// Metadata is arbitrary extra instance metadata.
	Metadata map[string]string `mapstructure:"metadata"`
	// MiddlewareRoutes are optional route-level middleware bindings, each of
	// the form "selector=mw1,mw2" (e.g. "/svc.v1.Admin/*=ratelimit").
	MiddlewareRoutes []string `mapstructure:"middleware-route"`
}

MeshOptions holds the core service identity and listen addresses.

func NewMeshOptions

func NewMeshOptions() *MeshOptions

NewMeshOptions returns default mesh options.

Port defaults to 0 rather than to a listening port: the registered port must be the one the process actually binds, and a default here would be a second source of truth that silently disagrees with GRPCAddr/HTTPAddr.

func (*MeshOptions) AddFlags

func (o *MeshOptions) AddFlags(fs *pflag.FlagSet, prefix string)

func (*MeshOptions) AdvertiseAddr added in v0.0.3

func (o *MeshOptions) AdvertiseAddr(listenAddr string) (string, int, error)

AdvertiseAddr splits a listen address and returns the host and port this instance should be registered under.

It is the one place that decides what a peer is told, so the registrar and the instance description cannot disagree — and so a backend that carries the endpoint in the instance (etcd, kubernetes) is fixed by the same change as one that carries it in Options (polaris, consul).

The port comes from the listen address unless Port overrides it: the port actually bound is the one a peer can reach, and a second default here would be a second source of truth for the same number.

func (*MeshOptions) AdvertiseHost added in v0.0.3

func (o *MeshOptions) AdvertiseHost() (string, error)

AdvertiseHost returns the address this instance is registered under.

A listen address is not a registration address. A service listening on 0.0.0.0:8180 accepts on every interface, but a peer dialing 0.0.0.0 in a registry entry reaches itself — so passing the listen address straight through, which is what this used to do, publishes an instance nobody can call. The two addresses agree on a developer's machine and diverge everywhere else, which is exactly why the mistake survives local testing.

The order is: an explicit host, then POD_IP, then the interface the kernel would use to reach the network. POD_IP is deliberately ahead of probing: a container often holds more than one interface, and reading the address the kubelet already wrote down beats guessing.

func (*MeshOptions) Validate

func (o *MeshOptions) Validate() []error

type OTelOptions

type OTelOptions struct {
	// Connection settings.
	Endpoint string `mapstructure:"endpoint"`
	Insecure bool   `mapstructure:"insecure"`

	// Service identification.
	ServiceName       string `mapstructure:"service-name"`
	ServiceVersion    string `mapstructure:"service-version"`
	ServiceInstanceID string `mapstructure:"service-instance-id"`
	Environment       string `mapstructure:"environment"`

	// Behavior settings.
	SamplingRatio float64 `mapstructure:"sampling-ratio"`
	WithResource  bool    `mapstructure:"with-resource"`

	// DisableDefaultGoCollector removes client_golang's process-wide Go collector
	// from the default Prometheus registry, so that the OTel runtime
	// instrumentation is the only source of go.* metrics this process exposes.
	// It only has an effect in the modes that install the Prometheus exporter.
	//
	// Off by default, because turning it on changes what an application's
	// /metrics already contained: the Go runtime's own metric names disappear and
	// the semantic conventions' take their place. See unregisterDefaultGoCollector
	// for what is and is not given up.
	DisableDefaultGoCollector bool `mapstructure:"disable-default-go-collector"`

	// Output configuration.
	OutputMode OutputMode `mapstructure:"output-mode"`
	OutputDir  string     `mapstructure:"output-dir"`

	// Logging configuration for the OTel log bridge (non-classic modes). Plain
	// slog configuration lives on ServerOptions.Slog and is applied separately.
	Level     string `mapstructure:"level"`
	AddSource bool   `mapstructure:"add-source"`
	// contains filtered or unexported fields
}

OTelOptions configures OpenTelemetry trace, metric and log.

func NewOTelOptions

func NewOTelOptions() *OTelOptions

NewOTelOptions creates a new OTelOptions with sensible defaults.

func (*OTelOptions) AddFlags

func (o *OTelOptions) AddFlags(fs *pflag.FlagSet, fullPrefix string)

AddFlags adds command line flags.

func (*OTelOptions) Apply

func (o *OTelOptions) Apply() error

Apply applies the configuration by initializing all three signals. If a later signal fails, any earlier-initialized providers and files are rolled back so a partial initialization does not leak resources.

func (*OTelOptions) GetLoggerProvider

func (o *OTelOptions) GetLoggerProvider() *otellog.LoggerProvider

GetLoggerProvider returns the logger provider.

func (*OTelOptions) GetMeterProvider

func (o *OTelOptions) GetMeterProvider() *metric.MeterProvider

GetMeterProvider returns the meter provider.

func (*OTelOptions) GetResource

func (o *OTelOptions) GetResource() *resource.Resource

GetResource creates or returns the cached resource configuration for this options instance. The cache is per-instance (not package-level) so multiple OTelOptions with different service identities do not cross-contaminate.

func (*OTelOptions) GetTracerProvider

func (o *OTelOptions) GetTracerProvider() *trace.TracerProvider

GetTracerProvider returns the tracer provider.

func (*OTelOptions) Shutdown

func (o *OTelOptions) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down all providers and closes files.

func (*OTelOptions) Validate

func (o *OTelOptions) Validate() []error

Validate validates the configuration.

type OTelProviders

type OTelProviders struct {
	// contains filtered or unexported fields
}

OTelProviders holds all OpenTelemetry providers.

type OutputMode

type OutputMode string

OutputMode represents the output mode for OpenTelemetry data.

const (
	// OutputModeOTLP sends all three signals to an OTel collector over OTLP.
	OutputModeOTLP OutputMode = "otel"
	// OutputModeFile writes all three signals to local files.
	OutputModeFile OutputMode = "file"
	// OutputModeConsole writes all three signals to standard output.
	OutputModeConsole OutputMode = "console"
	// OutputModeClassic uses traditional logging/metrics only (no OTel trace).
	OutputModeClassic OutputMode = "classic"
	// OutputModeHybrid routes each signal independently:
	// log->stdout, metric->prometheus, trace->otel.
	OutputModeHybrid OutputMode = "hybrid"
)

func (OutputMode) IsValid

func (o OutputMode) IsValid() bool

IsValid reports whether the output mode is a known value.

func (OutputMode) String

func (o OutputMode) String() string

String implements the Stringer interface.

type Provider

type Provider interface {
	Shutdown(context.Context) error
}

Provider wraps OpenTelemetry providers with shutdown capability.

type RegistryOptions

type RegistryOptions struct {
	// Type is the registry backend name: none, polaris, etcd, kubernetes,
	// consul, nacos or eureka.
	Type string `mapstructure:"type"`

	// Options collects the per-backend settings that have no field of their
	// own, keyed by backend name. It is ",remain", so a config file addresses a
	// backend under exactly its flag name — registry.polaris.addr sets the same
	// setting as --registry.polaris.addr, with no second spelling to remember:
	//
	//	registry:
	//	  type: polaris
	//	  polaris:
	//	    addr: polaris.infra-devops.svc.cluster.local:80
	//	    namespace: edu-onex
	//
	// The values reach the backend's typed Options in Complete.
	Options map[string]any `mapstructure:",remain"`
	// contains filtered or unexported fields
}

RegistryOptions selects the registry backend and delegates backend-specific configuration to the self-describing backends registered via registry.RegisterBackend. This keeps the options layer open to new backends without a per-backend field list or switch: adding a backend is one new package plus a blank import in pkg/registry/all.

func NewRegistryOptions

func NewRegistryOptions() *RegistryOptions

NewRegistryOptions returns default registry options.

func (*RegistryOptions) AddFlags

func (o *RegistryOptions) AddFlags(fs *pflag.FlagSet, prefix string)

AddFlags registers the shared registry type flag, then lets every registered backend contribute its own flags under a nested prefix (--registry.<name>.*). All backends are registered up front so the flag set does not depend on which type is selected.

func (*RegistryOptions) Complete added in v0.0.3

func (o *RegistryOptions) Complete() error

Complete overlays the configuration file's per-backend settings onto the backends' typed Options.

It exists because AddFlags alone leaves a backend configurable only from the command line: what a file carries under registry.<name>.* has nowhere to go, since a backend's typed Options is by design not a field of this struct. Before this, a polaris address written into a config file was silently ignored — the file parsed, the service started, and the setting had no effect.

func (*RegistryOptions) NewDiscovery

func (o *RegistryOptions) NewDiscovery() (registry.Discovery, error)

NewDiscovery creates the client-side discovery for this configuration. It returns (nil, nil) when the registry type is "none".

func (*RegistryOptions) NewRegistrar

func (o *RegistryOptions) NewRegistrar(host string, port int, protocol string) (registry.Registrar, error)

NewRegistrar creates the server-side registrar for this configuration. It returns (nil, nil) when the registry type is "none".

func (*RegistryOptions) Validate

func (o *RegistryOptions) Validate() []error

type ResilienceOptions

type ResilienceOptions struct {
	MaxAttempts          int           `mapstructure:"max-attempts"`
	BaseBackoff          time.Duration `mapstructure:"base-backoff"`
	MaxBackoff           time.Duration `mapstructure:"max-backoff"`
	BreakerWindow        time.Duration `mapstructure:"breaker-window"`
	BreakerProbeInterval time.Duration `mapstructure:"breaker-probe-interval"`
	Timeout              time.Duration `mapstructure:"timeout"`
	// Bulkhead bounds the number of concurrent in-flight requests to a single
	// downstream service. 0 disables the bulkhead.
	Bulkhead int `mapstructure:"bulkhead"`
	// PolicyPath enables declarative resilience: one or more resiliency YAML
	// files whose named policies (timeout/retry/breaker) are bound to endpoints.
	// When set, declarative policies take precedence over the imperative fields.
	PolicyPath []string `mapstructure:"policy-path"`
}

ResilienceOptions configures client-side resilience.

func NewResilienceOptions

func NewResilienceOptions() *ResilienceOptions

NewResilienceOptions returns default resilience options.

func (*ResilienceOptions) AddFlags

func (o *ResilienceOptions) AddFlags(fs *pflag.FlagSet, prefix string)

func (*ResilienceOptions) DialOptions

func (o *ResilienceOptions) DialOptions() []client.DialOption

DialOptions converts the resilience settings into client DialOptions.

func (*ResilienceOptions) Validate

func (o *ResilienceOptions) Validate() []error

type SelectorOptions

type SelectorOptions struct {
	Strategy string `mapstructure:"strategy"` // round_robin, random, weighted, p2c
	// DiscoveryCacheTTL enables the read-through discovery cache when > 0.
	DiscoveryCacheTTL time.Duration `mapstructure:"discovery-cache-ttl"`
}

SelectorOptions selects the load-balancing strategy and client-side discovery caching.

func NewSelectorOptions

func NewSelectorOptions() *SelectorOptions

NewSelectorOptions returns default selector options.

func (*SelectorOptions) AddFlags

func (o *SelectorOptions) AddFlags(fs *pflag.FlagSet, prefix string)

func (*SelectorOptions) DialOption

func (o *SelectorOptions) DialOption() client.DialOption

DialOption converts the strategy selection into a client DialOption.

func (*SelectorOptions) Validate

func (o *SelectorOptions) Validate() []error

type ServerOptions

type ServerOptions struct {
	Mesh       *MeshOptions       `mapstructure:"mesh"`
	Slog       *SlogOptions       `mapstructure:"log"`
	OTel       *OTelOptions       `mapstructure:"otel"`
	Registry   *RegistryOptions   `mapstructure:"registry"`
	Config     *ConfigOptions     `mapstructure:"-"`
	Selector   *SelectorOptions   `mapstructure:"selector"`
	Resilience *ResilienceOptions `mapstructure:"resilience"`
}

ServerOptions is the root options struct combining all leaf options. It satisfies the app.FlagSetOptions contract (AddFlags without prefix and Validate returning a single error) so it can be passed directly to app.

func NewServerOptions

func NewServerOptions() *ServerOptions

NewServerOptions returns a ServerOptions with all leaf defaults.

func (*ServerOptions) AddFlags

func (o *ServerOptions) AddFlags(fs *pflag.FlagSet)

AddFlags registers all leaf flags under their section prefixes.

func (*ServerOptions) Apply

func (o *ServerOptions) Apply() error

Apply initializes the runtime capabilities (plain slog, then OTel trace/metric/ log) so logging, metrics and tracing all take effect. It is the single entry point the composition root calls after options are validated. Plain slog is applied first; for non-classic OTel modes initLogs then bridges slog into OTel.

func (*ServerOptions) BuildClientDialOptions

func (o *ServerOptions) BuildClientDialOptions() ([]client.DialOption, error)

BuildClientDialOptions assembles the client DialOptions from the selector, resilience and registry settings. It returns an error when the registry type is "none", since service discovery requires a backend.

func (*ServerOptions) BuildMatcher

func (o *ServerOptions) BuildMatcher() (*matcher.Matcher, error)

BuildMatcher returns a route-aware matcher when route-level middleware bindings are configured, or (nil, nil) otherwise. The global chain from BuildMiddleware is registered via Use, and each "selector=mw1,mw2" binding is resolved through the middleware registry and registered via Add.

func (*ServerOptions) BuildMiddleware

func (o *ServerOptions) BuildMiddleware() []middleware.Middleware

BuildMiddleware assembles the server middleware chain, outermost first. The resulting order is recovery -> tracing -> logging -> metrics -> timeout -> reqval.

reqval is appended last, and only when the binary has registered it, because it is owned by the application rather than the framework: the framework cannot import the package that knows a request's default values and rules without depending on every service's IDL. A binary that does not register it — the demos, the tests — gets the chain it had before.

It goes last so that a rejection is recorded: the observability middleware above it has already opened its span and started its timer, and a request refused for a malformed page size is one an operator should be able to see.

func (*ServerOptions) Complete added in v0.0.3

func (o *ServerOptions) Complete() error

Complete applies the post-unmarshal fixups shared by the whole option tree. It runs after flags are bound and the config file is unmarshaled, and before Validate — so a setting that will be rejected is first put in its final form.

The registry layer needs it because a backend's typed Options is not a field of these options: the values a file carries under registry.<name>.* are collected into RegistryOptions.Options and have to be handed to the backend that understands them. See RegistryOptions.Complete.

func (*ServerOptions) ServiceInstance

func (o *ServerOptions) ServiceInstance() (*registry.ServiceInstance, error)

ServiceInstance builds the registry.ServiceInstance describing this service across every protocol it serves.

Endpoints are the advertised addresses, not the listen addresses: see MeshOptions.AdvertiseHost for why the two are not the same and why passing the listen address through publishes an instance nobody can call.

func (*ServerOptions) ServiceInstanceFor

func (o *ServerOptions) ServiceInstanceFor(protocol string) (*registry.ServiceInstance, error)

ServiceInstanceFor builds a single-protocol registry.ServiceInstance for the given protocol, so the gRPC and HTTP servers each register their own endpoint (rather than both advertising the gRPC endpoint). It returns (nil, nil) when the configured protocol does not include the requested one.

func (*ServerOptions) Shutdown

func (o *ServerOptions) Shutdown(ctx context.Context) error

Shutdown releases the OTel providers and any open output files (both OTel and plain slog).

func (*ServerOptions) Validate

func (o *ServerOptions) Validate() error

Validate aggregates all leaf validation errors into a single error.

type SlogOptions

type SlogOptions struct {
	Level      string `mapstructure:"level"`
	AddSource  bool   `mapstructure:"add-source"`
	Format     string `mapstructure:"format"`
	TimeFormat string `mapstructure:"time-format"`
	Output     string `mapstructure:"output"`
	// contains filtered or unexported fields
}

SlogOptions configures the slog logger.

func NewSlogOptions

func NewSlogOptions() *SlogOptions

NewSlogOptions returns default slog options.

func (*SlogOptions) AddFlags

func (o *SlogOptions) AddFlags(fs *pflag.FlagSet, prefix string)

func (*SlogOptions) Apply

func (o *SlogOptions) Apply() error

Apply sets the global default slog logger.

func (*SlogOptions) BuildHandler

func (o *SlogOptions) BuildHandler() (slog.Handler, error)

BuildHandler builds a slog.Handler from the options.

func (*SlogOptions) BuildLogger

func (o *SlogOptions) BuildLogger() (*slog.Logger, error)

BuildLogger builds a slog.Logger without touching the global logger.

func (*SlogOptions) Shutdown

func (o *SlogOptions) Shutdown() error

Shutdown closes any output file opened by the writer. It is idempotent.

func (*SlogOptions) ToSlogLevel

func (o *SlogOptions) ToSlogLevel() slog.Level

ToSlogLevel converts the level string to slog.Level.

func (*SlogOptions) Validate

func (o *SlogOptions) Validate() []error

type TraceIDHandler

type TraceIDHandler struct {
	slog.Handler
}

TraceIDHandler decorates a slog.Handler, attaching the current trace/span ids from the request context to every record.

func (*TraceIDHandler) Handle

func (h *TraceIDHandler) Handle(ctx context.Context, r slog.Record) error

func (*TraceIDHandler) WithAttrs

func (h *TraceIDHandler) WithAttrs(attrs []slog.Attr) slog.Handler

func (*TraceIDHandler) WithGroup

func (h *TraceIDHandler) WithGroup(name string) slog.Handler

Jump to

Keyboard shortcuts

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