Documentation
¶
Overview ¶
Package viper provides a wrapper around spf13/viper for configuration management with enhanced features including remote configuration support, custom decode hooks, and file watching capabilities.
Overview ¶
This package extends the functionality of github.com/spf13/viper by providing:
- Remote configuration support (ETCD)
- Custom decode hooks for type conversion
- File system watching with reload callbacks
- Configuration key unsetting
- Thread-safe operations
Basic Usage ¶
Create a new Viper instance and load configuration from a file:
import (
"context"
"github.com/nabbar/golib/logger"
"github.com/nabbar/golib/viper"
)
ctx := func() context.Context { return context.Background() }
log := func() logger.Logger { return logger.New(ctx) }
v := viper.New(ctx, log)
v.SetConfigFile("/path/to/config.yaml")
err := v.Config(logger.ErrorLevel, logger.InfoLevel)
if err != nil {
// Handle error
}
// Read values
name := v.GetString("app.name")
port := v.GetInt("app.port")
Configuration Sources ¶
The package supports multiple configuration sources:
1. File-based configuration (JSON, YAML, TOML, etc.) 2. Environment variables with prefix 3. Remote configuration providers (ETCD) 4. Default configuration via io.Reader
Remote Configuration ¶
Configure remote provider for dynamic configuration updates:
v.SetRemoteProvider("etcd")
v.SetRemoteEndpoint("http://localhost:2379")
v.SetRemotePath("/config/myapp")
v.SetRemoteModel(&MyConfig{})
err := v.Config(logger.ErrorLevel, logger.InfoLevel)
// Configuration will be automatically reloaded from remote
Custom Decode Hooks ¶
Register custom decode hooks for type conversion during unmarshalling:
import "github.com/go-viper/mapstructure/v2"
hook := func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
// Custom conversion logic
return data, nil
}
v.HookRegister(hook)
File Watching ¶
Watch for configuration file changes and trigger reload:
v.SetRemoteReloadFunc(func() {
// Reload application configuration
})
v.WatchFS(logger.InfoLevel)
Unmarshalling ¶
Unmarshal configuration into structs:
type AppConfig struct {
Name string
Port int
Debug bool
}
var config AppConfig
err := v.Unmarshal(&config)
// Or unmarshal a specific key
var dbConfig DatabaseConfig
err := v.UnmarshalKey("database", &dbConfig)
Configuration Management ¶
Unset configuration keys dynamically:
// Unset single key
err := v.Unset("app.debug")
// Unset multiple keys
err := v.Unset("app.debug", "app.verbose", "cache.enabled")
// Unset nested keys
err := v.Unset("database.connection.pool")
Error Handling ¶
The package defines specific error codes for different failure scenarios:
- ErrorParamEmpty: Required parameter is empty
- ErrorParamMissing: Required parameter is missing
- ErrorHomePathNotFound: Cannot retrieve user home path
- ErrorBasePathNotFound: Cannot retrieve base config path
- ErrorRemoteProvider: Cannot define remote provider
- ErrorRemoteProviderSecure: Cannot define secure remote provider
- ErrorRemoteProviderRead: Cannot read config from remote provider
- ErrorRemoteProviderMarshall: Cannot marshall config from remote provider
- ErrorConfigRead: Cannot read config from file
- ErrorConfigReadDefault: Cannot read default config
- ErrorConfigIsDefault: Using default config (warning)
Thread Safety ¶
All operations are thread-safe and can be called concurrently from multiple goroutines. The underlying viper instance and custom hooks are properly synchronized.
Dependencies ¶
This package depends on:
- github.com/spf13/viper: Core configuration management
- github.com/go-viper/mapstructure/v2: Struct decoding with hooks
- github.com/nabbar/golib/context: Context management
- github.com/nabbar/golib/logger: Logging functionality
- github.com/nabbar/golib/errors: Error handling
- github.com/fsnotify/fsnotify: File system notifications
See Also ¶
For more information on the underlying viper library: https://github.com/spf13/viper
For mapstructure decode hooks: https://github.com/go-viper/mapstructure
Index ¶
Constants ¶
const ( ErrorParamEmpty liberr.CodeError = iota + liberr.MinPkgViper ErrorParamMissing ErrorHomePathNotFound ErrorBasePathNotFound ErrorRemoteProvider ErrorRemoteProviderSecure ErrorRemoteProviderRead ErrorRemoteProviderMarshall ErrorConfigRead ErrorConfigReadDefault ErrorConfigIsDefault )
const (
// RemoteETCD is the identifier for ETCD remote configuration provider
RemoteETCD = "etcd"
)
Remote provider constants
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type FuncConfigGet ¶ added in v1.10.0
FuncConfigGet is a function type for retrieving configuration values. It takes a key string and a model interface to unmarshal the value into.
type FuncSPFViper ¶ added in v1.10.0
FuncSPFViper is a function type that returns the underlying spf13/viper instance. This allows direct access to the viper library when needed.
type FuncViper ¶ added in v1.10.0
type FuncViper func() Viper
FuncViper is a function type that returns a Viper instance. This is commonly used for dependency injection and lazy initialization.
type Viper ¶
type Viper interface {
// SetRemoteProvider sets the remote configuration provider (e.g., "etcd").
SetRemoteProvider(provider string)
// SetRemoteEndpoint sets the endpoint URL for the remote configuration provider.
SetRemoteEndpoint(endpoint string)
// SetRemotePath sets the path to the configuration in the remote provider.
SetRemotePath(path string)
// SetRemoteSecureKey sets the encryption key for secure remote connections.
SetRemoteSecureKey(key string)
// SetRemoteModel sets the model struct for unmarshalling remote configuration.
SetRemoteModel(model interface{})
// SetRemoteReloadFunc sets a callback function to be called when configuration is reloaded.
SetRemoteReloadFunc(fct func())
// SetHomeBaseName sets the base name for configuration file in home directory.
// The actual file will be named ".<basename>" (e.g., ".myapp").
SetHomeBaseName(base string)
// SetEnvVarsPrefix sets the prefix for environment variables.
// Environment variables will be read as PREFIX_KEY_NAME.
SetEnvVarsPrefix(prefix string)
// SetDefaultConfig sets a function that returns a default configuration reader.
// This is used as fallback when no configuration file is found.
SetDefaultConfig(fct func() io.Reader)
// SetConfigFile sets the path to the configuration file.
// If empty, it will search for config in home directory using SetHomeBaseName.
SetConfigFile(fileConfig string) error
// Config initializes the configuration from file or remote provider.
// logLevelRemoteKO is used for remote errors, logLevelRemoteOK for success messages.
Config(logLevelRemoteKO, logLevelRemoteOK loglvl.Level) error
// Viper returns the underlying spf13/viper instance for advanced operations.
Viper() *spfvpr.Viper
// WatchFS starts watching the configuration file for changes.
// When changes are detected, the reload function set by SetRemoteReloadFunc is called.
WatchFS(logLevelFSInfo loglvl.Level)
// Unset removes one or more configuration keys.
// Supports nested keys using dot notation (e.g., "database.host").
Unset(key ...string) error
// HookRegister registers a custom decode hook for type conversion during unmarshalling.
HookRegister(hook libmap.DecodeHookFunc)
// HookReset removes all registered decode hooks.
HookReset()
// UnmarshalKey unmarshals a specific configuration key into the provided struct.
UnmarshalKey(key string, rawVal interface{}) error
// Unmarshal unmarshals the entire configuration into the provided struct.
Unmarshal(rawVal interface{}) error
// UnmarshalExact is like Unmarshal but returns an error if the config contains
// fields that are not present in the target struct.
UnmarshalExact(rawVal interface{}) error
// GetBool returns the value associated with the key as a boolean.
GetBool(key string) bool
// GetString returns the value associated with the key as a string.
GetString(key string) string
// GetInt returns the value associated with the key as an integer.
GetInt(key string) int
// GetInt32 returns the value associated with the key as an int32.
GetInt32(key string) int32
// GetInt64 returns the value associated with the key as an int64.
GetInt64(key string) int64
// GetUint returns the value associated with the key as an unsigned integer.
GetUint(key string) uint
// GetUint16 returns the value associated with the key as a uint16.
GetUint16(key string) uint16
// GetUint32 returns the value associated with the key as a uint32.
GetUint32(key string) uint32
// GetUint64 returns the value associated with the key as a uint64.
GetUint64(key string) uint64
// GetFloat64 returns the value associated with the key as a float64.
GetFloat64(key string) float64
// GetTime returns the value associated with the key as time.Time.
GetTime(key string) time.Time
// GetDuration returns the value associated with the key as a time.Duration.
GetDuration(key string) time.Duration
// GetIntSlice returns the value associated with the key as a slice of int.
GetIntSlice(key string) []int
// GetStringSlice returns the value associated with the key as a slice of strings.
GetStringSlice(key string) []string
// GetStringMap returns the value associated with the key as a map of interfaces.
GetStringMap(key string) map[string]any
// GetStringMapString returns the value associated with the key as a map of strings.
GetStringMapString(key string) map[string]string
// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
GetStringMapStringSlice(key string) map[string][]string
}
Viper is the main interface for configuration management. It provides methods for setting up configuration sources, reading values, and managing decode hooks for custom type conversions.
All methods are safe for concurrent use.
func New ¶
New creates a new Viper instance with the provided context and logger.
If log is nil, a default logger will be created using the provided context. The returned Viper instance is ready to use and thread-safe.
Example:
ctx := func() context.Context { return context.Background() }
log := func() logger.Logger { return logger.New(ctx) }
v := viper.New(ctx, log)