argus

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2025 License: MPL-2.0 Imports: 15 Imported by: 2

README

Argus: Dynamic Configuration Framework for Go

an AGILira fragment

Argus is a high-performance, OS-independent dynamic configuration framework for Go, engineered for applications that demand real-time configuration updates, universal format support, and production-grade reliability without service restarts.

Security Go Report Card Test Coverage Xantos Powered

Architecture

Argus provides intelligent configuration management through polling-based optimization and universal format support:

Core Framework
  • Universal Format Support: JSON, YAML, TOML, HCL, INI, Properties with auto-detection
  • Polling Optimization: Four strategies (SingleEvent, SmallBatch, LargeBatch, Auto)
  • Zero Allocations: Pre-allocated buffers eliminate GC pressure in hot paths
  • Audit System: Tamper-resistant logging with sub-microsecond performance impact
  • Performance: 12.11ns polling overhead with intelligent caching strategies
  • Massive scalability - monitor hundreds to thousands of files simultaneously
Configuration Flow Architecture:

[Config Files] ──► [Format Detection] ──► [Universal Parser] ──┐
    │                                                          │
    ▼                                                          ▼
[File Monitor] ──► [BoreasLite Buffer] ──► [Optimization] ──► [Business Logic]
    │                      │                     │
    ▼                      ▼                     ▼
[Audit Trail] ──► [Tamper Detection] ──► [Compliance Logging]

- Zero-allocation monitoring with 12.11ns overhead
- Universal parsing eliminates format lock-in
- Audit system provides forensic-quality trails

Performance

Argus is engineered for production configuration management. The following benchmarks demonstrate sustained monitoring with minimal overhead and intelligent optimization.

Performance Characteristics
Configuration Monitoring Overhead:    12.11 ns/op     (99.998% efficiency)
Universal Parser Detection:           ~100 ns/op      (format auto-detection)
Audit System Impact:                  <0.5 μs/op      (121x faster than time.Now())
Memory Footprint:                     8KB fixed       + configurable buffers
File Count Scalability:               1-1000+ files   (auto-optimization)

Key Features:

  • 12.11ns polling overhead with intelligent caching
  • Sub-microsecond audit with tamper detection
  • Universal format support with zero configuration
  • Adaptive optimization based on workload patterns
  • Production-grade reliability with comprehensive error handling
Configuration Parser Support

Argus includes built-in parsers optimized for the 80% use case with line-based parsing for rapid deployment:

Fully Supported Formats:

  • JSON - Complete RFC 7159 compliance
  • Properties - Java-style key=value parsing
  • INI - Section-based configuration files

Simplified Parsers (80% Use Case):

  • YAML - Line-based parser for simple key-value configurations
  • TOML - Basic parsing for standard use cases
  • HCL - HashiCorp Configuration Language essentials

For Spec Compliance: Complex YAML/TOML/HCL configurations should use plugin parsers. Register custom parsers with argus.RegisterParser() for full specification compliance. See docs/PARSERS.md for parser plugin development.

Installation

go get github.com/agilira/argus

Quick Start

import "github.com/agilira/iris/argus"

// Watch any configuration format - auto-detected
watcher, err := argus.UniversalConfigWatcher("config.yaml", 
    func(config map[string]interface{}) {
        fmt.Printf("Config updated: %+v\n", config)
    })

watcher.Start()
defer watcher.Stop()

📖 Complete Quick Start Guide → - Get running in 2 minutes with detailed examples


## Core Features

### Universal Format Support
- **Auto-Detection**: Format determined by file extension and content analysis
- **Six Formats**: JSON, YAML, TOML, HCL (.hcl, .tf), INI, Properties
- **Zero Configuration**: Works out-of-the-box with any supported format

### Optimization Strategies
- **OptimizationAuto**: Adaptive strategy selection based on file count
- **OptimizationSingleEvent**: Ultra-low latency for single file (24ns processing)
- **OptimizationSmallBatch**: Balanced performance for 3-20 files
- **OptimizationLargeBatch**: High throughput for 20+ files with 4x unrolling

### Audit System
- **Tamper Detection**: Cryptographic checksums on every audit entry
- **Compliance Ready**: SOX, PCI-DSS, GDPR compatible logging
- **Sub-Microsecond Impact**: Cached timestamps for minimal overhead

📖 **[Full API Reference →](./docs/API.md)** - Complete API documentation with all types and methods

## Use Cases

- **Microservices Configuration**: Real-time config updates without service restarts
- **Feature Flag Management**: Dynamic feature enabling/disabling  
- **Database Connection Management**: Hot-swapping connection parameters
- **Kubernetes ConfigMaps**: Automatic detection of mounted ConfigMap changes
- **Security Policy Updates**: Real-time security configuration enforcement

## The Philosophy Behind Argus

In Greek mythology, Argus Panoptes was the all-seeing giant with a hundred eyes, known for his unwavering vigilance and ability to watch over everything simultaneously. Unlike reactive systems that miss changes, Argus maintained constant awareness while remaining efficient and unobtrusive.

This embodies Argus' design philosophy: intelligent vigilance over configuration changes through universal format support and adaptive optimization. The framework provides comprehensive visibility into configuration state while adapting its monitoring strategy to current conditions. The audit system ensures complete accountability without sacrificing performance.

