Documentation
¶
Overview ¶
Package collectors provides standard implementations of the config.Collector interface for loading configuration from various sources.
Collector Types ¶
- Map — reads configuration from an in-memory map[string]any.
- Env — reads configuration from environment variables, with configurable prefix, delimiter, and key transformation.
- Storage — reads multiple configuration documents from a key-value storage (e.g., etcd) under a common prefix, with integrity verification.
- Directory — reads multiple configuration files from a filesystem directory, with optional recursive scanning.
- Source / DataSource — abstraction over a single data stream (file, storage key, etc.) used by the generic collector.
Format and Watching ¶
- Format — interface for parsing raw data (e.g., YAML) into a tree.Node.
- YamlFormat — YAML implementation of Format.
- Watcher — interface for reactive change notifications from storage backends.
Builder Pattern ¶
All collectors use a fluent builder pattern with With* methods for optional configuration (WithName, WithSourceType, WithRevision, WithKeepOrder).
Example ¶
m := collectors.NewMap(map[string]any{
"listen": "127.0.0.1:3301",
"log": map[string]any{"level": "info"},
})
cfg, err := config.NewBuilder().
AddCollector(m.WithName("defaults")).
Build()
if err != nil {
log.Fatal(err)
}
Index ¶
- Variables
- func NewSource(source DataSource, format Format) (config.Collector, error)
- type DataSource
- type Directory
- func (d *Directory) Collectors(_ context.Context) ([]config.Collector, error)
- func (d *Directory) KeepOrder() bool
- func (d *Directory) Name() string
- func (d *Directory) Read(ctx context.Context) <-chan config.Value
- func (d *Directory) Recursive() bool
- func (d *Directory) Revision() config.RevisionType
- func (d *Directory) Source() config.SourceType
- func (d *Directory) WithKeepOrder(keep bool) *Directory
- func (d *Directory) WithName(name string) *Directory
- func (d *Directory) WithRecursive(recursive bool) *Directory
- func (d *Directory) WithRevision(rev config.RevisionType) *Directory
- func (d *Directory) WithSourceType(source config.SourceType) *Directory
- type Env
- func (ec *Env) KeepOrder() bool
- func (ec *Env) Name() string
- func (ec *Env) Read(ctx context.Context) <-chan config.Value
- func (ec *Env) Revision() config.RevisionType
- func (ec *Env) Source() config.SourceType
- func (ec *Env) WithDelimiter(delim string) *Env
- func (ec *Env) WithKeepOrder(keep bool) *Env
- func (ec *Env) WithName(name string) *Env
- func (ec *Env) WithPrefix(prefix string) *Env
- func (ec *Env) WithRevision(rev config.RevisionType) *Env
- func (ec *Env) WithSourceType(source config.SourceType) *Env
- func (ec *Env) WithTransform(fn func(string) config.KeyPath) *Env
- type File
- type Format
- type Map
- func (mc *Map) KeepOrder() bool
- func (mc *Map) Name() string
- func (mc *Map) Read(ctx context.Context) <-chan config.Value
- func (mc *Map) Revision() config.RevisionType
- func (mc *Map) Source() config.SourceType
- func (mc *Map) WithKeepOrder(keep bool) *Map
- func (mc *Map) WithName(name string) *Map
- func (mc *Map) WithRevision(rev config.RevisionType) *Map
- func (mc *Map) WithSourceType(source config.SourceType) *Map
- type Mock
- func (mc *Mock) KeepOrder() bool
- func (mc *Mock) Name() string
- func (mc *Mock) Read(ctx context.Context) <-chan config.Value
- func (mc *Mock) Revision() config.RevisionType
- func (mc *Mock) Source() config.SourceType
- func (mc *Mock) WithEntries(entries map[string]any) *Mock
- func (mc *Mock) WithEntry(keyPath config.KeyPath, value any) *Mock
- func (mc *Mock) WithKeepOrder(keep bool) *Mock
- func (mc *Mock) WithName(name string) *Mock
- func (mc *Mock) WithRevision(rev config.RevisionType) *Mock
- func (mc *Mock) WithSourceType(source config.SourceType) *Mock
- type Source
- type Storage
- func (s *Storage) Collectors(ctx context.Context) ([]config.Collector, error)
- func (s *Storage) KeepOrder() bool
- func (s *Storage) Name() string
- func (s *Storage) Read(ctx context.Context) <-chan config.Value
- func (s *Storage) Revision() config.RevisionType
- func (s *Storage) Source() config.SourceType
- func (s *Storage) Watch(ctx context.Context) (<-chan WatchEvent, error)
- func (s *Storage) WithDelimiter(delim string) *Storage
- func (s *Storage) WithKeepOrder(keep bool) *Storage
- func (s *Storage) WithName(name string) *Storage
- func (s *Storage) WithRevision(rev config.RevisionType) *Storage
- func (s *Storage) WithSourceType(source config.SourceType) *Storage
- type StorageSource
- func (s *StorageSource) FetchStream(ctx context.Context) (io.ReadCloser, error)
- func (s *StorageSource) Name() string
- func (s *StorageSource) Revision() config.RevisionType
- func (s *StorageSource) SourceType() config.SourceType
- func (s *StorageSource) Watch(ctx context.Context) (<-chan WatchEvent, error)
- type WatchEvent
- type Watcher
- type YamlFormat
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNoData indicates that there is no data to process. ErrNoData = errors.New("no data to process") // ErrUnmarshall indicates that unmarshalling failed. ErrUnmarshall = errors.New("failed to unmarshall") // ErrFile indicates a file processing error. ErrFile = errors.New("file processing error") // ErrReader indicates a reader processing error. ErrReader = errors.New("reader processing error") // ErrFetchStream indicates that fetching the stream failed. ErrFetchStream = errors.New("failed to fetch the stream") // ErrFormatParse indicates that parsing data with format failed. ErrFormatParse = errors.New("failed to parse data with format") // ErrStorageFetch indicates that storage fetch failed. ErrStorageFetch = errors.New("storage fetch failed") // ErrStorageKeyNotFound indicates that a storage key was not found. ErrStorageKeyNotFound = errors.New("storage key not found") // ErrStorageRange indicates that a storage range query failed. ErrStorageRange = errors.New("storage range query failed") // ErrStorageValidation indicates that storage integrity validation failed. ErrStorageValidation = errors.New("storage integrity validation failed") // ErrDirectoryRead indicates that reading a directory failed. ErrDirectoryRead = errors.New("directory read failed") )
Functions ¶
Types ¶
type DataSource ¶
type DataSource interface {
Name() string
SourceType() config.SourceType
Revision() config.RevisionType
FetchStream(ctx context.Context) (io.ReadCloser, error)
}
DataSource represent data source.
type Directory ¶
type Directory struct {
// contains filtered or unexported fields
}
Directory implements config.Collector and config.MultiCollector for reading multiple configuration files from a filesystem directory. Each file matching the configured extension is parsed according to the given Format and merged independently as a separate sub-collector. File names (without extension) are used for source identification; the file content determines the tree structure.
When recursive mode is enabled, subdirectories are scanned recursively. Symbolic links to files are followed, but symbolic links to directories are skipped to prevent infinite loops and cyclic traversals.
func NewDirectory ¶
NewDirectory creates a new Directory collector that reads all files with the given extension from the specified directory path. Each file's content is parsed using the provided Format. The extension should include the leading dot (e.g., ".yaml").
func (*Directory) Collectors ¶
Collectors implements config.MultiCollector. It reads the configured directory, filters files by extension, parses each file using the collector's Format, and returns one sub-collector per file. Each sub-collector is merged independently by the Builder with its own MergerContext, source name, and revision. Returns an error if any file cannot be read or parsed. Symbolic links to files are followed, but symbolic links to directories are skipped.
func (*Directory) Read ¶
Read performs a directory scan and emits all values from all files on a single channel. This is a convenience method; the Builder uses Collectors for independent per-file merging.
func (*Directory) Recursive ¶
Recursive returns whether the collector scans subdirectories recursively.
func (*Directory) Revision ¶
func (d *Directory) Revision() config.RevisionType
Revision returns the collector's current revision.
func (*Directory) Source ¶
func (d *Directory) Source() config.SourceType
Source returns the collector's source type.
func (*Directory) WithKeepOrder ¶
WithKeepOrder sets whether the collector should preserve the order of keys as they appear in each file (default false).
func (*Directory) WithName ¶
WithName sets a custom name prefix for the collector (default "directory"). The final SourceInfo.Name for each value will be "<name>:<path>/<filename>", where <filename> is the name of the file from which the value was read. For example, WithName("config") with path "/etc/app" and file "db.yaml" produces SourceInfo.Name "config:/etc/app/db.yaml".
func (*Directory) WithRecursive ¶
WithRecursive sets whether to scan subdirectories recursively (default false).
func (*Directory) WithRevision ¶
func (d *Directory) WithRevision(rev config.RevisionType) *Directory
WithRevision sets the revision for the collector.
func (*Directory) WithSourceType ¶
func (d *Directory) WithSourceType(source config.SourceType) *Directory
WithSourceType sets the source type reported by the collector (default config.FileSource).
type Env ¶
type Env struct {
// contains filtered or unexported fields
}
Env reads configuration data from environment variables.
func NewEnv ¶
func NewEnv() *Env
NewEnv creates an Env with default settings. By default, it uses underscore ('_') as delimiter, no prefix, and converts keys to lowercase, replacing underscores with slashes to form a hierarchical key path.
func (*Env) Revision ¶
func (ec *Env) Revision() config.RevisionType
Revision implements the Collector interface.
func (*Env) Source ¶
func (ec *Env) Source() config.SourceType
Source implements the Collector interface.
func (*Env) WithDelimiter ¶
WithDelimiter sets the delimiter used by the default transformation to split environment variable names. The default is underscore ('_').
func (*Env) WithKeepOrder ¶
WithKeepOrder sets whether the collector preserves key order.
func (*Env) WithPrefix ¶
WithPrefix sets a prefix to strip from environment variable names. If set, only variables starting with this prefix are processed, and the prefix is removed.
func (*Env) WithRevision ¶
func (ec *Env) WithRevision(rev config.RevisionType) *Env
WithRevision sets the revision for the collector.
func (*Env) WithSourceType ¶
func (ec *Env) WithSourceType(source config.SourceType) *Env
WithSourceType sets the source type for the collector.
type File ¶
type File struct {
// contains filtered or unexported fields
}
File implements DataSource with data from file.
func (File) FetchStream ¶
FetchStream returns reader.
func (File) SourceType ¶
func (f File) SourceType() config.SourceType
SourceType returns source type.
type Format ¶
type Format interface {
Name() string
KeepOrder() bool
From(r io.Reader) Format
Parse() (*tree.Node, error)
}
Format represents way to convert some data into the tree.Node.
type Map ¶
type Map struct {
// contains filtered or unexported fields
}
Map reads configuration data from a map.
func NewMap ¶
NewMap creates a Map with the given data. The source type defaults to config.UnknownSource.
func (*Map) Revision ¶
func (mc *Map) Revision() config.RevisionType
Revision implements the Collector interface.
func (*Map) Source ¶
func (mc *Map) Source() config.SourceType
Source implements the Collector interface.
func (*Map) WithKeepOrder ¶
WithKeepOrder sets whether the collector preserves key order.
func (*Map) WithRevision ¶
func (mc *Map) WithRevision(rev config.RevisionType) *Map
WithRevision sets the revision for the collector.
func (*Map) WithSourceType ¶
func (mc *Map) WithSourceType(source config.SourceType) *Map
WithSourceType sets the source type for the collector.
type Mock ¶
type Mock struct {
// contains filtered or unexported fields
}
Mock is a testing collector that returns a predefined set of values.
func (*Mock) Revision ¶
func (mc *Mock) Revision() config.RevisionType
Revision implements the Collector interface.
func (*Mock) Source ¶
func (mc *Mock) Source() config.SourceType
Source implements the Collector interface.
func (*Mock) WithEntries ¶
WithEntries adds multiple key-value pairs to the collector.
func (*Mock) WithKeepOrder ¶
WithKeepOrder sets whether the collector preserves key order.
func (*Mock) WithRevision ¶
func (mc *Mock) WithRevision(rev config.RevisionType) *Mock
WithRevision sets the revision for the collector.
func (*Mock) WithSourceType ¶
func (mc *Mock) WithSourceType(source config.SourceType) *Mock
WithSourceType sets the source type for the collector.
type Source ¶
type Source struct {
// contains filtered or unexported fields
}
Source represent data source with format.
func (*Source) Revision ¶
func (s *Source) Revision() config.RevisionType
Revision implements Collector interface.
func (*Source) Source ¶
func (s *Source) Source() config.SourceType
Source implements Collector interface.
type Storage ¶
type Storage struct {
// contains filtered or unexported fields
}
Storage implements config.Collector for reading multiple configuration documents from a key-value storage under a common prefix with integrity verification. Each key's value is parsed according to the given Format and merged into a single config tree. Key names are used only for distinguishing documents; the YAML content determines the tree structure.
func NewStorage ¶
NewStorage creates a new Storage collector that reads all keys under the prefix managed by the given integrity.Typed storage. Each key's value is parsed using the provided Format.
func (*Storage) Collectors ¶
Collectors implements config.MultiCollector. It performs a range query with the configured prefix, validates integrity, parses each key's value using the collector's Format, and returns one sub-collector per storage key. Each sub-collector is merged independently by the Builder with its own MergerContext, source name, and revision. The parent Storage's revision is updated to the maximum ModRevision among the fetched keys. Keys with empty values or parsing errors are skipped.
func (*Storage) Read ¶
Read performs a range query with the configured prefix and emits all values from all documents on a single channel. This is a convenience method; the Builder uses Collectors for independent per-document merging.
func (*Storage) Revision ¶
func (s *Storage) Revision() config.RevisionType
Revision returns the collector's current revision.
func (*Storage) Source ¶
func (s *Storage) Source() config.SourceType
Source returns the collector's source type.
func (*Storage) Watch ¶
func (s *Storage) Watch(ctx context.Context) (<-chan WatchEvent, error)
Watch implements the Watcher interface. It returns a channel that streams change events for the configured prefix in storage.
func (*Storage) WithDelimiter ¶
WithDelimiter sets the delimiter used to split storage keys into config path segments. The default is "/". If the delimiter differs from "/", it is replaced internally with "/" before constructing the KeyPath.
func (*Storage) WithKeepOrder ¶
WithKeepOrder sets whether the collector should preserve the order of keys as they appear in the storage range (default false).
func (*Storage) WithName ¶
WithName sets a custom name prefix for the collector (default "storage"). The final SourceInfo.Name for each value will be "<name>:<prefix><key>", where <key> is the storage key from which the value was read. For example, WithName("etcd") with prefix "/config/" and key "app" produces SourceInfo.Name "etcd:/config/app".
func (*Storage) WithRevision ¶
func (s *Storage) WithRevision(rev config.RevisionType) *Storage
WithRevision sets an initial revision for the collector. If not set, the revision will be derived from the highest ModRevision among the fetched keys after a successful Read.
func (*Storage) WithSourceType ¶
func (s *Storage) WithSourceType(source config.SourceType) *Storage
WithSourceType sets the source type reported by the collector (default config.StorageSource).
type StorageSource ¶
type StorageSource struct {
// contains filtered or unexported fields
}
StorageSource implements DataSource for reading a single configuration document from a key-value storage with integrity verification. It uses the integrity layer's namer and validator to generate properly structured keys and verify hashes/signatures on the fetched value.
func NewStorageSource ¶
func NewStorageSource( strg storage.Storage, prefix string, name string, hashers []hasher.Hasher, verifiers []crypto.Verifier, ) *StorageSource
NewStorageSource creates a new StorageSource that will read from the given storage the value identified by the logical name. The prefix determines the key namespace in the storage backend (e.g., "/config/").
func (*StorageSource) FetchStream ¶
func (s *StorageSource) FetchStream(ctx context.Context) (io.ReadCloser, error)
FetchStream performs a transactional Get for the configured name with integrity verification and returns an io.ReadCloser over the raw value bytes. If the key is not found, ErrStorageKeyNotFound is returned. Storage errors are wrapped with ErrStorageFetch. Integrity verification errors are wrapped with ErrStorageValidation. The revision is updated on success.
func (*StorageSource) Name ¶
func (s *StorageSource) Name() string
Name returns the fixed label "storage".
func (*StorageSource) Revision ¶
func (s *StorageSource) Revision() config.RevisionType
Revision returns the modification revision of the last successfully fetched value. The revision is a string representation of the storage's ModRevision.
func (*StorageSource) SourceType ¶
func (s *StorageSource) SourceType() config.SourceType
SourceType returns config.StorageSource.
func (*StorageSource) Watch ¶
func (s *StorageSource) Watch(ctx context.Context) (<-chan WatchEvent, error)
Watch implements the Watcher interface. It returns a channel that streams change events for the configured name in storage.
type WatchEvent ¶
type WatchEvent struct {
// Prefix indicates the key or prefix that was changed.
Prefix string
}
WatchEvent represents a change notification from storage.
type Watcher ¶
type Watcher interface {
// Watch returns a channel that streams change events for the collector's
// key or prefix. The channel is closed when the context is cancelled.
Watch(ctx context.Context) (<-chan WatchEvent, error)
}
Watcher provides reactive change notifications from a storage backend. Collectors that support watching for changes implement this interface in addition to the standard Collector interface.
type YamlFormat ¶
type YamlFormat struct {
// contains filtered or unexported fields
}
YamlFormat implements Format interface.
func (YamlFormat) From ¶
func (y YamlFormat) From(reader io.Reader) Format
From implements the Format interface.
func (YamlFormat) KeepOrder ¶
func (y YamlFormat) KeepOrder() bool
KeepOrder implements the Format interface.