Documentation
¶
Overview ¶
Package argus provides a comprehensive dynamic configuration management framework for Go applications, combining ultra-fast file monitoring, universal format parsing, and zero-reflection configuration binding in a single, cohesive system.
Philosophy: Dynamic Configuration for the Modern Era ¶
Argus is built on the principle that configuration should be dynamic, type-safe, and ultra-performant. It transforms static configuration files into reactive, real-time configuration sources that adapt to changes without application restarts.
Architecture Overview ¶
Argus consists of six integrated subsystems:
- **BoreasLite Ring Buffer**: Ultra-fast MPSC event processing (1.6M+ ops/sec)
- **Universal Format Parsers**: Support for JSON, YAML, TOML, HCL, INI, Properties
- **Zero-Reflection Config Binding**: Type-safe binding with unsafe.Pointer optimization
- **Comprehensive Audit System**: Security and compliance logging with SQLite backend
- **Security Hardening Layer**: Multi-layer protection against path traversal and DoS attacks
- **Remote Configuration**: Distributed config management with graceful failover
Universal Configuration Watching ¶
Argus automatically detects and parses any configuration format, making it truly universal for modern applications that use diverse configuration sources.
Quick start with automatic format detection:
watcher, err := argus.UniversalConfigWatcher("config.yml", func(config map[string]interface{}) {
if level, ok := config["log_level"].(string); ok {
logger.SetLevel(level)
}
if port, ok := config["server"].(map[string]interface{})["port"].(int); ok {
server.UpdatePort(port)
}
})
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
Supported formats with zero configuration:
- JSON (.json) - Native high-performance parsing
- YAML (.yml, .yaml) - Built-in parser + plugin support
- TOML (.toml) - Built-in parser + plugin support
- HCL (.hcl, .tf) - HashiCorp configuration language
- INI (.ini, .conf, .cfg) - Traditional configuration files
- Properties (.properties) - Java-style key=value format
Ultra-Fast Configuration Binding ¶
The zero-reflection binding system provides type-safe configuration access with unprecedented performance through unsafe.Pointer optimizations.
High-performance typed configuration binding:
var dbHost string var dbPort int var enableSSL bool var timeout time.Duration err := argus.BindFromConfig(configMap). BindString(&dbHost, "database.host", "localhost"). BindInt(&dbPort, "database.port", 5432). BindBool(&enableSSL, "database.ssl", true). BindDuration(&timeout, "database.timeout", 30*time.Second). Apply()
Performance characteristics:
- 1,609,530+ binding operations per second
- ~744 nanoseconds per binding operation
- Zero reflection overhead using unsafe.Pointer
- Minimal memory allocations (1 per operation)
- Support for nested keys with dot notation (e.g., "database.pool.max_connections")
BoreasLite: Ultra-Fast Event Processing ¶
At the heart of Argus is BoreasLite, a specialized MPSC ring buffer optimized for configuration file events with adaptive performance strategies.
Adaptive optimization strategies:
**SingleEvent**: Ultra-low latency for 1-2 files (24ns per event)
**SmallBatch**: Balanced performance for 3-20 files
**LargeBatch**: High throughput for 20+ files with 4x unrolling
**Auto**: Automatically adapts based on file count
config := argus.Config{ PollInterval: 5 * time.Second, OptimizationStrategy: argus.OptimizationAuto, BoreasLiteCapacity: 128, } watcher := argus.New(config)
Production-Grade Monitoring ¶
Argus uses intelligent polling rather than OS-specific APIs for maximum portability and predictable behavior across all platforms.
Advanced file monitoring with caching:
config := argus.Config{
PollInterval: 5 * time.Second,
CacheTTL: 2 * time.Second, // Cache os.Stat() calls
MaxWatchedFiles: 100,
ErrorHandler: func(err error, path string) {
metrics.Increment("config.errors")
log.Printf("Config error in %s: %v", path, err)
},
}
watcher := argus.New(config)
err := watcher.Watch("/app/config.json", func(event argus.ChangeEvent) {
if event.IsModify {
// Reload configuration
reloadConfig(event.Path)
}
})
watcher.Start()
defer watcher.Close()
Comprehensive Audit System ¶
Built-in audit logging provides security and compliance capabilities with tamper detection, structured logging, and unified SQLite backend for persistence.
auditConfig := argus.AuditConfig{
Enabled: true,
OutputFile: "/var/log/argus/audit.jsonl",
SQLiteFile: "/var/log/argus/audit.db", // Unified SQLite backend
MinLevel: argus.AuditInfo,
BufferSize: 1000,
FlushInterval: 5 * time.Second,
EnableSQLite: true, // Enable database persistence
}
Audit events include:
- Configuration file changes with before/after values
- File watch start/stop events
- Security events (path traversal attempts, DoS detection, watch limit exceeded)
- Tamper-detection checksums using SHA-256
- Process context and timestamps
- Unified storage in SQLite for queryable audit trails and compliance reporting
Security Hardening Layer ¶
Argus implements comprehensive security controls to protect against common attack vectors, making it safe for production environments with untrusted input.
Multi-layer path validation prevents directory traversal attacks:
// All file paths are automatically validated through 7 security layers: // 1. Empty/null path rejection // 2. Directory traversal pattern detection (.., ../, ..\\, /.., \\.., ./) // 3. Path length limits (max 4096 characters) // 4. Directory depth limits (max 50 levels) // 5. Control character filtering (\x00-\x1f, \x7f-\x9f) // 6. Symlink resolution with safety checks // 7. Windows Alternate Data Stream (ADS) protection
DoS protection through resource limits:
config := argus.Config{
MaxWatchedFiles: 1000, // Prevent file descriptor exhaustion
PollInterval: 100*time.Millisecond, // Min 100ms to prevent CPU DoS
CacheTTL: 1*time.Second, // Min 1s cache TTL
}
Environment variable validation prevents injection attacks:
// All environment variables are validated for: // - Valid UTF-8 encoding // - Safe numeric ranges (poll intervals, cache TTL, file limits) // - Path safety (config file paths, audit log paths) // - Prevention of performance degradation attacks
Remote Configuration Management ¶
Argus supports distributed configuration management with built-in failover, synchronization, and conflict resolution for multi-instance deployments.
remoteConfig := argus.RemoteConfig{
Enabled: true,
PrimaryURL: "https://config.example.com/api/v1",
FallbackPath: "/etc/argus/fallback.json",
SyncInterval: 30 * time.Second,
TimeoutConfig: argus.TimeoutConfig{
Connection: 5 * time.Second,
Read: 10 * time.Second,
},
}
Remote configuration features:
- Automatic failover to local fallback files
- Conflict resolution with configurable merge strategies
- Encrypted transport with TLS certificate validation
- Graceful degradation when remote endpoints are unavailable
- Audit logging of all remote configuration changes
Graceful Shutdown System ¶
Built-in graceful shutdown ensures clean resource cleanup and prevents data loss during application termination.
// Automatic graceful shutdown on SIGINT/SIGTERM
watcher := argus.New(config)
defer watcher.GracefulShutdown(30 * time.Second) // 30s timeout
// Manual shutdown with custom timeout
shutdownComplete := watcher.InitiateShutdown()
select {
case <-shutdownComplete:
log.Info("Argus shutdown completed successfully")
case <-time.After(10 * time.Second):
log.Warn("Argus shutdown timeout, forcing termination")
}
Shutdown sequence includes:
- Stop accepting new file watch requests
- Complete processing of pending events in BoreasLite buffer
- Flush audit logs to SQLite database
- Close all file descriptors and cleanup watchers
- Release system resources with proper synchronization
Plugin Architecture ¶
Argus supports pluggable parsers for production environments requiring full specification compliance or advanced features.
Register custom parsers at startup:
import _ "github.com/your-org/argus-yaml-pro" // Auto-registers in init() import _ "github.com/your-org/argus-toml-pro" // Advanced TOML features
Or manually:
argus.RegisterParser(&MyAdvancedYAMLParser{})
Performance Optimizations ¶
Argus is designed for high-performance production environments with security-first optimizations:
- **Lock-free caching**: Atomic pointers for zero-contention os.Stat() caching
- **Zero-allocation polling**: Reusable buffers and value types prevent GC pressure
- **Intelligent batching**: Event processing adapts to load patterns
- **Time optimization**: Uses go-timecache for 121x faster timestamps
- **Memory efficiency**: Sync.Pool for map reuse and careful allocation patterns
- **Security-optimized validation**: Multi-layer path validation with minimal performance impact
- **SQLite backend optimization**: Prepared statements and transaction batching for audit performance
Cross-Platform Compatibility ¶
Argus works identically on all platforms with platform-specific optimizations:
- **Linux**: Optimized for container environments and high file counts
- **macOS**: Native performance with efficient polling
- **Windows**: Proper path handling and JSON escaping
Integration Patterns ¶
Common integration patterns for different use cases:
**Microservice Configuration**:
// Hot-reload service configuration
watcher, _ := argus.UniversalConfigWatcher("service.yml", func(config map[string]interface{}) {
service.UpdateConfig(config)
})
**Feature Flags**:
// Real-time feature flag updates var enableNewAPI bool var rateLimitRPS int argus.BindFromConfig(config). BindBool(&enableNewAPI, "features.new_api", false). BindInt(&rateLimitRPS, "rate_limit.rps", 1000). Apply()
**Database Connection Pools**:
// Dynamic connection pool sizing
var maxConns int
var idleTimeout time.Duration
watcher.Watch("db.toml", func(event argus.ChangeEvent) {
argus.BindFromConfig(config).
BindInt(&maxConns, "pool.max_connections", 10).
BindDuration(&idleTimeout, "pool.idle_timeout", 5*time.Minute).
Apply()
db.UpdatePoolConfig(maxConns, idleTimeout)
})
Thread Safety and Concurrency ¶
All Argus components are thread-safe and optimized for concurrent access:
- Configuration binding supports concurrent reads
- File watching uses atomic operations for state management
- Audit logging uses buffered writes with proper synchronization
- BoreasLite ring buffer is MPSC (Multiple Producer, Single Consumer)
Error Handling and Observability ¶
Argus provides comprehensive error handling and observability:
- Structured error messages with context
- Configurable error handlers for custom logging/metrics
- Built-in statistics for monitoring ring buffer performance
- Audit trail for all configuration changes and system events
Getting Started ¶
For detailed examples and documentation:
- examples/config_binding/ - Ultra-fast binding system demo
- examples/error_handling/ - Error handling patterns and best practices
- examples/config_validation/ - Configuration validation examples
- docs/quick-start.md - Getting started guide
- docs/api-reference.md - Full API reference
- docs/audit-system.md - Audit system and SQLite backend configuration
- docs/architecture.md - System architecture and scaling guide
- docs/parser-guide.md - Configuration parser system and plugins
- docs/cli-integration.md - CLI integration with Orpheus framework
- docs/remote-config-api.md - Remote configuration API reference
- SECURITY.md - Security hardening and best practices
For production deployments, see docs/architecture.md for scaling, performance tuning, and security configuration recommendations.
Repository: https://github.com/agilira/argus
Index ¶
- Constants
- Variables
- func ConfigEquals(config1, config2 map[string]interface{}) bool
- func GetEnvBoolWithDefault(key string, defaultValue bool) bool
- func GetEnvDurationWithDefault(key string, defaultValue time.Duration) time.Duration
- func GetEnvIntWithDefault(key string, defaultValue int) int
- func GetEnvWithDefault(key, defaultValue string) string
- func GetValidationErrorCode(err error) string
- func HealthCheckRemoteProvider(configURL string, opts ...*RemoteConfigOptions) error
- func HealthCheckRemoteProviderWithContext(ctx context.Context, configURL string, opts ...*RemoteConfigOptions) error
- func IsValidationError(err error) bool
- func LoadRemoteConfig(configURL string, opts ...*RemoteConfigOptions) (map[string]interface{}, error)
- func LoadRemoteConfigWithContext(ctx context.Context, configURL string, opts ...*RemoteConfigOptions) (map[string]interface{}, error)
- func ParseConfig(data []byte, format ConfigFormat) (map[string]interface{}, error)
- func RegisterParser(parser ConfigParser)
- func RegisterRemoteProvider(provider RemoteConfigProvider) error
- func ValidateConfigFile(configPath string) error
- func ValidateEnvironmentConfig() error
- func ValidateSecurePath(path string) error
- func WatchRemoteConfig(configURL string, opts ...*RemoteConfigOptions) (<-chan map[string]interface{}, error)
- func WatchRemoteConfigWithContext(ctx context.Context, configURL string, opts ...*RemoteConfigOptions) (<-chan map[string]interface{}, error)
- type AuditConfig
- type AuditDatabaseStats
- type AuditEvent
- type AuditLevel
- type AuditLogger
- func (al *AuditLogger) Close() error
- func (al *AuditLogger) Flush() error
- func (al *AuditLogger) Log(level AuditLevel, event, component, filePath string, ...)
- func (al *AuditLogger) LogConfigChange(filePath string, oldConfig, newConfig map[string]interface{})
- func (al *AuditLogger) LogFileWatch(event, filePath string)
- func (al *AuditLogger) LogSecurityEvent(event, details string, context map[string]interface{})
- type BoreasLite
- func (b *BoreasLite) AdaptStrategy(fileCount int)
- func (b *BoreasLite) ProcessBatch() int
- func (b *BoreasLite) RunProcessor()
- func (b *BoreasLite) Stats() map[string]int64
- func (b *BoreasLite) Stop()
- func (b *BoreasLite) WriteFileChange(path string, modTime time.Time, size int64, isCreate, isDelete, isModify bool) bool
- func (b *BoreasLite) WriteFileEvent(event *FileChangeEvent) bool
- type CacheStats
- type ChangeEvent
- type Config
- type ConfigBinder
- func (cb *ConfigBinder) Apply() error
- func (cb *ConfigBinder) BindBool(target *bool, key string, defaultValue ...bool) *ConfigBinder
- func (cb *ConfigBinder) BindDuration(target *time.Duration, key string, defaultValue ...time.Duration) *ConfigBinder
- func (cb *ConfigBinder) BindFloat64(target *float64, key string, defaultValue ...float64) *ConfigBinder
- func (cb *ConfigBinder) BindInt(target *int, key string, defaultValue ...int) *ConfigBinder
- func (cb *ConfigBinder) BindInt64(target *int64, key string, defaultValue ...int64) *ConfigBinder
- func (cb *ConfigBinder) BindString(target *string, key string, defaultValue ...string) *ConfigBinder
- type ConfigFormat
- type ConfigManager
- func (cm *ConfigManager) BoolFlag(name string, defaultValue bool, usage string) *ConfigManager
- func (cm *ConfigManager) DurationFlag(name string, defaultValue time.Duration, usage string) *ConfigManager
- func (cm *ConfigManager) FlagToEnvKey(flagName string) string
- func (cm *ConfigManager) Float64Flag(name string, defaultValue float64, usage string) *ConfigManager
- func (cm *ConfigManager) GetBool(key string) bool
- func (cm *ConfigManager) GetBoundFlags() map[string]string
- func (cm *ConfigManager) GetDuration(key string) time.Duration
- func (cm *ConfigManager) GetInt(key string) int
- func (cm *ConfigManager) GetStats() (total, valid int)
- func (cm *ConfigManager) GetString(key string) string
- func (cm *ConfigManager) GetStringSlice(key string) []string
- func (cm *ConfigManager) IntFlag(name string, defaultValue int, usage string) *ConfigManager
- func (cm *ConfigManager) LoadConfigFile(path string) error
- func (cm *ConfigManager) Parse(args []string) error
- func (cm *ConfigManager) ParseArgs() error
- func (cm *ConfigManager) ParseArgsOrExit()
- func (cm *ConfigManager) PrintUsage()
- func (cm *ConfigManager) Set(key string, value interface{})
- func (cm *ConfigManager) SetDefault(key string, value interface{})
- func (cm *ConfigManager) SetDescription(description string) *ConfigManager
- func (cm *ConfigManager) SetVersion(version string) *ConfigManager
- func (cm *ConfigManager) StartWatching() error
- func (cm *ConfigManager) StopWatching() error
- func (cm *ConfigManager) StringFlag(name, defaultValue, usage string) *ConfigManager
- func (cm *ConfigManager) StringSliceFlag(name string, defaultValue []string, usage string) *ConfigManager
- func (cm *ConfigManager) WatchConfigFile(path string, callback func()) error
- type ConfigParser
- type ConfigWriter
- func (w *ConfigWriter) DeleteValue(key string) bool
- func (w *ConfigWriter) GetConfig() map[string]interface{}
- func (w *ConfigWriter) GetValue(key string) interface{}
- func (w *ConfigWriter) HasChanges() bool
- func (w *ConfigWriter) ListKeys(prefix string) []string
- func (w *ConfigWriter) Reset() error
- func (w *ConfigWriter) SetValue(key string, value interface{}) error
- func (w *ConfigWriter) WriteConfig() error
- func (w *ConfigWriter) WriteConfigAs(filePath string) error
- type EnvConfig
- type ErrorHandler
- type FileChangeEvent
- type IdleStrategy
- type OptimizationStrategy
- type RemoteConfig
- type RemoteConfigManager
- type RemoteConfigOptions
- type RemoteConfigProvider
- type SleepStrategy
- type UpdateCallback
- type ValidationResult
- type Watcher
- func GenericConfigWatcher(configPath string, callback func(config map[string]interface{})) (*Watcher, error)
- func New(config Config) *Watcher
- func SimpleFileWatcher(filePath string, callback func(path string)) (*Watcher, error)
- func UniversalConfigWatcher(configPath string, callback func(config map[string]interface{})) (*Watcher, error)
- func UniversalConfigWatcherWithConfig(configPath string, callback func(config map[string]interface{}), config Config) (*Watcher, error)
- func (w *Watcher) ClearCache()
- func (w *Watcher) Close() error
- func (w *Watcher) GetCacheStats() CacheStats
- func (w *Watcher) GetWriter(filePath string, format ConfigFormat, initialConfig map[string]interface{}) (*ConfigWriter, error)
- func (w *Watcher) GracefulShutdown(timeout time.Duration) error
- func (w *Watcher) IsRunning() bool
- func (w *Watcher) Start() error
- func (w *Watcher) Stop() error
- func (w *Watcher) Unwatch(path string) error
- func (w *Watcher) Watch(path string, callback UpdateCallback) error
- func (w *Watcher) WatchedFiles() int
Constants ¶
const ( ErrCodeInvalidConfig = "ARGUS_INVALID_CONFIG" ErrCodeFileNotFound = "ARGUS_FILE_NOT_FOUND" ErrCodeWatcherStopped = "ARGUS_WATCHER_STOPPED" ErrCodeWatcherBusy = "ARGUS_WATCHER_BUSY" ErrCodeRemoteConfigError = "ARGUS_REMOTE_CONFIG_ERROR" ErrCodeConfigNotFound = "ARGUS_CONFIG_NOT_FOUND" ErrCodeInvalidPollInterval = "ARGUS_INVALID_POLL_INTERVAL" ErrCodeInvalidCacheTTL = "ARGUS_INVALID_CACHE_TTL" ErrCodeInvalidMaxWatchedFiles = "ARGUS_INVALID_MAX_WATCHED_FILES" ErrCodeInvalidOptimization = "ARGUS_INVALID_OPTIMIZATION" ErrCodeInvalidAuditConfig = "ARGUS_INVALID_AUDIT_CONFIG" ErrCodeInvalidBufferSize = "ARGUS_INVALID_BUFFER_SIZE" ErrCodeInvalidFlushInterval = "ARGUS_INVALID_FLUSH_INTERVAL" ErrCodeInvalidOutputFile = "ARGUS_INVALID_OUTPUT_FILE" ErrCodeUnwritableOutputFile = "ARGUS_UNWRITABLE_OUTPUT_FILE" ErrCodeCacheTTLTooLarge = "ARGUS_CACHE_TTL_TOO_LARGE" ErrCodePollIntervalTooSmall = "ARGUS_POLL_INTERVAL_TOO_SMALL" ErrCodeMaxFilesTooLarge = "ARGUS_MAX_FILES_TOO_LARGE" ErrCodeBoreasCapacityInvalid = "ARGUS_INVALID_BOREAS_CAPACITY" ErrCodeConfigWriterError = "ARGUS_CONFIG_WRITER_ERROR" ErrCodeSerializationError = "ARGUS_SERIALIZATION_ERROR" ErrCodeIOError = "ARGUS_IO_ERROR" )
Error codes for Argus operations
const ( FileEventCreate uint8 = 1 << iota FileEventDelete FileEventModify )
Event flags for file changes
Variables ¶
var ( ErrInvalidPollInterval = errors.New(ErrCodeInvalidPollInterval, "poll interval must be positive") ErrInvalidCacheTTL = errors.New(ErrCodeInvalidCacheTTL, "cache TTL must be positive") ErrInvalidMaxWatchedFiles = errors.New(ErrCodeInvalidMaxWatchedFiles, "max watched files must be positive") ErrInvalidOptimization = errors.New(ErrCodeInvalidOptimization, "unknown optimization strategy") ErrInvalidAuditConfig = errors.New(ErrCodeInvalidAuditConfig, "audit configuration is invalid") ErrInvalidBufferSize = errors.New(ErrCodeInvalidBufferSize, "buffer size must be positive") ErrInvalidFlushInterval = errors.New(ErrCodeInvalidFlushInterval, "flush interval must be positive") ErrInvalidOutputFile = errors.New(ErrCodeInvalidOutputFile, "audit output file path is invalid") ErrUnwritableOutputFile = errors.New(ErrCodeUnwritableOutputFile, "audit output file is not writable") ErrCacheTTLTooLarge = errors.New(ErrCodeCacheTTLTooLarge, "cache TTL should not exceed poll interval") ErrPollIntervalTooSmall = errors.New(ErrCodePollIntervalTooSmall, "poll interval should be at least 10ms for stability") ErrMaxFilesTooLarge = errors.New(ErrCodeMaxFilesTooLarge, "max watched files exceeds recommended limit (10000)") ErrBoreasCapacityInvalid = errors.New(ErrCodeBoreasCapacityInvalid, "BoreasLite capacity must be power of 2") )
Validation errors - implementing error codes pattern from Iris
Functions ¶
func ConfigEquals ¶ added in v1.0.3
ConfigEquals performs a basic equality check for configurations. This utility function compares two configuration maps for equality by comparing their keys and values. It uses string representation for value comparison, making it suitable for basic configuration comparison needs.
Example:
config1 := map[string]interface{}{"key": "value", "count": 42}
config2 := map[string]interface{}{"key": "value", "count": 42}
if argus.ConfigEquals(config1, config2) {
log.Println("Configurations are identical")
}
Note: This function uses string comparison for values, so it may not handle complex nested structures or type-sensitive comparisons perfectly. For production use cases requiring deep equality, consider using reflect.DeepEqual or specialized comparison libraries.
func GetEnvBoolWithDefault ¶ added in v1.0.1
GetEnvBoolWithDefault returns environment variable as bool or default
func GetEnvDurationWithDefault ¶ added in v1.0.1
GetEnvDurationWithDefault returns environment variable as duration or default
func GetEnvIntWithDefault ¶ added in v1.0.1
GetEnvIntWithDefault returns environment variable as int or default
func GetEnvWithDefault ¶ added in v1.0.1
GetEnvWithDefault returns environment variable value or default if not set
func GetValidationErrorCode ¶ added in v1.0.1
GetValidationErrorCode extracts the error code from an Argus validation error
func HealthCheckRemoteProvider ¶ added in v1.0.1
func HealthCheckRemoteProvider(configURL string, opts ...*RemoteConfigOptions) error
HealthCheckRemoteProvider performs a health check on a remote configuration provider
func HealthCheckRemoteProviderWithContext ¶ added in v1.0.1
func HealthCheckRemoteProviderWithContext(ctx context.Context, configURL string, opts ...*RemoteConfigOptions) error
HealthCheckRemoteProviderWithContext performs a health check with context
func IsValidationError ¶ added in v1.0.1
IsValidationError checks if an error is an Argus validation error
func LoadRemoteConfig ¶ added in v1.0.1
func LoadRemoteConfig(configURL string, opts ...*RemoteConfigOptions) (map[string]interface{}, error)
LoadRemoteConfig loads configuration from a remote source using default context. Automatically detects provider based on URL scheme and handles retries.
Example:
config, err := argus.LoadRemoteConfig("redis://localhost:6379/config")
config, err := argus.LoadRemoteConfig("consul://localhost:8500/config/myapp")
func LoadRemoteConfigWithContext ¶ added in v1.0.1
func LoadRemoteConfigWithContext(ctx context.Context, configURL string, opts ...*RemoteConfigOptions) (map[string]interface{}, error)
LoadRemoteConfigWithContext loads configuration from a remote source with custom context. Provides full control over timeouts and cancellation for remote configuration loading.
func ParseConfig ¶
func ParseConfig(data []byte, format ConfigFormat) (map[string]interface{}, error)
ParseConfig parses configuration data based on the detected format. Tries custom parsers first, then falls back to built-in parsers. HYPER-OPTIMIZED: Fast path for no custom parsers, reduced lock contention.
Parameters:
- data: Raw configuration file bytes
- format: Detected configuration format
Returns:
- map[string]interface{}: Parsed configuration data
- error: Any parsing errors
func RegisterParser ¶
func RegisterParser(parser ConfigParser)
RegisterParser registers a custom parser for production use cases. Custom parsers are tried before built-in parsers, allowing for full specification compliance or advanced features not available in built-in parsers.
Example:
argus.RegisterParser(&MyAdvancedYAMLParser{})
Or via import-based registration:
import _ "github.com/your-org/argus-yaml-pro"
func RegisterRemoteProvider ¶ added in v1.0.1
func RegisterRemoteProvider(provider RemoteConfigProvider) error
RegisterRemoteProvider registers a custom remote configuration provider. Providers are tried in registration order. Duplicate schemes are rejected.
Example:
argus.RegisterRemoteProvider(&MyCustomProvider{})
Or via import-based auto-registration:
import _ "github.com/agilira/argus-redis" // Auto-registers in init()
func ValidateConfigFile ¶ added in v1.0.1
ValidateConfigFile validates a configuration that would be loaded from a file This method performs validation without actually starting file watching
func ValidateEnvironmentConfig ¶ added in v1.0.1
func ValidateEnvironmentConfig() error
ValidateEnvironmentConfig validates environment-loaded configuration This is a convenience method for validating configs loaded from environment variables
func ValidateSecurePath ¶ added in v1.0.3
ValidateSecurePath validates that a file path is safe from path traversal attacks.
SECURITY PURPOSE: Prevents directory traversal attacks (CWE-22) by rejecting paths that contain dangerous patterns or attempt to escape the intended directory.
This function implements multiple layers of protection: 1. Pattern-based detection of traversal sequences (case-insensitive) 2. URL decoding to catch encoded attacks 3. Normalization attacks prevention 4. System file protection 5. Device name filtering (Windows)
SECURITY NOTICE: All validation is performed case-insensitively to ensure consistent protection across different file systems and OS configurations.
CRITICAL: This function must be called on ALL user-provided paths before any file operations to prevent security vulnerabilities.
This function is exported to allow external packages to use the same security validation logic as the core Argus library.
func WatchRemoteConfig ¶ added in v1.0.1
func WatchRemoteConfig(configURL string, opts ...*RemoteConfigOptions) (<-chan map[string]interface{}, error)
WatchRemoteConfig starts watching a remote configuration source for changes
func WatchRemoteConfigWithContext ¶ added in v1.0.1
func WatchRemoteConfigWithContext(ctx context.Context, configURL string, opts ...*RemoteConfigOptions) (<-chan map[string]interface{}, error)
WatchRemoteConfigWithContext starts watching a remote configuration source with context
Types ¶
type AuditConfig ¶
type AuditConfig struct {
Enabled bool `json:"enabled"`
OutputFile string `json:"output_file"`
MinLevel AuditLevel `json:"min_level"`
BufferSize int `json:"buffer_size"`
FlushInterval time.Duration `json:"flush_interval"`
IncludeStack bool `json:"include_stack"`
}
AuditConfig configures the audit system
func DefaultAuditConfig ¶
func DefaultAuditConfig() AuditConfig
DefaultAuditConfig returns secure default audit configuration with unified SQLite storage.
The default configuration uses the unified SQLite audit system, which consolidates all Argus audit events into a single system-wide database. This provides:
- Cross-component event correlation
- Efficient storage and querying
- Automatic schema management
- WAL mode for concurrent access
For applications requiring JSONL format, specify OutputFile with .jsonl extension.
type AuditDatabaseStats ¶ added in v1.0.2
type AuditDatabaseStats struct {
TotalEvents int64 `json:"total_events"`
EventsByLevel map[string]int64 `json:"events_by_level"`
EventsByComponent map[string]int64 `json:"events_by_component"`
OldestEvent *time.Time `json:"oldest_event"`
NewestEvent *time.Time `json:"newest_event"`
DatabaseSize int64 `json:"database_size_bytes"`
SchemaVersion int `json:"schema_version"`
}
AuditDatabaseStats represents statistics about the unified audit database.
type AuditEvent ¶
type AuditEvent struct {
Timestamp time.Time `json:"timestamp"`
Level AuditLevel `json:"level"`
Event string `json:"event"`
Component string `json:"component"`
FilePath string `json:"file_path,omitempty"`
OldValue interface{} `json:"old_value,omitempty"`
NewValue interface{} `json:"new_value,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
ProcessID int `json:"process_id"`
ProcessName string `json:"process_name"`
Context map[string]interface{} `json:"context,omitempty"`
Checksum string `json:"checksum"` // For tamper detection
}
AuditEvent represents a single auditable event
type AuditLevel ¶
type AuditLevel int
AuditLevel represents the severity of audit events
const ( AuditInfo AuditLevel = iota AuditWarn AuditCritical AuditSecurity )
func (AuditLevel) String ¶
func (al AuditLevel) String() string
type AuditLogger ¶
type AuditLogger struct {
// contains filtered or unexported fields
}
AuditLogger provides high-performance audit logging with pluggable backends.
This logger implements a unified audit system that automatically selects the optimal storage backend (SQLite for unified system audit, JSONL for backward compatibility) while maintaining the same public API.
The logger uses buffering and background flushing for optimal performance in high-throughput scenarios while ensuring audit integrity.
func NewAuditLogger ¶
func NewAuditLogger(config AuditConfig) (*AuditLogger, error)
NewAuditLogger creates a new audit logger with automatic backend selection.
The logger automatically selects the optimal audit backend based on system capabilities and configuration:
- SQLite unified backend for consolidation (preferred)
- JSONL fallback for compatibility
This approach ensures seamless migration to unified audit trails while maintaining backward compatibility with existing configurations.
Parameters:
- config: Audit configuration specifying behavior and output preferences
Returns:
- Configured audit logger ready for use
- Error if both backend initialization attempts fail
func (*AuditLogger) Close ¶
func (al *AuditLogger) Close() error
Close gracefully shuts down the audit logger
func (*AuditLogger) Flush ¶
func (al *AuditLogger) Flush() error
Flush immediately writes all buffered events
func (*AuditLogger) Log ¶
func (al *AuditLogger) Log(level AuditLevel, event, component, filePath string, oldVal, newVal interface{}, context map[string]interface{})
Log records an audit event with ultra-high performance
func (*AuditLogger) LogConfigChange ¶
func (al *AuditLogger) LogConfigChange(filePath string, oldConfig, newConfig map[string]interface{})
LogConfigChange logs configuration file changes (most common use case)
func (*AuditLogger) LogFileWatch ¶
func (al *AuditLogger) LogFileWatch(event, filePath string)
LogFileWatch logs file watch events
func (*AuditLogger) LogSecurityEvent ¶
func (al *AuditLogger) LogSecurityEvent(event, details string, context map[string]interface{})
LogSecurityEvent logs security-related events
type BoreasLite ¶
type BoreasLite struct {
// contains filtered or unexported fields
}
BoreasLite - Ultra-fast MPSC ring buffer for file watching Optimized for Argus-specific use cases:
- Small number of files (typically 1-10)
- Infrequent events (file changes are rare)
- Low latency priority (immediate callback execution)
- Minimal memory footprint
func NewBoreasLite ¶
func NewBoreasLite(capacity int64, strategy OptimizationStrategy, processor func(*FileChangeEvent)) *BoreasLite
NewBoreasLite creates a new ultra-fast ring buffer for file events
Parameters:
- capacity: Ring buffer size (must be power of 2)
- strategy: Optimization strategy for performance tuning
- processor: Function to process file change events
Returns:
- *BoreasLite: Ready-to-use ring buffer
func (*BoreasLite) AdaptStrategy ¶
func (b *BoreasLite) AdaptStrategy(fileCount int)
AdaptStrategy dynamically adjusts the optimization strategy based on file count. This is called when OptimizationAuto is used and file count changes. Automatically selects the optimal batch size for current workload:
- 1-3 files: SingleEvent (ultra-low latency, 24.91ns)
- 4-50 files: SmallBatch (balanced performance, 100% detection)
- 51+ files: LargeBatch (high throughput, 1000+ files supported)
func (*BoreasLite) ProcessBatch ¶
func (b *BoreasLite) ProcessBatch() int
ProcessBatch processes available events in small batches Optimized for low latency - smaller batches than ZephyrosLite
Returns:
- int: Number of events processed
func (*BoreasLite) RunProcessor ¶
func (b *BoreasLite) RunProcessor()
RunProcessor runs the consumer loop with strategy-optimized behavior
func (*BoreasLite) Stats ¶
func (b *BoreasLite) Stats() map[string]int64
Stats returns minimal statistics for monitoring ring buffer performance. Provides real-time metrics for debugging and performance analysis.
Returns a map containing:
- writer_position: Current writer sequence number
- reader_position: Current reader sequence number
- buffer_size: Ring buffer capacity
- items_buffered: Number of events waiting to be processed
- items_processed: Total events processed since startup
- items_dropped: Total events dropped due to buffer overflow
- running: 1 if processor is running, 0 if stopped
func (*BoreasLite) Stop ¶
func (b *BoreasLite) Stop()
Stop stops the processor immediately without graceful shutdown. Optimized for file watching use cases where immediate termination is acceptable. Sets the running flag to false, causing all processor loops to exit.
func (*BoreasLite) WriteFileChange ¶
func (b *BoreasLite) WriteFileChange(path string, modTime time.Time, size int64, isCreate, isDelete, isModify bool) bool
WriteFileChange is a convenience method for creating events from parameters. Slightly slower than WriteFileEvent but more convenient for direct parameter usage. Automatically handles path length limits and flag setting.
Parameters:
- path: File path (automatically truncated if > 109 characters)
- modTime: File modification time
- size: File size in bytes
- isCreate: True if this is a file creation event
- isDelete: True if this is a file deletion event
- isModify: True if this is a file modification event
Returns:
- bool: true if event was successfully queued, false if buffer is full
func (*BoreasLite) WriteFileEvent ¶
func (b *BoreasLite) WriteFileEvent(event *FileChangeEvent) bool
WriteFileEvent adds a file change event to the ring buffer ZERO ALLOCATIONS - uses provided event struct directly
Parameters:
- event: Pre-populated file change event
Returns:
- bool: true if written, false if ring is full/closed
Performance: Target <8ns per operation
type CacheStats ¶
type CacheStats struct {
Entries int // Number of cached entries
OldestAge time.Duration // Age of oldest cache entry
NewestAge time.Duration // Age of newest cache entry
}
CacheStats returns statistics about the internal cache for monitoring and debugging. Provides insights into cache efficiency and performance characteristics.
type ChangeEvent ¶
type ChangeEvent struct {
Path string // File path that changed
ModTime time.Time // New modification time
Size int64 // New file size
IsCreate bool // True if file was created
IsDelete bool // True if file was deleted
IsModify bool // True if file was modified
}
ChangeEvent represents a file change notification
func ConvertFileEventToChangeEvent ¶
func ConvertFileEventToChangeEvent(fileEvent FileChangeEvent) ChangeEvent
ConvertFileEventToChangeEvent converts FileChangeEvent back to standard ChangeEvent. Used when delivering events to user callbacks, converting from BoreasLite's optimized internal format back to the public API format.
type Config ¶
type Config struct {
// PollInterval is how often to check for file changes
// Default: 5 seconds (good balance of responsiveness vs overhead)
PollInterval time.Duration
// CacheTTL is how long to cache os.Stat() results
// Should be <= PollInterval for effectiveness
// Default: PollInterval / 2
CacheTTL time.Duration
// MaxWatchedFiles limits the number of files that can be watched
// Default: 100 (generous for config files)
MaxWatchedFiles int
// Audit configuration for security and compliance
// Default: Enabled with secure defaults
Audit AuditConfig
// ErrorHandler is called when errors occur during file watching/parsing
// If nil, errors are logged to stderr (backward compatible)
// Example: func(err error, path string) { metrics.Increment("config.errors") }
ErrorHandler ErrorHandler
// OptimizationStrategy determines how BoreasLite optimizes performance
// - OptimizationAuto: Automatically choose based on file count (default)
// - OptimizationSingleEvent: Ultra-low latency for 1-2 files
// - OptimizationSmallBatch: Balanced for 3-20 files
// - OptimizationLargeBatch: High throughput for 20+ files
OptimizationStrategy OptimizationStrategy
// BoreasLiteCapacity sets the ring buffer size (must be power of 2)
// - Auto/SingleEvent: 64 (minimal memory)
// - SmallBatch: 128 (balanced)
// - LargeBatch: 256+ (high throughput)
// Default: 0 (auto-calculated based on strategy)
BoreasLiteCapacity int64
// Remote configuration with automatic fallback capabilities
// When enabled, provides distributed configuration management with local fallback
// Default: Disabled for backward compatibility
Remote RemoteConfig
}
Config configures the Argus watcher behavior
func LoadConfigFromEnv ¶ added in v1.0.1
LoadConfigFromEnv loads Argus configuration from environment variables This provides an intuitive interface for container deployments
func LoadConfigMultiSource ¶ added in v1.0.1
LoadConfigMultiSource loads configuration with precedence: 1. Environment variables (highest priority) 2. Configuration file (medium priority) - supports JSON, YAML, TOML, HCL, INI, Properties 3. Default values (lowest priority)
This provides complete multi-source configuration loading with:
- Universal format auto-detection from file extension
- Security validation for configuration file paths
- Graceful fallback when file doesn't exist or fails to parse
- Environment variable override of any file-based settings
Example:
config, err := LoadConfigMultiSource("config.yaml")
// Loads config.yaml, overrides with ARGUS_* environment variables
Parameters:
- configFile: Path to configuration file (optional, "" for env-only config)
Returns:
- *Config: Merged configuration with precedence applied
- error: Any critical errors in environment variable parsing
func (*Config) Validate ¶ added in v1.0.1
Validate performs comprehensive validation of the Argus configuration Returns error if configuration is invalid, warnings are included in ValidationResult
func (*Config) ValidateDetailed ¶ added in v1.0.1
func (c *Config) ValidateDetailed() ValidationResult
ValidateDetailed performs comprehensive validation and returns detailed results including both errors and warnings for better debugging and monitoring
func (*Config) WithDefaults ¶
WithDefaults applies sensible defaults to the configuration and validates settings. Returns a new Config instance with all required fields populated. Ensures proper relationships between settings (e.g., CacheTTL <= PollInterval).
Default values:
- PollInterval: 5 seconds
- CacheTTL: PollInterval / 2
- MaxWatchedFiles: 100
- BoreasLiteCapacity: Strategy-dependent (64-256)
- Audit: Enabled with secure defaults
type ConfigBinder ¶ added in v1.0.1
type ConfigBinder struct {
// contains filtered or unexported fields
}
ConfigBinder provides ultra-fast configuration binding with fluent API
func BindFromConfig ¶ added in v1.0.1
func BindFromConfig(config map[string]interface{}) *ConfigBinder
BindFromConfig creates a new ConfigBinder from a parsed configuration map This is the main entry point for users
func NewConfigBinder ¶ added in v1.0.1
func NewConfigBinder(config map[string]interface{}) *ConfigBinder
NewConfigBinder creates a new high-performance configuration binder
func (*ConfigBinder) Apply ¶ added in v1.0.1
func (cb *ConfigBinder) Apply() error
Apply executes all bindings in a single optimized pass This is where the magic happens - ultra-fast batch processing
func (*ConfigBinder) BindBool ¶ added in v1.0.1
func (cb *ConfigBinder) BindBool(target *bool, key string, defaultValue ...bool) *ConfigBinder
BindBool binds a boolean configuration value with optional default
func (*ConfigBinder) BindDuration ¶ added in v1.0.1
func (cb *ConfigBinder) BindDuration(target *time.Duration, key string, defaultValue ...time.Duration) *ConfigBinder
BindDuration binds a time.Duration configuration value with optional default
func (*ConfigBinder) BindFloat64 ¶ added in v1.0.1
func (cb *ConfigBinder) BindFloat64(target *float64, key string, defaultValue ...float64) *ConfigBinder
BindFloat64 binds a float64 configuration value with optional default
func (*ConfigBinder) BindInt ¶ added in v1.0.1
func (cb *ConfigBinder) BindInt(target *int, key string, defaultValue ...int) *ConfigBinder
BindInt binds an integer configuration value with optional default
func (*ConfigBinder) BindInt64 ¶ added in v1.0.1
func (cb *ConfigBinder) BindInt64(target *int64, key string, defaultValue ...int64) *ConfigBinder
BindInt64 binds an int64 configuration value with optional default
func (*ConfigBinder) BindString ¶ added in v1.0.1
func (cb *ConfigBinder) BindString(target *string, key string, defaultValue ...string) *ConfigBinder
BindString binds a string configuration value with optional default
type ConfigFormat ¶
type ConfigFormat int
ConfigFormat represents supported configuration file formats for auto-detection. Used by the format detection system to determine appropriate parser selection.
const ( FormatJSON ConfigFormat = iota FormatYAML FormatTOML FormatHCL FormatINI FormatProperties FormatUnknown )
func DetectFormat ¶
func DetectFormat(filePath string) ConfigFormat
DetectFormat detects the configuration format from file extension HYPER-OPTIMIZED: Zero allocations, perfect hashing, unrolled loops Note: High cyclomatic complexity (38) is justified for optimal performance across 7 configuration formats with zero memory allocation
func (ConfigFormat) String ¶
func (cf ConfigFormat) String() string
String returns the string representation of the config format for debugging and logging.
type ConfigManager ¶ added in v1.0.1
type ConfigManager struct {
// contains filtered or unexported fields
}
ConfigManager combines all configuration sources in a unified interface. Integrates FlashFlags for command-line parsing with Argus file watching and provides a fluent API for configuration management.
Key features:
- Ultra-fast command-line parsing via FlashFlags
- Real-time configuration file watching
- Multi-source configuration (flags, env vars, files, defaults)
- Type-safe configuration access
- Automatic environment variable mapping
func NewConfigManager ¶ added in v1.0.1
func NewConfigManager(appName string) *ConfigManager
NewConfigManager creates a unified configuration manager with FlashFlags integration. The appName is used for environment variable prefixing and help text generation.
Example:
config := argus.NewConfigManager("myapp").
SetDescription("My Application").
SetVersion("1.0.0").
StringFlag("port", "8080", "Server port")
func (*ConfigManager) BoolFlag ¶ added in v1.0.1
func (cm *ConfigManager) BoolFlag(name string, defaultValue bool, usage string) *ConfigManager
BoolFlag adds a boolean configuration flag
func (*ConfigManager) DurationFlag ¶ added in v1.0.1
func (cm *ConfigManager) DurationFlag(name string, defaultValue time.Duration, usage string) *ConfigManager
DurationFlag adds a duration configuration flag
func (*ConfigManager) FlagToEnvKey ¶ added in v1.0.1
func (cm *ConfigManager) FlagToEnvKey(flagName string) string
FlagToEnvKey converts a flag name to an environment variable key (exported version)
func (*ConfigManager) Float64Flag ¶ added in v1.0.1
func (cm *ConfigManager) Float64Flag(name string, defaultValue float64, usage string) *ConfigManager
Float64Flag adds a float64 configuration flag
func (*ConfigManager) GetBool ¶ added in v1.0.1
func (cm *ConfigManager) GetBool(key string) bool
GetBool retrieves a boolean configuration value
func (*ConfigManager) GetBoundFlags ¶ added in v1.0.1
func (cm *ConfigManager) GetBoundFlags() map[string]string
GetBoundFlags returns a map of all bound flags and their configuration keys
func (*ConfigManager) GetDuration ¶ added in v1.0.1
func (cm *ConfigManager) GetDuration(key string) time.Duration
GetDuration retrieves a duration configuration value
func (*ConfigManager) GetInt ¶ added in v1.0.1
func (cm *ConfigManager) GetInt(key string) int
GetInt retrieves an integer configuration value
func (*ConfigManager) GetStats ¶ added in v1.0.1
func (cm *ConfigManager) GetStats() (total, valid int)
GetStats returns configuration performance statistics
func (*ConfigManager) GetString ¶ added in v1.0.1
func (cm *ConfigManager) GetString(key string) string
GetString retrieves a string configuration value
func (*ConfigManager) GetStringSlice ¶ added in v1.0.1
func (cm *ConfigManager) GetStringSlice(key string) []string
GetStringSlice retrieves a string slice configuration value
func (*ConfigManager) IntFlag ¶ added in v1.0.1
func (cm *ConfigManager) IntFlag(name string, defaultValue int, usage string) *ConfigManager
IntFlag adds an integer configuration flag
func (*ConfigManager) LoadConfigFile ¶ added in v1.0.1
func (cm *ConfigManager) LoadConfigFile(path string) error
LoadConfigFile loads configuration from a file
func (*ConfigManager) Parse ¶ added in v1.0.1
func (cm *ConfigManager) Parse(args []string) error
Parse parses command-line arguments and binds them to configuration
func (*ConfigManager) ParseArgs ¶ added in v1.0.1
func (cm *ConfigManager) ParseArgs() error
ParseArgs is a convenience method that parses os.Args[1:]
func (*ConfigManager) ParseArgsOrExit ¶ added in v1.0.1
func (cm *ConfigManager) ParseArgsOrExit()
ParseArgsOrExit parses command-line arguments and exits gracefully on help/error
func (*ConfigManager) PrintUsage ¶ added in v1.0.1
func (cm *ConfigManager) PrintUsage()
PrintUsage prints help information for all flags
func (*ConfigManager) Set ¶ added in v1.0.1
func (cm *ConfigManager) Set(key string, value interface{})
Set explicitly sets a configuration value (highest precedence)
func (*ConfigManager) SetDefault ¶ added in v1.0.1
func (cm *ConfigManager) SetDefault(key string, value interface{})
SetDefault sets a default configuration value (lowest precedence)
func (*ConfigManager) SetDescription ¶ added in v1.0.1
func (cm *ConfigManager) SetDescription(description string) *ConfigManager
SetDescription sets the application description for help text
func (*ConfigManager) SetVersion ¶ added in v1.0.1
func (cm *ConfigManager) SetVersion(version string) *ConfigManager
SetVersion sets the application version for help text
func (*ConfigManager) StartWatching ¶ added in v1.0.1
func (cm *ConfigManager) StartWatching() error
StartWatching starts the configuration file watcher
func (*ConfigManager) StopWatching ¶ added in v1.0.1
func (cm *ConfigManager) StopWatching() error
StopWatching stops the configuration file watcher
func (*ConfigManager) StringFlag ¶ added in v1.0.1
func (cm *ConfigManager) StringFlag(name, defaultValue, usage string) *ConfigManager
StringFlag adds a string configuration flag
func (*ConfigManager) StringSliceFlag ¶ added in v1.0.1
func (cm *ConfigManager) StringSliceFlag(name string, defaultValue []string, usage string) *ConfigManager
StringSliceFlag adds a string slice configuration flag
func (*ConfigManager) WatchConfigFile ¶ added in v1.0.1
func (cm *ConfigManager) WatchConfigFile(path string, callback func()) error
WatchConfigFile enables real-time configuration file watching
type ConfigParser ¶
type ConfigParser interface {
// Parse parses configuration data for supported formats
Parse(data []byte) (map[string]interface{}, error)
// Supports returns true if this parser can handle the given format
Supports(format ConfigFormat) bool
// Name returns a human-readable name for this parser (for debugging)
Name() string
}
ConfigParser defines the interface for pluggable configuration parsers
PRODUCTION PARSER INTEGRATION: Go binaries are compiled statically, so "plugins" work via compile-time registration:
IMPORT-BASED REGISTRATION (Recommended): Users import parser libraries that auto-register in init():
import _ "github.com/your-org/argus-yaml-pro" // Registers advanced YAML parser import _ "github.com/your-org/argus-toml-pro" // Registers advanced TOML parser
MANUAL REGISTRATION: Users manually register parsers in their main():
argus.RegisterParser(&MyAdvancedYAMLParser{})
BUILD TAGS (Advanced): Conditional compilation for different parser sets:
go build -tags "yaml_pro,toml_pro" ./...
Built-in parsers handle 80% of use cases with zero dependencies. Production parsers provide full spec compliance and advanced features.
type ConfigWriter ¶ added in v1.0.3
type ConfigWriter struct {
// contains filtered or unexported fields
}
ConfigWriter provides zero-allocation configuration writing capabilities. It maintains the original format and structure while enabling programmatic modifications with full audit integration.
Performance characteristics:
- SetValue: 127 ns/op (0 allocs) for simple keys
- WriteConfig: File I/O bound, ~2-5ms typical
- Memory usage: Fixed 8KB + config size
Thread safety: Safe for concurrent reads, serialized writes
func NewConfigWriter ¶ added in v1.0.3
func NewConfigWriter(filePath string, format ConfigFormat, initialConfig map[string]interface{}) (*ConfigWriter, error)
newConfigWriter creates a new ConfigWriter instance with pre-allocated buffers. Internal constructor - not exposed to prevent misuse.
Performance: 89 ns/op, 1 alloc (for the struct itself) NewConfigWriter creates a new zero-allocation configuration writer. The buffer sizes are optimized for typical configuration files.
Performance: Zero allocations in hot paths, ~500 ns/op for typical operations
func NewConfigWriterWithAudit ¶ added in v1.0.3
func NewConfigWriterWithAudit(filePath string, format ConfigFormat, initialConfig map[string]interface{}, auditLogger *AuditLogger) (*ConfigWriter, error)
NewConfigWriterWithAudit creates a new configuration writer with optional audit logging. Provides the same performance characteristics as NewConfigWriter with optional audit integration.
Parameters:
- filePath: Path to the configuration file
- format: Configuration format (JSON, YAML, TOML, etc.)
- initialConfig: Initial configuration data (can be nil)
- auditLogger: Optional audit logger for compliance (can be nil for performance)
Performance: Zero allocations in hot paths, ~500 ns/op when audit is disabled
~750 ns/op when audit is enabled (minimal overhead)
func (*ConfigWriter) DeleteValue ¶ added in v1.0.3
func (w *ConfigWriter) DeleteValue(key string) bool
DeleteValue removes a configuration key using dot notation. Returns true if the key existed and was deleted, false otherwise.
Performance: 156 ns/op, 0 allocs for simple keys
Examples:
writer.DeleteValue("port") // Delete simple key
writer.DeleteValue("database.host") // Delete nested key
writer.DeleteValue("features.auth.enabled") // Delete deep nested key
func (*ConfigWriter) GetConfig ¶ added in v1.0.3
func (w *ConfigWriter) GetConfig() map[string]interface{}
GetConfig returns a deep copy of the current configuration. This enables CLI operations like list and convert without exposing internal state.
Performance: O(n) where n is config size, allocates new map
func (*ConfigWriter) GetValue ¶ added in v1.0.3
func (w *ConfigWriter) GetValue(key string) interface{}
GetValue retrieves a configuration value using dot notation. Returns nil if the key doesn't exist.
Performance: 89 ns/op, 0 allocs for simple lookups
func (*ConfigWriter) HasChanges ¶ added in v1.0.3
func (w *ConfigWriter) HasChanges() bool
HasChanges returns true if the configuration has unsaved changes. Uses fast hash comparison for O(1) performance.
func (*ConfigWriter) ListKeys ¶ added in v1.0.3
func (w *ConfigWriter) ListKeys(prefix string) []string
ListKeys returns all configuration keys in dot notation format. Optionally filters by prefix for hierarchical listing.
Performance: O(n) where n is total number of keys
func (*ConfigWriter) Reset ¶ added in v1.0.3
func (w *ConfigWriter) Reset() error
Reset discards all changes and reverts to the last saved state. Loads the configuration from the original file to restore its state. Useful for canceling operations or handling errors.
Performance: I/O bound, reads and parses original file
func (*ConfigWriter) SetValue ¶ added in v1.0.3
func (w *ConfigWriter) SetValue(key string, value interface{}) error
SetValue sets a configuration value using dot notation. Supports nested keys like "database.connection.host".
Performance: 127 ns/op, 0 allocs for simple keys
295 ns/op, 1 alloc for nested keys (map creation)
Examples:
writer.SetValue("port", 8080) // Simple key
writer.SetValue("database.host", "localhost") // Nested key
writer.SetValue("features.auth.enabled", true) // Deep nesting
func (*ConfigWriter) WriteConfig ¶ added in v1.0.3
func (w *ConfigWriter) WriteConfig() error
WriteConfig atomically writes the current configuration to disk. Uses temporary file + rename for atomic operation to prevent corruption.
Performance: I/O bound, typically 2-5ms
Memory: 0 additional allocations for serialization
Atomicity guarantee: Either succeeds completely or leaves original unchanged
func (*ConfigWriter) WriteConfigAs ¶ added in v1.0.3
func (w *ConfigWriter) WriteConfigAs(filePath string) error
WriteConfigAs writes the configuration to a different file path. Useful for backups or exporting to different locations.
The original file path and watcher remain unchanged.
type EnvConfig ¶ added in v1.0.1
type EnvConfig struct {
// Core Configuration
PollInterval time.Duration `env:"ARGUS_POLL_INTERVAL"`
CacheTTL time.Duration `env:"ARGUS_CACHE_TTL"`
MaxWatchedFiles int `env:"ARGUS_MAX_WATCHED_FILES"`
// Performance Configuration
OptimizationStrategy string `env:"ARGUS_OPTIMIZATION_STRATEGY"`
BoreasLiteCapacity int64 `env:"ARGUS_BOREAS_CAPACITY"`
// Audit Configuration
AuditEnabled bool `env:"ARGUS_AUDIT_ENABLED"`
AuditOutputFile string `env:"ARGUS_AUDIT_OUTPUT_FILE"`
AuditMinLevel string `env:"ARGUS_AUDIT_MIN_LEVEL"`
AuditBufferSize int `env:"ARGUS_AUDIT_BUFFER_SIZE"`
AuditFlushInterval time.Duration `env:"ARGUS_AUDIT_FLUSH_INTERVAL"`
// Remote Configuration Sources
RemoteURL string `env:"ARGUS_REMOTE_URL"`
RemoteInterval time.Duration `env:"ARGUS_REMOTE_INTERVAL"`
RemoteTimeout time.Duration `env:"ARGUS_REMOTE_TIMEOUT"`
RemoteHeaders string `env:"ARGUS_REMOTE_HEADERS"` // JSON format
// Validation Configuration
ValidationEnabled bool `env:"ARGUS_VALIDATION_ENABLED"`
ValidationSchema string `env:"ARGUS_VALIDATION_SCHEMA"`
ValidationStrict bool `env:"ARGUS_VALIDATION_STRICT"`
}
EnvConfig represents configuration loaded from environment variables This provides environment variable support with automatic type detection
type ErrorHandler ¶
ErrorHandler is called when errors occur during file watching or parsing It receives the error and the file path where the error occurred
type FileChangeEvent ¶
type FileChangeEvent struct {
ModTime int64 // Unix nanoseconds (8 bytes, aligned first)
Size int64 // File size (8 bytes)
Path [110]byte // FULL POWER: 110 bytes for any file path (109 chars + null terminator)
PathLen uint8 // Actual path length (1 byte)
Flags uint8 // Create(1), Delete(2), Modify(4) bits (1 byte)
}
FileChangeEvent represents a file change optimized for minimal memory footprint 128 bytes (2 cache lines) for maximum path compatibility and performance
func ConvertChangeEventToFileEvent ¶
func ConvertChangeEventToFileEvent(event ChangeEvent) FileChangeEvent
ConvertChangeEventToFileEvent converts standard ChangeEvent to optimized FileChangeEvent. Used for interfacing between Argus's public API and BoreasLite's optimized internal format. Handles path truncation and flag conversion automatically.
type IdleStrategy ¶
type IdleStrategy interface {
// Wait is called between polling cycles when no changes are detected
Wait()
// Reset is called when file changes are detected to reset any backoff
Reset()
}
IdleStrategy defines how the watcher should behave when no file changes are detected. This allows for power management and CPU optimization. Currently serves as a design interface for future power management features.
type OptimizationStrategy ¶
type OptimizationStrategy int
OptimizationStrategy defines how BoreasLite should optimize performance
const ( // OptimizationAuto automatically chooses the best strategy based on file count // - 1-3 files: SingleEvent strategy (ultra-low latency) // - 4-20 files: SmallBatch strategy (balanced) // - 21+ files: LargeBatch strategy (high throughput) OptimizationAuto OptimizationStrategy = iota // OptimizationSingleEvent optimizes for 1-2 files with ultra-low latency // - Fast path for single events (24ns) // - Minimal batching overhead // - Aggressive spinning for immediate processing OptimizationSingleEvent // OptimizationSmallBatch optimizes for 3-20 files with balanced performance // - Small batch sizes (2-8 events) // - Moderate spinning with short sleeps // - Good balance between latency and throughput OptimizationSmallBatch // OptimizationLargeBatch optimizes for 20+ files with high throughput // - Large batch sizes (16-64 events) // - Zephyros-style 4x unrolling // - Focus on maximum throughput over latency OptimizationLargeBatch )
type RemoteConfig ¶ added in v1.0.3
type RemoteConfig struct {
// Enabled controls whether remote configuration loading is active
// Default: false (for backward compatibility)
// When false, all other RemoteConfig fields are ignored
Enabled bool `json:"enabled" yaml:"enabled" toml:"enabled"`
// PrimaryURL is the main remote configuration source
// Supports all registered remote providers (consul://, redis://, etcd://, http://, https://)
// Examples:
// - "consul://prod-consul:8500/config/myapp?datacenter=dc1"
// - "redis://prod-redis:6379/0/myapp:config"
// - "etcd://prod-etcd:2379/config/myapp"
// - "https://config-api.company.com/api/v1/config/myapp"
// Required when Enabled=true
PrimaryURL string `json:"primary_url" yaml:"primary_url" toml:"primary_url"`
// FallbackURL is an optional secondary remote configuration source
// Used when PrimaryURL fails but before falling back to local file
// Should typically be a different instance/datacenter of the same system
// Examples:
// - "consul://backup-consul:8500/config/myapp"
// - "redis://backup-redis:6379/0/myapp:config"
// Optional: can be empty to skip remote fallback
FallbackURL string `json:"fallback_url,omitempty" yaml:"fallback_url,omitempty" toml:"fallback_url,omitempty"`
// FallbackPath is a local file path used when all remote sources fail
// This provides the ultimate fallback for high-availability deployments
// The file should contain a valid configuration in JSON, YAML, or TOML format
// Examples:
// - "/etc/myapp/emergency-config.json"
// - "/opt/myapp/fallback-config.yaml"
// - "./config/local-fallback.toml"
// Recommended: Always configure for production deployments
FallbackPath string `json:"fallback_path,omitempty" yaml:"fallback_path,omitempty" toml:"fallback_path,omitempty"`
// SyncInterval controls how often to check for remote configuration updates
// This applies to all remote sources (primary and fallback)
// Shorter intervals provide faster updates but increase system load
// Default: 30 seconds (good balance for most applications)
// Production considerations:
// - High-frequency apps: 10-15 seconds
// - Standard apps: 30-60 seconds
// - Batch jobs: 5+ minutes
SyncInterval time.Duration `json:"sync_interval" yaml:"sync_interval" toml:"sync_interval"`
// Timeout controls the maximum time to wait for each remote configuration request
// Applied to both primary and fallback URL requests
// Should be shorter than SyncInterval to allow for fallback attempts
// Default: 10 seconds (allows for network latency and processing)
// Production recommendations:
// - Local network: 5-10 seconds
// - Cross-datacenter: 10-20 seconds
// - Internet-based: 20-30 seconds
Timeout time.Duration `json:"timeout" yaml:"timeout" toml:"timeout"`
// MaxRetries controls retry attempts for failed remote requests
// Applied per URL (primary/fallback) before moving to next fallback level
// Default: 2 (total of 3 attempts: initial + 2 retries)
// Higher values increase reliability but also increase latency during failures
MaxRetries int `json:"max_retries" yaml:"max_retries" toml:"max_retries"`
// RetryDelay is the base delay between retry attempts
// Uses exponential backoff: attempt N waits RetryDelay * 2^N
// Default: 1 second (results in 1s, 2s, 4s... delays)
// Should be balanced with Timeout to ensure retries fit within timeout window
RetryDelay time.Duration `json:"retry_delay" yaml:"retry_delay" toml:"retry_delay"`
}
RemoteConfig defines distributed configuration management with automatic fallback. This struct enables enterprise-grade remote configuration loading with resilient fallback capabilities for production deployments where configuration comes from distributed systems (Consul, etcd, Redis) but local fallback is required.
The RemoteConfig system implements the following fallback sequence: 1. Attempt to load from PrimaryURL (e.g., consul://prod-consul/myapp/config) 2. On failure, attempt FallbackURL if configured (e.g., consul://backup-consul/myapp/config) 3. On complete remote failure, load from FallbackPath (e.g., /etc/myapp/fallback-config.json) 4. Continue with SyncInterval for automatic recovery when remote systems recover
Zero-allocation design: All URLs and paths are pre-parsed and cached during initialization to avoid allocations during runtime operations.
Production deployment patterns:
// Consul with local fallback (recommended)
Remote: RemoteConfig{
Enabled: true,
PrimaryURL: "consul://prod-consul:8500/config/myapp",
FallbackPath: "/etc/myapp/config.json",
SyncInterval: 30 * time.Second,
Timeout: 10 * time.Second,
}
// Multi-datacenter setup with remote fallback
Remote: RemoteConfig{
Enabled: true,
PrimaryURL: "consul://dc1-consul:8500/config/myapp",
FallbackURL: "consul://dc2-consul:8500/config/myapp",
FallbackPath: "/etc/myapp/emergency-config.json",
SyncInterval: 60 * time.Second,
}
// Redis with backup Redis
Remote: RemoteConfig{
Enabled: true,
PrimaryURL: "redis://prod-redis:6379/0/myapp:config",
FallbackURL: "redis://backup-redis:6379/0/myapp:config",
SyncInterval: 15 * time.Second,
}
Thread safety: RemoteConfig operations are thread-safe and can be called concurrently from multiple goroutines without external synchronization.
Error handling: Failed remote loads automatically trigger fallback sequence. Applications receive the most recent successful configuration and error notifications through the standard ErrorHandler mechanism.
Monitoring integration: All remote configuration operations generate audit events for monitoring, alerting, and compliance tracking in production environments.
type RemoteConfigManager ¶ added in v1.0.3
type RemoteConfigManager struct {
// contains filtered or unexported fields
}
RemoteConfigManager manages remote configuration loading with automatic fallback. This struct encapsulates all remote configuration state and provides thread-safe operations for loading, watching, and fallback management.
Zero-allocation design: Pre-allocates all necessary structures and reuses contexts, channels, and error objects to minimize heap pressure during operations.
Thread safety: All methods are safe for concurrent use and employ atomic operations for state management to avoid lock contention in hot paths.
func NewRemoteConfigManager ¶ added in v1.0.3
func NewRemoteConfigManager(config *RemoteConfig, watcher *Watcher) (*RemoteConfigManager, error)
NewRemoteConfigManager creates a new remote configuration manager. This constructor validates the RemoteConfig settings and initializes all necessary state for zero-allocation operation.
Parameters:
- config: RemoteConfig settings with URLs, timeouts, and fallback paths
- watcher: Parent Watcher for error handling and audit integration
Returns:
- *RemoteConfigManager: Configured manager ready for Start()
- error: Configuration validation errors
func (*RemoteConfigManager) GetCurrentConfig ¶ added in v1.0.3
func (r *RemoteConfigManager) GetCurrentConfig() (map[string]interface{}, time.Time, error)
GetCurrentConfig returns the most recently loaded configuration. This method provides lock-free access to the current configuration cache using atomic pointer operations for maximum performance.
Returns:
- map[string]interface{}: Current configuration (may be nil if not yet loaded)
- time.Time: Timestamp of last successful configuration load
- error: ErrCodeConfigNotFound if no configuration has been loaded
func (*RemoteConfigManager) Start ¶ added in v1.0.3
func (r *RemoteConfigManager) Start() error
Start begins remote configuration synchronization. This method starts a background goroutine that periodically loads configuration from remote sources according to the SyncInterval setting.
The method performs an immediate initial load to populate the configuration cache before starting the periodic sync loop. If the initial load fails across all fallback sources, an error is returned but the sync loop continues for recovery.
Zero-allocation sync loop: The background goroutine reuses contexts, timers, and error objects to minimize garbage collection pressure.
Returns:
- error: Initial configuration load errors (sync continues in background)
func (*RemoteConfigManager) Stop ¶ added in v1.0.3
func (r *RemoteConfigManager) Stop()
Stop terminates remote configuration synchronization. This method gracefully stops the background sync loop and cleans up resources.
The method blocks until the sync loop has fully terminated to ensure clean shutdown and prevent resource leaks.
Thread safety: Safe to call multiple times and from multiple goroutines.
type RemoteConfigOptions ¶ added in v1.0.1
type RemoteConfigOptions struct {
// Timeout for remote operations
Timeout time.Duration
// RetryAttempts for failed requests
RetryAttempts int
// RetryDelay between retry attempts
RetryDelay time.Duration
// Watch enables automatic configuration reloading
Watch bool
// WatchInterval for polling-based providers (fallback if native watching not supported)
WatchInterval time.Duration
// Headers for HTTP-based providers
Headers map[string]string
// TLSConfig for secure connections (provider-specific)
TLSConfig map[string]interface{}
// Authentication credentials (provider-specific)
Auth map[string]interface{}
}
RemoteConfigOptions provides options for remote configuration loading. Controls timeouts, retries, authentication, and watching behavior. Use DefaultRemoteConfigOptions() for sensible defaults.
func DefaultRemoteConfigOptions ¶ added in v1.0.1
func DefaultRemoteConfigOptions() *RemoteConfigOptions
DefaultRemoteConfigOptions provides sensible defaults for remote configuration. Returns a new options instance with production-ready timeout and retry settings.
type RemoteConfigProvider ¶ added in v1.0.1
type RemoteConfigProvider interface {
// Name returns a human-readable name for this provider (for debugging)
Name() string
// Scheme returns the URL scheme this provider handles (e.g., "redis", "consul", "etcd", "http", "https")
Scheme() string
// Load loads configuration from the remote source
// The URL contains the full connection information
Load(ctx context.Context, configURL string) (map[string]interface{}, error)
// Watch starts watching for configuration changes (optional)
// Returns a channel that sends new configurations when they change
// If the provider doesn't support watching, it should return nil, nil
Watch(ctx context.Context, configURL string) (<-chan map[string]interface{}, error)
// Validate validates that the provider can handle the given URL
Validate(configURL string) error
// HealthCheck performs a health check on the remote source
HealthCheck(ctx context.Context, configURL string) error
}
RemoteConfigProvider defines the interface for remote configuration sources. Implementations provide access to distributed configuration systems like Redis, Consul, etcd, or HTTP APIs. Providers are registered globally and selected automatically based on URL scheme.
Example implementations:
- Redis: redis://localhost:6379/config
- Consul: consul://localhost:8500/config/myapp
- etcd: etcd://localhost:2379/config/myapp
- HTTP: https://config.mycompany.com/api/config
func GetRemoteProvider ¶ added in v1.0.1
func GetRemoteProvider(scheme string) (RemoteConfigProvider, error)
GetRemoteProvider returns the provider for the given URL scheme. Used internally to find the appropriate provider for a remote config URL.
func ListRemoteProviders ¶ added in v1.0.1
func ListRemoteProviders() []RemoteConfigProvider
ListRemoteProviders returns a list of all registered remote providers. Returns a copy to prevent external modification of the provider registry. Useful for debugging and discovering available remote configuration sources.
type SleepStrategy ¶
type SleepStrategy struct{}
SleepStrategy implements IdleStrategy using simple sleep-based waiting. This is the default strategy that relies on polling intervals for timing.
func NewSleepStrategy ¶
func NewSleepStrategy() *SleepStrategy
NewSleepStrategy creates a new sleep-based idle strategy
func (*SleepStrategy) Reset ¶
func (s *SleepStrategy) Reset()
Reset implements IdleStrategy by doing nothing
func (*SleepStrategy) Wait ¶
func (s *SleepStrategy) Wait()
Wait implements IdleStrategy by doing nothing (polling interval handles timing)
type UpdateCallback ¶
type UpdateCallback func(event ChangeEvent)
UpdateCallback is called when a watched file changes
type ValidationResult ¶ added in v1.0.1
type ValidationResult struct {
Valid bool `json:"valid"`
Errors []string `json:"errors,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
ValidationResult contains the result of configuration validation with detailed feedback. Provides comprehensive validation information including errors, warnings, and performance recommendations for production deployments.
func (ValidationResult) String ¶ added in v1.0.1
func (vr ValidationResult) String() string
String returns a human-readable representation of validation results
type Watcher ¶
type Watcher struct {
// contains filtered or unexported fields
}
Watcher monitors configuration files for changes ULTRA-OPTIMIZED: Uses BoreasLite MPSC ring buffer + lock-free cache for maximum performance
func GenericConfigWatcher ¶
func GenericConfigWatcher(configPath string, callback func(config map[string]interface{})) (*Watcher, error)
GenericConfigWatcher creates a watcher for JSON configuration (backward compatibility). DEPRECATED: Use UniversalConfigWatcher for better format support and future-proofing. This function is maintained for existing codebases but new code should use UniversalConfigWatcher.
func SimpleFileWatcher ¶
SimpleFileWatcher creates a basic file watcher with minimal configuration. Useful for simple use cases where you just want to know when a file changes, without the complexity of configuration parsing or format detection.
Parameters:
- filePath: Path to file to watch
- callback: Function called with file path when changes occur
Returns:
- *Watcher: Configured watcher (not automatically started)
- error: Any initialization errors
func UniversalConfigWatcher ¶
func UniversalConfigWatcher(configPath string, callback func(config map[string]interface{})) (*Watcher, error)
UniversalConfigWatcher creates a watcher for ANY configuration format Supports JSON, YAML, TOML, HCL, INI, XML, Properties
Example:
watcher, err := argus.UniversalConfigWatcher("config.yml", func(config map[string]interface{}) {
if level, ok := config["level"].(string); ok {
// Handle level change
}
if port, ok := config["port"].(int); ok {
// Handle port change
}
})
func UniversalConfigWatcherWithConfig ¶
func UniversalConfigWatcherWithConfig(configPath string, callback func(config map[string]interface{}), config Config) (*Watcher, error)
UniversalConfigWatcherWithConfig creates a watcher for ANY configuration format with custom config. Provides fine-grained control over watcher behavior while maintaining universal format support.
Parameters:
- configPath: Path to configuration file (format auto-detected from extension)
- callback: Function called when configuration changes
- config: Custom Argus configuration for performance tuning
Returns:
- *Watcher: Configured and started watcher
- error: Any initialization or file access errors
func (*Watcher) ClearCache ¶
func (w *Watcher) ClearCache()
ClearCache forces clearing of the stat cache (no pool cleanup needed) Useful for testing or when you want to force fresh stat calls
func (*Watcher) Close ¶
Close is an alias for Stop() for better resource management patterns Implements the common Close() interface for easy integration with defer statements
func (*Watcher) GetCacheStats ¶
func (w *Watcher) GetCacheStats() CacheStats
GetCacheStats returns current cache statistics using timecache for performance
func (*Watcher) GetWriter ¶ added in v1.0.3
func (w *Watcher) GetWriter(filePath string, format ConfigFormat, initialConfig map[string]interface{}) (*ConfigWriter, error)
GetWriter creates a ConfigWriter for the specified file. The writer enables programmatic configuration modifications with atomic operations.
Performance: ~500 ns/op, zero allocations for writer creation
func (*Watcher) GracefulShutdown ¶ added in v1.0.3
GracefulShutdown performs a graceful shutdown with timeout control. This method provides production-grade shutdown capabilities with deterministic timeout handling, ensuring all resources are properly cleaned up without hanging indefinitely.
The method performs the following shutdown sequence: 1. Signals shutdown intent to all goroutines via context cancellation 2. Waits for all file polling operations to complete 3. Flushes all pending audit events to persistent storage 4. Closes BoreasLite ring buffer and releases memory 5. Cleans up file descriptors and other system resources
Zero-allocation design: Uses pre-allocated channels and avoids heap allocations during the shutdown process to maintain performance characteristics even during termination.
Example usage:
watcher := argus.New(config) defer watcher.GracefulShutdown(30 * time.Second) // 30s timeout for Kubernetes // Kubernetes deployment watcher := argus.New(config) defer watcher.GracefulShutdown(time.Duration(terminationGracePeriodSeconds) * time.Second) // CI/CD pipelines watcher := argus.New(config) defer watcher.GracefulShutdown(10 * time.Second) // Fast shutdown for tests
Parameters:
- timeout: Maximum time to wait for graceful shutdown. If exceeded, the method returns an error but resources are still cleaned up in the background.
Returns:
- nil if shutdown completed within timeout
- ErrCodeWatcherStopped if watcher was already stopped
- ErrCodeWatcherBusy if shutdown timeout was exceeded (resources still cleaned up)
Thread-safety: Safe to call from multiple goroutines. First caller wins, subsequent calls return immediately with appropriate status.
Production considerations:
- Kubernetes: Use terminationGracePeriodSeconds - 5s to allow for signal propagation
- Docker: Typically 10-30 seconds is sufficient
- CI/CD: Use shorter timeouts (5-10s) for faster test cycles
- Load balancers: Ensure timeout exceeds health check intervals
func (*Watcher) Watch ¶
func (w *Watcher) Watch(path string, callback UpdateCallback) error
Watch adds a file to the watch list
func (*Watcher) WatchedFiles ¶
WatchedFiles returns the number of currently watched files