Argus doesn't just watch files—it understands configuration, adapting to your application's needs while maintaining the reliability and transparency that production systems demand.

## Security & Quality Assurance

Argus maintains enterprise-grade security standards with comprehensive automated validation:

### Security Verification
```bash
# Run security analysis with gosec
./scripts/security-check.sh

# Manual security scan
gosec --exclude=G104,G306,G301 ./...
Audit System Configuration

Argus includes enterprise-grade audit logging with SHA-256 tamper detection:

// Default audit configuration (Linux-optimized)
config := argus.DefaultAuditConfig()
// Default path: /var/log/argus/audit.jsonl

// Cross-platform configuration
config := argus.AuditConfig{
    Enabled:    true,
    OutputFile: filepath.Join(os.TempDir(), "argus-audit.jsonl"), // Portable
    MinLevel:   argus.AuditInfo,
}

Platform Notes: Default audit path /var/log/argus/audit.jsonl assumes Linux/Unix. For Windows or restricted environments, customize OutputFile to writable location. Ensure proper directory permissions and log rotation for production deployments.

Quality Tools Integration
  • gosec: Static security analysis (0 issues)
  • go vet: Static analysis validation
  • staticcheck: Advanced static analysis
  • revive: Code quality linting
  • go test -race: Race condition detection
  • 93% test coverage: Comprehensive test suite (0 functions at 0%)
  • gocyclo: Cyclomatic complexity 4.24 avg (A+ grade)
  • go fmt: Perfect code formatting

🏆 Go Report Card Grade: A+

All critical security issues have been resolved with appropriate #nosec annotations for justified cases (demo files, bounded conversions).

Documentation

Quick Links:

License

Argus is licensed under the Mozilla Public License 2.0.


Argus • an AGILira fragment

Documentation

Index

Constants

View Source
const (
	ErrCodeInvalidConfig  = "ARGUS_INVALID_CONFIG"
	ErrCodeFileNotFound   = "ARGUS_FILE_NOT_FOUND"
	ErrCodeWatcherStopped = "ARGUS_WATCHER_STOPPED"
	ErrCodeWatcherBusy    = "ARGUS_WATCHER_BUSY"
)

Error codes for Argus operations

View Source
const (
	FileEventCreate uint8 = 1 << iota
	FileEventDelete
	FileEventModify
)

Event flags for file changes

Variables

This section is empty.

Functions

func ParseConfig

func ParseConfig(data []byte, format ConfigFormat) (map[string]interface{}, error)

ParseConfig parses configuration data based on the detected format HYPER-OPTIMIZED: Fast path for no custom parsers, reduced lock contention

func RegisterParser

func RegisterParser(parser ConfigParser)

RegisterParser registers a custom parser for production use Custom parsers are tried before built-in parsers

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

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

func NewAuditLogger

func NewAuditLogger(config AuditConfig) (*AuditLogger, error)

NewAuditLogger creates a new audit logger

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

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

func (*BoreasLite) Stop

func (b *BoreasLite) Stop()

Stop stops the processor (immediate, no graceful shutdown needed for file watching)

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

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

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 ChangeEvent

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
}

Config configures the Argus watcher behavior

func (*Config) WithDefaults

func (c *Config) WithDefaults() *Config

WithDefaults applies sensible defaults to the configuration

type ConfigFormat

type ConfigFormat int

ConfigFormat represents supported configuration file formats

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

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:

  1. 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

  2. MANUAL REGISTRATION: Users manually register parsers in their main():

    argus.RegisterParser(&MyAdvancedYAMLParser{})

  3. 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 ErrorHandler

type ErrorHandler func(err error, filepath string)

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 {
	Path    [110]byte // FULL POWER: 110 bytes for any file path (109 chars + null terminator)
	PathLen uint8     // Actual path length
	ModTime int64     // Unix nanoseconds
	Size    int64     // File size
	Flags   uint8     // Create(1), Delete(2), Modify(4) bits
	// contains filtered or unexported fields
}

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 FileChangeEvent

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.

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 SleepStrategy

type SleepStrategy struct{}

SleepStrategy implements IdleStrategy using simple sleep

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 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

func New

func New(config Config) *Watcher

New creates a new Argus file watcher with BoreasLite integration

func SimpleFileWatcher

func SimpleFileWatcher(filePath string, callback func(path string)) (*Watcher, error)

SimpleFileWatcher creates a basic file watcher with minimal configuration Useful for simple use cases where you just want to know when a file changes

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

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

func (w *Watcher) Close() error

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) IsRunning

func (w *Watcher) IsRunning() bool

IsRunning returns true if the watcher is currently running

func (*Watcher) Start

func (w *Watcher) Start() error

Start begins watching files for changes

func (*Watcher) Stop

func (w *Watcher) Stop() error

Stop stops the watcher and waits for cleanup

func (*Watcher) Unwatch

func (w *Watcher) Unwatch(path string) error

Unwatch removes a file from the watch list

func (*Watcher) Watch

func (w *Watcher) Watch(path string, callback UpdateCallback) error

Watch adds a file to the watch list

func (*Watcher) WatchedFiles

func (w *Watcher) WatchedFiles() int

WatchedFiles returns the number of currently watched files

Jump to

Keyboard shortcuts

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