Argus API Reference
May 2, 2026 · View on GitHub
Quick Navigation: Core Types | ConfigWriter | ConfigBinder | Parsers | Error Codes | Utils
Table of Contents
Core Types
- Watcher - Main file watching functionality
- Config - Core configuration options
- RemoteConfig - Remote configuration management
- ChangeEvent - File change event structure
- OptimizationStrategy - Performance tuning options
ConfigWriter System
- ConfigWriter - Atomic configuration file operations
- Constructor Functions - Creating writers
- CRUD Methods - Get, Set, Delete, List operations
- File Operations - Write, backup, format conversion
Configuration Binding System
- ConfigBinder - Ultra-fast configuration binding
- Binding Methods - Struct binding operations
- Advanced Binding - Complex data types
Configuration File Parsing
- Supported Formats - JSON, YAML, TOML, HCL, INI, Properties
- ConfigParser Interface - Custom parser implementation
- Format Detection - Automatic format recognition
Error Handling
- Error Codes - Complete error code reference
- Error Types - Categorized error handling
Advanced Features
- Audit System - Enterprise audit trails
- Remote Configuration - Distributed configuration
- Plugin System - Extensibility features
Performance & Best Practices
- Performance Characteristics - Benchmarks and optimization
- Best Practices - Production usage patterns
- Thread Safety - Concurrency considerations
Utilities
- Global Utility Functions - Helper functions and utilities
Core Types
Watcher
The main watcher instance that monitors files for changes.
type Watcher struct {
// Internal fields not exposed
}
Constructor
New(config Config) *Watcher
Creates a new Argus watcher instance with the specified configuration.
Parameters:
config Config: Configuration options for the watcher
Returns: *Watcher - New watcher instance
Example:
config := argus.Config{
PollInterval: 2 * time.Second,
OptimizationStrategy: argus.OptimizationSingleEvent,
}
watcher := argus.New(*config.WithDefaults())
Methods
Watch(filePath string, callback UpdateCallback) error
Adds a file to the watch list with a callback function that executes when the file changes.
Parameters:
filePath string: Absolute or relative path to the file to watchcallback UpdateCallback: Function called when file changes
Returns: error - Error if file cannot be watched
Example:
err := watcher.Watch("/etc/myapp/config.json", func(event argus.ChangeEvent) {
if event.IsModify {
reloadConfig(event.Path)
}
})
Unwatch(filePath string) error
Removes a file from the watch list.
Parameters:
filePath string: Path of the file to stop watching
Returns: error - Error if file was not being watched
Start() error
Starts the file watching process in a background goroutine.
Returns: error - Error if watcher is already running
Stop() error
Stops the file watching process and cleans up resources.
Returns: error - Error if watcher was not running
GracefulShutdown(timeout time.Duration) error
Performs a graceful shutdown with timeout control. Enterprise feature for production deployments requiring controlled shutdown behavior.
Parameters:
timeout time.Duration: Maximum time to wait for graceful shutdown
Returns: error - Error if shutdown times out or watcher was not running
Example:
// Graceful shutdown with 30 second timeout (Kubernetes)
err := watcher.GracefulShutdown(30 * time.Second)
if err != nil {
log.Printf("Graceful shutdown failed: %v", err)
}
Use Cases:
- Kubernetes pod termination handling
- Docker container shutdown hooks
- Production service graceful restarts
- Integration testing cleanup
IsRunning() bool
Returns whether the watcher is currently active.
Returns: bool - True if watcher is running
GetStats() Stats
Returns performance and operational statistics.
Returns: Stats - Current watcher statistics
WatchedFiles() int
Returns the number of currently watched files.
Returns: int - Number of files currently being watched
GetWriter(filePath string, format ConfigFormat, initialConfig map[string]interface{}) (*ConfigWriter, error)
Creates a ConfigWriter for the specified file with atomic write operations.
Parameters:
filePath string: Path to the configuration fileformat ConfigFormat: Configuration format (JSON, YAML, etc.)initialConfig map[string]interface{}: Initial configuration data
Returns:
*ConfigWriter: New ConfigWriter instance for atomic operationserror: Error if writer creation fails
Performance: ~500 ns/op, zero allocations for writer creation
Example:
writer, err := watcher.GetWriter("config.json", argus.FormatJSON, initialConfig)
if err != nil {
log.Fatal(err)
}
writer.SetValue("port", 8080)
writer.WriteConfig()
ClearCache()
Forces clearing of the internal file stat cache.
Use Cases:
- Testing scenarios requiring fresh file stats
- Debugging cache-related issues
- Manual cache invalidation after external file changes
Performance: Zero allocations, immediate effect
GetCacheStats() CacheStats
Returns statistics about the internal cache for monitoring and debugging.
Returns: CacheStats - Current cache performance metrics
Example:
stats := watcher.GetCacheStats()
fmt.Printf("Cache entries: %d, oldest: %v\n", stats.Entries, stats.OldestAge)
Close() error
Alias for Stop() that implements the common Close() interface for better resource management patterns.
Returns: error - Error if watcher was not running
Example:
defer watcher.Close() // Can be used with defer for automatic cleanup
Config
Configuration structure for customizing watcher behavior.
type Config struct {
PollInterval time.Duration
CacheTTL time.Duration
MaxWatchedFiles int
Audit AuditConfig
ErrorHandler ErrorHandler
OptimizationStrategy OptimizationStrategy
BoreasLiteCapacity int64
Remote RemoteConfig
}
Fields
PollInterval time.Duration
How often to check for file changes.
- Default: 5 seconds
- Recommended: 1-10 seconds for config files
- Performance: Lower values increase CPU usage
CacheTTL time.Duration
How long to cache os.Stat() results to reduce syscalls.
- Default:
PollInterval / 2 - Constraint: Must be ≤
PollInterval - Performance: Longer TTL reduces I/O overhead
MaxWatchedFiles int
Maximum number of files that can be watched simultaneously.
- Default: 100
- Range: 1-1000 (practical limits)
OptimizationStrategy OptimizationStrategy
Strategy for optimizing performance based on workload.
- Default:
OptimizationAuto - Options: Auto, SingleEvent, SmallBatch, LargeBatch
BoreasLiteCapacity int64
Ring buffer size for event processing (must be power of 2).
- Default: Auto-calculated based on strategy
- Range: 64-4096
Remote RemoteConfig
Remote configuration with automatic fallback capabilities.
- Default: Disabled for backward compatibility
- Purpose: Distributed configuration management with resilient fallback
RemoteConfig
Remote configuration management with automatic fallback sequence.
type RemoteConfig struct {
Enabled bool
PrimaryURL string
FallbackURL string
LocalPath string
Timeout time.Duration
MaxRetries int
RetryDelay time.Duration
SyncInterval time.Duration
}
Fields
Enabled bool
Enables remote configuration loading with fallback sequence.
- Default:
false - Note: Must be explicitly enabled
PrimaryURL string
Primary remote configuration endpoint (Consul, etcd, HTTP API).
- Required: When
Enabledis true - Example:
"https://consul.internal:8500/v1/kv/app/config"
FallbackURL string
Secondary remote configuration endpoint for failover scenarios.
- Optional: Provides additional resilience
- Example:
"https://backup-consul.internal:8500/v1/kv/app/config"
LocalPath string
Local file path for last-resort fallback when remote endpoints fail.
- Optional: Final fallback in the sequence
- Example:
"/etc/myapp/config.json"
Timeout time.Duration
Maximum time to wait for remote configuration loading.
- Default:
10 * time.Second - Range: 1s-300s
MaxRetries int
Maximum retry attempts for failed remote requests.
- Default:
3 - Range: 0-10
RetryDelay time.Duration
Base delay for exponential backoff retry strategy.
- Default:
1 * time.Second - Pattern:
RetryDelay * 2^(attempt-1)
SyncInterval time.Duration
Interval for periodic remote configuration synchronization.
- Default:
5 * time.Minute - Range: 1m-24h
Methods
NewRemoteConfigWithFallback(primaryURL, fallbackURL, localPath string) *RemoteConfigManager
Creates a new RemoteConfig manager with automatic fallback sequence for.
Parameters:
primaryURL string: Primary remote configuration endpointfallbackURL string: Secondary endpoint (can be empty)localPath string: Local fallback file path (can be empty)
Returns: *RemoteConfigManager - Configured remote config manager
Example:
remoteManager := argus.NewRemoteConfigWithFallback(
"https://consul.internal:8500/v1/kv/app/config",
"https://backup-consul.internal:8500/v1/kv/app/config",
"/etc/myapp/fallback.json",
)
config := argus.Config{
Remote: remoteManager.Config(),
}
watcher := argus.New(config)
Fallback Sequence:
- Primary URL → Try primary remote endpoint
- Fallback URL → Try secondary remote endpoint
- Local Path → Load local configuration file
- Error → All sources failed
Methods
WithDefaults() *Config
Applies sensible defaults to configuration fields.
Returns: *Config - Configuration with defaults applied
Example:
config := argus.Config{
PollInterval: 3 * time.Second,
// Other fields will get defaults
}
finalConfig := config.WithDefaults()
ConfigWriter System
ConfigWriter
The ConfigWriter provides atomic configuration file operations with zero-allocation performance for programmatic configuration management.
type ConfigWriter struct {
// Internal fields - not exposed for thread safety
}
Constructor Functions
NewConfigWriter(filePath string, format ConfigFormat, initialConfig map[string]interface{}) (*ConfigWriter, error)
Creates a new ConfigWriter for atomic configuration file operations.
Parameters:
filePath string: Path to the configuration fileformat ConfigFormat: Configuration format (JSON, YAML, TOML, HCL, INI, Properties)initialConfig map[string]interface{}: Initial configuration data (can be nil)
Returns:
*ConfigWriter: New ConfigWriter instanceerror: Error if creation fails
Performance: ~500 ns/op, zero allocations for writer creation
Example:
writer, err := argus.NewConfigWriter("config.yaml", argus.FormatYAML, config)
if err != nil {
return err
}
NewConfigWriterWithAudit(filePath string, format ConfigFormat, initialConfig map[string]interface{}, auditLogger *AuditLogger) (*ConfigWriter, error)
Creates a new ConfigWriter with optional audit logging for compliance requirements.
Parameters:
filePath string: Path to configuration fileformat ConfigFormat: Configuration formatinitialConfig map[string]interface{}: Initial configuration (can be nil)auditLogger *AuditLogger: Optional audit logger (can be nil for performance)
Returns:
*ConfigWriter: New ConfigWriter with audit capabilityerror: Error if creation fails
Performance: ~500 ns/op when audit disabled, ~750 ns/op when enabled
Methods
SetValue(key string, value interface{}) error
Sets a configuration value using dot notation for nested keys.
Parameters:
key string: Configuration key in dot notation (e.g., "database.host")value interface{}: Value to set (any JSON-serializable type)
Returns: error - Error if key is invalid or operation fails
Performance: 127 ns/op, 0 allocs for simple keys; 295 ns/op, 1 alloc for nested keys
Examples:
writer.SetValue("port", 8080) // Simple key
writer.SetValue("database.host", "localhost") // Nested key
writer.SetValue("features.auth.enabled", true) // Deep nesting
GetValue(key string) interface{}
Retrieves a configuration value using dot notation.
Parameters:
key string: Configuration key in dot notation
Returns: interface{} - Value or nil if key doesn't exist
Performance: 89 ns/op, 0 allocs for simple lookups
Example:
host := writer.GetValue("database.host")
if host != nil {
fmt.Printf("Database host: %s\n", host.(string))
}
DeleteValue(key string) bool
Removes a configuration key using dot notation.
Parameters:
key string: Configuration key to remove
Returns: bool - True if key existed and was deleted
Performance: 156 ns/op, 0 allocs for simple keys
Examples:
deleted := writer.DeleteValue("old.setting") // Returns true if existed
writer.DeleteValue("features.beta.enabled") // Remove nested key
WriteConfig() error
Atomically writes the current configuration to disk using temporary file + rename.
Returns: error - Error if write operation fails
Performance: I/O bound, typically 2-5ms
Atomicity: Either succeeds completely or leaves original file unchanged
Example:
writer.SetValue("database.port", 5432)
if err := writer.WriteConfig(); err != nil {
log.Printf("Failed to write config: %v", err)
}
WriteConfigAs(filePath string) error
Writes the configuration to a different file path (useful for backups).
Parameters:
filePath string: Target file path for export
Returns: error - Error if write fails
Use Cases:
- Configuration backups
- Exporting to different locations
- Creating configuration templates
HasChanges() bool
Returns true if the configuration has unsaved changes.
Returns: bool - True if changes exist
Performance: O(1) using fast hash comparison
GetConfig() map[string]interface{}
Returns a deep copy of the current configuration.
Returns: map[string]interface{} - Deep copy of configuration
Performance: O(n) where n is config size
ListKeys(prefix string) []string
Returns all configuration keys in dot notation format, optionally filtered by prefix.
Parameters:
prefix string: Optional prefix filter (empty string returns all keys)
Returns: []string - List of keys matching the prefix
Performance: O(n) where n is total number of keys
Examples:
allKeys := writer.ListKeys("") // All keys
dbKeys := writer.ListKeys("database") // Only database.* keys
Reset() error
Discards all changes and reverts to the last saved state by reloading from file.
Returns: error - Error if reload fails (resets to empty config)
Performance: I/O bound, reads and parses original file
Use Cases:
- Canceling unsaved operations
- Error recovery
- Reverting to known good state
Configuration Binding System
ConfigBinder
Configuration binding system that eliminates reflection overhead while providing excellent developer experience.
type ConfigBinder struct {
// Internal fields - optimized for zero-allocation performance
}
Constructor Functions
BindFromConfig(config map[string]interface{}) *ConfigBinder
Creates a new ConfigBinder from a parsed configuration map. This is the main entry point for configuration binding.
Parameters:
config map[string]interface{}: Parsed configuration data
Returns: *ConfigBinder - New ConfigBinder instance
Example:
binder := argus.BindFromConfig(parsedConfig)
NewConfigBinder(config map[string]interface{}) *ConfigBinder
Creates a new high-performance configuration binder. Prefer using BindFromConfig() for better API consistency.
Parameters:
config map[string]interface{}: Configuration source
Returns: *ConfigBinder - New ConfigBinder instance
Binding Methods
BindString(target *string, key string, defaultValue ...string) *ConfigBinder
Binds a string configuration value with optional default.
Parameters:
target *string: Pointer to target variablekey string: Configuration key (supports dot notation)defaultValue ...string: Optional default value
Returns: *ConfigBinder - Self for method chaining
Example:
var dbHost string
binder.BindString(&dbHost, "database.host", "localhost")
BindInt(target *int, key string, defaultValue ...int) *ConfigBinder
Binds an integer configuration value with optional default.
Parameters:
target *int: Pointer to target variablekey string: Configuration key (supports dot notation)defaultValue ...int: Optional default value
Returns: *ConfigBinder - Self for method chaining
BindInt64(target *int64, key string, defaultValue ...int64) *ConfigBinder
Binds an int64 configuration value with optional default.
Parameters:
target *int64: Pointer to target variablekey string: Configuration keydefaultValue ...int64: Optional default value
Returns: *ConfigBinder - Self for method chaining
BindBool(target *bool, key string, defaultValue ...bool) *ConfigBinder
Binds a boolean configuration value with optional default.
Parameters:
target *bool: Pointer to target variablekey string: Configuration keydefaultValue ...bool: Optional default value
Returns: *ConfigBinder - Self for method chaining
BindFloat64(target *float64, key string, defaultValue ...float64) *ConfigBinder
Binds a float64 configuration value with optional default.
Parameters:
target *float64: Pointer to target variablekey string: Configuration keydefaultValue ...float64: Optional default value
Returns: *ConfigBinder - Self for method chaining
BindDuration(target *time.Duration, key string, defaultValue ...time.Duration) *ConfigBinder
Binds a time.Duration configuration value with optional default.
Parameters:
target *time.Duration: Pointer to target variablekey string: Configuration keydefaultValue ...time.Duration: Optional default value
Returns: *ConfigBinder - Self for method chaining
Example:
var timeout time.Duration
binder.BindDuration(&timeout, "database.timeout", 30*time.Second)
Apply() error
Executes all bindings in a single optimized pass with ultra-fast batch processing.
Returns: error - Error if any binding fails
Performance: 1,645,489 operations/second with single allocation per bind
Example:
var (
dbHost string
dbPort int
enableSSL bool
timeout time.Duration
)
err := argus.BindFromConfig(parsedConfig).
BindString(&dbHost, "database.host", "localhost").
BindInt(&dbPort, "database.port", 5432).
BindBool(&enableSSL, "database.ssl", true).
BindDuration(&timeout, "database.timeout", 30*time.Second).
Apply()
if err != nil {
log.Fatal(err)
}
// Variables are now populated and ready to use!
ChangeEvent
Represents a file change notification.
type ChangeEvent struct {
Path string
ModTime time.Time
Size int64
IsCreate bool
IsDelete bool
IsModify bool
}
Fields
Path string
Absolute path of the file that changed.
ModTime time.Time
New modification timestamp of the file.
Size int64
New size of the file in bytes.
IsCreate bool
True if the file was newly created.
IsDelete bool
True if the file was deleted.
IsModify bool
True if the file was modified (most common case).
OptimizationStrategy
Enumeration of performance optimization strategies.
type OptimizationStrategy int
Constants
OptimizationAuto
Automatically selects the best strategy based on file count:
- 1-3 files: SingleEvent strategy
- 4-20 files: SmallBatch strategy
- 21+ files: LargeBatch strategy
OptimizationSingleEvent
Optimized for 1-2 files with ultra-low latency:
- Performance: 24ns per operation
- Best for: Single config file scenarios
- Memory: 64-event ring buffer
OptimizationSmallBatch
Balanced optimization for 3-20 files:
- Performance: 28ns per operation
- Best for: Multi-config applications
- Memory: 128-event ring buffer
OptimizationLargeBatch
High throughput optimization for 20+ files:
- Performance: 35ns per operation
- Best for: Configuration management systems
- Memory: 256+ event ring buffer
UpdateCallback
Function type for handling file change notifications.
type UpdateCallback func(event ChangeEvent)
Parameters:
event ChangeEvent: Details about the file change
Example:
callback := func(event argus.ChangeEvent) {
switch {
case event.IsCreate:
fmt.Printf("File created: %s\n", event.Path)
case event.IsDelete:
fmt.Printf("File deleted: %s\n", event.Path)
case event.IsModify:
fmt.Printf("File modified: %s (size: %d)\n", event.Path, event.Size)
}
}
ErrorHandler
Function type for handling errors during file watching.
type ErrorHandler func(err error, filepath string)
Parameters:
err error: The error that occurredfilepath string: Path of the file where error occurred
Example:
errorHandler := func(err error, path string) {
log.Printf("Argus error for %s: %v", path, err)
metrics.Increment("argus.errors")
}
config := argus.Config{
ErrorHandler: errorHandler,
}
Stats
Performance and operational statistics.
type Stats struct {
FilesWatched int64
TotalPolls int64
TotalChanges int64
CacheHits int64
CacheMisses int64
LastPollDuration time.Duration
AverageLatency time.Duration
ErrorCount int64
}
Fields
FilesWatched int64
Current number of files being monitored.
TotalPolls int64
Total number of polling cycles completed.
TotalChanges int64
Total number of file changes detected.
CacheHits int64 / CacheMisses int64
Statistics for the internal os.Stat() cache.
LastPollDuration time.Duration
Duration of the most recent polling cycle.
AverageLatency time.Duration
Average time from file change detection to callback execution.
ErrorCount int64
Total number of errors encountered.
CacheStats
Statistics about the internal file stat cache for monitoring and debugging.
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
}
Fields
Entries int
Number of cached file stat entries currently in memory.
OldestAge time.Duration
Age of the oldest cache entry, indicating how long the oldest cached stat has been retained.
NewestAge time.Duration
Age of the newest cache entry, indicating how recently the cache was last updated.
Use Cases:
- Cache efficiency monitoring
- Memory usage optimization
- Performance debugging
- Cache hit ratio analysis
Error Codes
Argus uses structured error codes for better error handling:
ARGUS_INVALID_CONFIG: Invalid configuration providedARGUS_FILE_NOT_FOUND: Watched file does not existARGUS_WATCHER_STOPPED: Operation attempted on stopped watcherARGUS_WATCHER_BUSY: Watcher is already running
Configuration File Parsing
Argus includes universal configuration parsers for common formats:
ConfigFormat
Enumeration of supported configuration file formats for auto-detection and parsing.
type ConfigFormat int
const (
FormatJSON ConfigFormat = iota
FormatYAML
FormatTOML
FormatHCL
FormatINI
FormatProperties
FormatUnknown
)
Constants
FormatJSON
JSON format (.json files) - Full production support with zero dependencies.
FormatYAML
YAML format (.yml, .yaml files) - Full YAML 1.2 spec compliance via yaml.v3 (anchors, aliases, multiline scalars, flow styles, correct inline comment handling on all value types).
FormatTOML
TOML format (.toml files) - Built-in parser + plugin support for full specification compliance.
FormatHCL
HashiCorp Configuration Language (.hcl, .tf files) - Built-in parser + plugin support.
FormatINI
INI/Configuration format (.ini, .conf, .cfg files) - Built-in parser with section support.
FormatProperties
Java Properties format (.properties files) - Built-in parser with dot notation flattening.
FormatUnknown
Unknown or unsupported format - returned by DetectFormat() when format cannot be determined.
Supported Formats
- JSON (.json): Full production support
- YAML (.yml, .yaml): Full YAML 1.2 spec compliance via yaml.v3
- TOML (.toml): Built-in + plugin support
- HCL (.hcl, .tf): Built-in + plugin support
- INI (.ini, .conf, .cfg): Built-in + plugin support
- Properties (.properties): Built-in + plugin support
ConfigParser Interface
Interface for pluggable configuration parsers that enable production-grade parsing with full specification compliance.
type ConfigParser interface {
Parse(data []byte) (map[string]interface{}, error)
Supports(format ConfigFormat) bool
Name() string
}
Methods
Parse(data []byte) (map[string]interface{}, error)
Parses configuration data for supported formats.
Parameters:
data []byte: Raw configuration file data
Returns:
map[string]interface{}: Parsed configuration dataerror: Parse error if data is invalid
Supports(format ConfigFormat) bool
Returns true if this parser can handle the given format.
Parameters:
format ConfigFormat: Configuration format to check
Returns: bool - True if parser supports the format
Name() string
Returns a human-readable name for this parser for debugging and logging.
Returns: string - Parser name (e.g., "Advanced YAML Parser v2.1")
Parser Registration
Custom parsers are tried before built-in parsers, allowing for full specification compliance or advanced features not available in built-in parsers.
Import-based Registration (Recommended):
import _ "github.com/your-org/argus-yaml-pro" // Auto-registers in init()
import _ "github.com/your-org/argus-toml-pro" // Auto-registers in init()
Manual Registration:
argus.RegisterParser(&MyAdvancedYAMLParser{})
Build Tags (Advanced):
go build -tags "yaml_pro,toml_pro" ./...
Using Parsers
// Register custom parser
argus.RegisterParser("json", &MyJSONParser{})
// Parse configuration in callback
watcher.Watch("config.json", func(event argus.ChangeEvent) {
if event.IsModify {
data, _ := os.ReadFile(event.Path)
config, err := argus.ParseConfig(event.Path, data)
if err == nil {
applyConfig(config)
}
}
})
Advanced Features
Audit and Compliance
Argus provides professional audit capabilities with unified SQLite backend for cross-application correlation.
AuditConfig
Configuration structure for the audit system:
type AuditConfig struct {
Enabled bool // Enable/disable audit logging
OutputFile string // Path to audit storage (empty = SQLite, .jsonl = JSONL)
MinLevel AuditLevel // Minimum audit level to log
BufferSize int // Number of events to buffer
FlushInterval time.Duration // How often to flush buffer
IncludeStack bool // Include stack traces (for debugging)
}
Backend Selection
Argus automatically selects the appropriate audit backend:
// Unified SQLite backend (recommended)
config := argus.Config{
Audit: argus.DefaultAuditConfig(), // Uses unified SQLite
}
// Or explicit SQLite configuration
config := argus.Config{
Audit: argus.AuditConfig{
Enabled: true,
OutputFile: "", // Empty = unified SQLite backend
MinLevel: argus.AuditCritical,
},
}
// Legacy JSONL backend (backward compatibility)
config := argus.Config{
Audit: argus.AuditConfig{
Enabled: true,
OutputFile: "/var/log/argus-audit.jsonl", // .jsonl = JSONL backend
MinLevel: argus.AuditInfo,
},
}
AuditLevel Constants
const (
AuditInfo AuditLevel = iota // File watch events, system status
AuditWarn // Performance warnings, parsing issues
AuditCritical // Configuration changes with before/after
AuditSecurity // Access violations, suspicious activity
)
See Audit System Documentation for comprehensive usage examples and best practices.
Performance Monitoring
Real-time performance metrics:
go func() {
ticker := time.NewTicker(30 * time.Second)
for range ticker.C {
stats := watcher.GetStats()
fmt.Printf("Files: %d, Changes: %d, Cache Hit Rate: %.2f%%\n",
stats.FilesWatched,
stats.TotalChanges,
float64(stats.CacheHits)/float64(stats.CacheHits+stats.CacheMisses)*100,
)
}
}()
Performance Characteristics
Overhead Analysis
Based on comprehensive benchmarking:
- Polling overhead: 12.11 nanoseconds per cycle
- Memory footprint: 8KB fixed + (64 bytes × files watched)
- HTTP request impact: +0.061ns per request (0.002%)
- System impact: 1.44µs every 5 seconds
Optimization Guidelines
- Single config file: Use
OptimizationSingleEvent - Few config files (3-20): Use
OptimizationSmallBatch - Many config files (20+): Use
OptimizationLargeBatch - Unknown workload: Use
OptimizationAuto(default)
Cache Tuning
config := argus.Config{
PollInterval: 5 * time.Second,
CacheTTL: 2 * time.Second, // 40% of poll interval
}
Best Practices
Configuration Management
// Centralized configuration reloading
type ConfigManager struct {
watcher *argus.Watcher
config atomic.Value
}
func (cm *ConfigManager) Start() error {
cm.watcher.Watch("config.json", func(event argus.ChangeEvent) {
if newConfig, err := LoadConfig(event.Path); err == nil {
cm.config.Store(newConfig)
}
})
return cm.watcher.Start()
}
func (cm *ConfigManager) GetConfig() *Config {
return cm.config.Load().(*Config)
}
Error Handling
config := argus.Config{
ErrorHandler: func(err error, path string) {
switch {
case errors.Is(err, os.ErrNotExist):
log.Printf("Config file removed: %s", path)
// Use default configuration
case errors.Is(err, os.ErrPermission):
log.Printf("Permission denied: %s", path)
// Alert operations team
default:
log.Printf("Unexpected error for %s: %v", path, err)
}
},
}
Graceful Shutdown
func main() {
watcher := argus.New(config)
// Handle shutdown signals
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
log.Println("Shutting down...")
watcher.Stop()
os.Exit(0)
}()
watcher.Start()
select {} // Keep running
}
Thread Safety
Argus is fully thread-safe and designed for concurrent use:
- Watch/Unwatch: Safe to call from multiple goroutines
- Callbacks: Executed sequentially to prevent race conditions
- Statistics: Atomic operations ensure consistent reads
- Configuration: Immutable after watcher creation
Global Utility Functions
Configuration Loading and Parsing
LoadConfigMultiSource(configFile string) (*Config, error)
Loads configuration with automatic precedence: Environment Variables > Configuration File > Defaults.
Parameters:
configFile string: Path to configuration file
Returns:
*Config: Loaded configuration with applied precedenceerror: Error if loading fails
Precedence Order:
- Environment variables (highest priority)
- Configuration file values
- Default values (lowest priority)
Example:
config, err := argus.LoadConfigMultiSource("config.yaml")
if err != nil {
log.Fatal(err)
}
watcher := argus.New(*config)
ParseConfig(data []byte, format ConfigFormat) (map[string]interface{}, error)
Parses configuration data in the specified format using built-in or registered parsers.
Parameters:
data []byte: Raw configuration dataformat ConfigFormat: Configuration format (JSON, YAML, TOML, etc.)
Returns:
map[string]interface{}: Parsed configuration dataerror: Parse error if format is invalid
Parser Priority:
- Custom registered parsers (tried first)
- Built-in parsers (fallback)
Example:
data, _ := os.ReadFile("config.json")
config, err := argus.ParseConfig(data, argus.FormatJSON)
if err != nil {
log.Fatal(err)
}
DetectFormat(filePath string) ConfigFormat
Automatically detects configuration format from file extension.
Parameters:
filePath string: Path to configuration file
Returns: ConfigFormat - Detected format or FormatUnknown
Supported Extensions:
.json→ FormatJSON.yml,.yaml→ FormatYAML.toml→ FormatTOML.hcl,.tf→ FormatHCL.ini,.conf,.cfg→ FormatINI.properties→ FormatProperties
Example:
format := argus.DetectFormat("config.yaml")
if format == argus.FormatUnknown {
log.Fatal("Unsupported file format")
}
RegisterParser(parser ConfigParser)
Registers a custom parser for production use cases requiring full specification compliance.
Parameters:
parser ConfigParser: Custom parser implementation
Use Cases:
- Full YAML specification compliance
- Advanced TOML features
- Custom configuration formats
- Enterprise parsing requirements
Example:
argus.RegisterParser(&MyAdvancedYAMLParser{})
Or via import-based registration:
import _ "github.com/your-org/argus-yaml-pro"
Universal Configuration Watchers
UniversalConfigWatcher(configPath string, callback func(config map[string]interface{})) (*Watcher, error)
Creates a watcher for ANY configuration format with automatic format detection and parsing.
Parameters:
configPath string: Path to configuration file (format auto-detected)callback func(config map[string]interface{}): Function called when configuration changes
Returns:
*Watcher: Configured and started watchererror: Initialization error
Features:
- Automatic format detection from file extension
- Built-in parsing for all supported formats
- Automatic watcher startup
- Initial configuration loading
Example:
watcher, err := argus.UniversalConfigWatcher("config.yml", func(config map[string]interface{}) {
if level, ok := config["level"].(string); ok {
log.Printf("Log level changed to: %s", level)
}
if port, ok := config["port"].(int); ok {
log.Printf("Port changed to: %d", port)
}
})
defer watcher.Stop()
UniversalConfigWatcherWithConfig(configPath string, callback func(config map[string]interface{}), config Config) (*Watcher, error)
Creates a universal configuration watcher with custom Argus configuration for performance tuning.
Parameters:
configPath string: Path to configuration filecallback func(config map[string]interface{}): Configuration change callbackconfig Config: Custom Argus configuration for performance tuning
Returns:
*Watcher: Configured and started watchererror: Initialization error
Example:
config := argus.Config{
PollInterval: 1 * time.Second,
OptimizationStrategy: argus.OptimizationSingleEvent,
}
watcher, err := argus.UniversalConfigWatcherWithConfig("config.json",
func(cfg map[string]interface{}) {
// Handle configuration changes
}, config)
SimpleFileWatcher(filePath string, callback func(path string)) (*Watcher, error)
Creates a basic file watcher without configuration parsing for simple use cases.
Parameters:
filePath string: Path to file to watchcallback func(path string): Function called with file path when changes occur
Returns:
*Watcher: Configured watcher (NOT automatically started)error: Setup error
Note: Unlike Universal watchers, SimpleFileWatcher does NOT auto-start. Call Start() manually.
Example:
watcher, err := argus.SimpleFileWatcher("/var/log/app.log", func(path string) {
log.Printf("Log file changed: %s", path)
})
if err != nil {
log.Fatal(err)
}
// Must start manually
watcher.Start()
defer watcher.Stop()
GenericConfigWatcher(configPath string, callback func(config map[string]interface{})) (*Watcher, error)
DEPRECATED: Use UniversalConfigWatcher for better format support and future-proofing.
This function is maintained for existing codebases but new code should use UniversalConfigWatcher.
Security Functions
ValidateSecurePath(path string) error
Validates that a file path is safe from path traversal attacks and security vulnerabilities.
Parameters:
path string: File path to validate
Returns: error - Error if path is unsafe
Security Protection:
- Directory traversal prevention (CWE-22)
- URL decoding attack detection
- System file protection
- Windows device name protection
- Symlink traversal validation
- Path length and complexity limits
Example:
if err := argus.ValidateSecurePath(userProvidedPath); err != nil {
return fmt.Errorf("unsafe path: %w", err)
}
Critical: Call this function on ALL user-provided paths before file operations.
Remote Configuration
NewRemoteConfigWithFallback(primaryURL, fallbackURL, localPath string) *RemoteConfigManager
Creates a new RemoteConfigManager with automatic fallback sequence for enterprise deployments.
Parameters:
primaryURL string: Primary remote configuration endpoint (required)fallbackURL string: Secondary endpoint for failover (optional, can be empty)localPath string: Local fallback file path (optional, can be empty)
Returns: *RemoteConfigManager - Configured remote config manager
Fallback Sequence:
- Primary URL → Try primary remote endpoint
- Fallback URL → Try secondary remote endpoint (if provided)
- Local Path → Load local configuration file (if provided)
- Error → All sources failed
Example:
// Full enterprise setup with all fallback layers
remoteManager := argus.NewRemoteConfigWithFallback(
"https://consul.prod:8500/v1/kv/app/config",
"https://consul.backup:8500/v1/kv/app/config",
"/etc/myapp/fallback.json",
)
// Use with watcher
watcher := argus.New(argus.Config{
Remote: remoteManager.Config(),
})
Argus • an AGILira fragment