v0.3.6 number types refactored to 64-bit matching config types, bundled config samples updated
This commit is contained in:
@ -20,31 +20,4 @@ type Config struct {
|
||||
// Existing fields
|
||||
Logging *LogConfig `toml:"logging"`
|
||||
Pipelines []PipelineConfig `toml:"pipelines"`
|
||||
}
|
||||
|
||||
// Helper functions to handle type conversions from any
|
||||
func toInt(v any) (int, bool) {
|
||||
switch val := v.(type) {
|
||||
case int:
|
||||
return val, true
|
||||
case int64:
|
||||
return int(val), true
|
||||
case float64:
|
||||
return int(val), true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
func toFloat(v any) (float64, bool) {
|
||||
switch val := v.(type) {
|
||||
case float64:
|
||||
return val, true
|
||||
case int:
|
||||
return float64(val), true
|
||||
case int64:
|
||||
return float64(val), true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
@ -40,7 +40,7 @@ func defaults() *Config {
|
||||
Options: map[string]any{
|
||||
"path": "./",
|
||||
"pattern": "*.log",
|
||||
"check_interval_ms": 100,
|
||||
"check_interval_ms": int64(100),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -48,13 +48,13 @@ func defaults() *Config {
|
||||
{
|
||||
Type: "http",
|
||||
Options: map[string]any{
|
||||
"port": 8080,
|
||||
"buffer_size": 1000,
|
||||
"port": int64(8080),
|
||||
"buffer_size": int64(1000),
|
||||
"stream_path": "/stream",
|
||||
"status_path": "/status",
|
||||
"heartbeat": map[string]any{
|
||||
"enabled": true,
|
||||
"interval_seconds": 30,
|
||||
"interval_seconds": int64(30),
|
||||
"include_timestamp": true,
|
||||
"include_stats": false,
|
||||
"format": "comment",
|
||||
|
||||
@ -86,7 +86,7 @@ func validateSource(pipelineName string, sourceIndex int, cfg *SourceConfig) err
|
||||
|
||||
// Validate check interval if provided
|
||||
if interval, ok := cfg.Options["check_interval_ms"]; ok {
|
||||
if intVal, ok := toInt(interval); ok {
|
||||
if intVal, ok := interval.(int64); ok {
|
||||
if intVal < 10 {
|
||||
return fmt.Errorf("pipeline '%s' source[%d]: check interval too small: %d ms (min: 10ms)",
|
||||
pipelineName, sourceIndex, intVal)
|
||||
@ -102,7 +102,7 @@ func validateSource(pipelineName string, sourceIndex int, cfg *SourceConfig) err
|
||||
|
||||
case "http":
|
||||
// Validate HTTP source options
|
||||
port, ok := toInt(cfg.Options["port"])
|
||||
port, ok := cfg.Options["port"].(int64)
|
||||
if !ok || port < 1 || port > 65535 {
|
||||
return fmt.Errorf("pipeline '%s' source[%d]: invalid or missing HTTP port",
|
||||
pipelineName, sourceIndex)
|
||||
@ -125,7 +125,7 @@ func validateSource(pipelineName string, sourceIndex int, cfg *SourceConfig) err
|
||||
|
||||
case "tcp":
|
||||
// Validate TCP source options
|
||||
port, ok := toInt(cfg.Options["port"])
|
||||
port, ok := cfg.Options["port"].(int64)
|
||||
if !ok || port < 1 || port > 65535 {
|
||||
return fmt.Errorf("pipeline '%s' source[%d]: invalid or missing TCP port",
|
||||
pipelineName, sourceIndex)
|
||||
@ -146,7 +146,7 @@ func validateSource(pipelineName string, sourceIndex int, cfg *SourceConfig) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts map[int]string) error {
|
||||
func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts map[int64]string) error {
|
||||
if cfg.Type == "" {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: missing type", pipelineName, sinkIndex)
|
||||
}
|
||||
@ -154,7 +154,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
switch cfg.Type {
|
||||
case "http":
|
||||
// Extract and validate HTTP configuration
|
||||
port, ok := toInt(cfg.Options["port"])
|
||||
port, ok := cfg.Options["port"].(int64)
|
||||
if !ok || port < 1 || port > 65535 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: invalid or missing HTTP port",
|
||||
pipelineName, sinkIndex)
|
||||
@ -168,7 +168,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
allPorts[port] = fmt.Sprintf("%s-http[%d]", pipelineName, sinkIndex)
|
||||
|
||||
// Validate buffer size
|
||||
if bufSize, ok := toInt(cfg.Options["buffer_size"]); ok {
|
||||
if bufSize, ok := cfg.Options["buffer_size"].(int64); ok {
|
||||
if bufSize < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: HTTP buffer size must be positive: %d",
|
||||
pipelineName, sinkIndex, bufSize)
|
||||
@ -213,7 +213,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
|
||||
case "tcp":
|
||||
// Extract and validate TCP configuration
|
||||
port, ok := toInt(cfg.Options["port"])
|
||||
port, ok := cfg.Options["port"].(int64)
|
||||
if !ok || port < 1 || port > 65535 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: invalid or missing TCP port",
|
||||
pipelineName, sinkIndex)
|
||||
@ -227,7 +227,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
allPorts[port] = fmt.Sprintf("%s-tcp[%d]", pipelineName, sinkIndex)
|
||||
|
||||
// Validate buffer size
|
||||
if bufSize, ok := toInt(cfg.Options["buffer_size"]); ok {
|
||||
if bufSize, ok := cfg.Options["buffer_size"].(int64); ok {
|
||||
if bufSize < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: TCP buffer size must be positive: %d",
|
||||
pipelineName, sinkIndex, bufSize)
|
||||
@ -275,7 +275,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
}
|
||||
|
||||
// Validate batch size
|
||||
if batchSize, ok := toInt(cfg.Options["batch_size"]); ok {
|
||||
if batchSize, ok := cfg.Options["batch_size"].(int64); ok {
|
||||
if batchSize < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: batch_size must be positive: %d",
|
||||
pipelineName, sinkIndex, batchSize)
|
||||
@ -283,7 +283,7 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
}
|
||||
|
||||
// Validate timeout
|
||||
if timeout, ok := toInt(cfg.Options["timeout_seconds"]); ok {
|
||||
if timeout, ok := cfg.Options["timeout_seconds"].(int64); ok {
|
||||
if timeout < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: timeout_seconds must be positive: %d",
|
||||
pipelineName, sinkIndex, timeout)
|
||||
@ -307,14 +307,14 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
}
|
||||
|
||||
// Validate timeouts
|
||||
if dialTimeout, ok := toInt(cfg.Options["dial_timeout_seconds"]); ok {
|
||||
if dialTimeout, ok := cfg.Options["dial_timeout_seconds"].(int64); ok {
|
||||
if dialTimeout < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: dial_timeout_seconds must be positive: %d",
|
||||
pipelineName, sinkIndex, dialTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
if writeTimeout, ok := toInt(cfg.Options["write_timeout_seconds"]); ok {
|
||||
if writeTimeout, ok := cfg.Options["write_timeout_seconds"].(int64); ok {
|
||||
if writeTimeout < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: write_timeout_seconds must be positive: %d",
|
||||
pipelineName, sinkIndex, writeTimeout)
|
||||
@ -336,21 +336,21 @@ func validateSink(pipelineName string, sinkIndex int, cfg *SinkConfig, allPorts
|
||||
}
|
||||
|
||||
// Validate numeric options
|
||||
if maxSize, ok := toInt(cfg.Options["max_size_mb"]); ok {
|
||||
if maxSize, ok := cfg.Options["max_size_mb"].(int64); ok {
|
||||
if maxSize < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: max_size_mb must be positive: %d",
|
||||
pipelineName, sinkIndex, maxSize)
|
||||
}
|
||||
}
|
||||
|
||||
if maxTotalSize, ok := toInt(cfg.Options["max_total_size_mb"]); ok {
|
||||
if maxTotalSize, ok := cfg.Options["max_total_size_mb"].(int64); ok {
|
||||
if maxTotalSize < 0 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: max_total_size_mb cannot be negative: %d",
|
||||
pipelineName, sinkIndex, maxTotalSize)
|
||||
}
|
||||
}
|
||||
|
||||
if retention, ok := toFloat(cfg.Options["retention_hours"]); ok {
|
||||
if retention, ok := cfg.Options["retention_hours"].(float64); ok {
|
||||
if retention < 0 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d]: retention_hours cannot be negative: %f",
|
||||
pipelineName, sinkIndex, retention)
|
||||
|
||||
@ -25,7 +25,7 @@ type RateLimitConfig struct {
|
||||
// Policy defines the action to take when the limit is exceeded. "pass" or "drop".
|
||||
Policy string `toml:"policy"`
|
||||
// MaxEntrySizeBytes is the maximum allowed size for a single log entry. 0 = no limit.
|
||||
MaxEntrySizeBytes int `toml:"max_entry_size_bytes"`
|
||||
MaxEntrySizeBytes int64 `toml:"max_entry_size_bytes"`
|
||||
}
|
||||
|
||||
func validateRateLimit(pipelineName string, cfg *RateLimitConfig) error {
|
||||
|
||||
@ -4,9 +4,9 @@ package config
|
||||
import "fmt"
|
||||
|
||||
type TCPConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
Port int `toml:"port"`
|
||||
BufferSize int `toml:"buffer_size"`
|
||||
Enabled bool `toml:"enabled"`
|
||||
Port int64 `toml:"port"`
|
||||
BufferSize int64 `toml:"buffer_size"`
|
||||
|
||||
// SSL/TLS Configuration
|
||||
SSL *SSLConfig `toml:"ssl"`
|
||||
@ -19,9 +19,9 @@ type TCPConfig struct {
|
||||
}
|
||||
|
||||
type HTTPConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
Port int `toml:"port"`
|
||||
BufferSize int `toml:"buffer_size"`
|
||||
Enabled bool `toml:"enabled"`
|
||||
Port int64 `toml:"port"`
|
||||
BufferSize int64 `toml:"buffer_size"`
|
||||
|
||||
// Endpoint paths
|
||||
StreamPath string `toml:"stream_path"`
|
||||
@ -39,10 +39,10 @@ type HTTPConfig struct {
|
||||
|
||||
type HeartbeatConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
IntervalSeconds int `toml:"interval_seconds"`
|
||||
IntervalSeconds int64 `toml:"interval_seconds"`
|
||||
IncludeTimestamp bool `toml:"include_timestamp"`
|
||||
IncludeStats bool `toml:"include_stats"`
|
||||
Format string `toml:"format"` // "comment" or "json"
|
||||
Format string `toml:"format"`
|
||||
}
|
||||
|
||||
type NetLimitConfig struct {
|
||||
@ -53,23 +53,23 @@ type NetLimitConfig struct {
|
||||
RequestsPerSecond float64 `toml:"requests_per_second"`
|
||||
|
||||
// Burst size (token bucket)
|
||||
BurstSize int `toml:"burst_size"`
|
||||
BurstSize int64 `toml:"burst_size"`
|
||||
|
||||
// Net limit by: "ip", "user", "token", "global"
|
||||
LimitBy string `toml:"limit_by"`
|
||||
|
||||
// Response when net limited
|
||||
ResponseCode int `toml:"response_code"` // Default: 429
|
||||
ResponseCode int64 `toml:"response_code"` // Default: 429
|
||||
ResponseMessage string `toml:"response_message"` // Default: "Net limit exceeded"
|
||||
|
||||
// Connection limits
|
||||
MaxConnectionsPerIP int `toml:"max_connections_per_ip"`
|
||||
MaxTotalConnections int `toml:"max_total_connections"`
|
||||
MaxConnectionsPerIP int64 `toml:"max_connections_per_ip"`
|
||||
MaxTotalConnections int64 `toml:"max_total_connections"`
|
||||
}
|
||||
|
||||
func validateHeartbeatOptions(serverType, pipelineName string, sinkIndex int, hb map[string]any) error {
|
||||
if enabled, ok := hb["enabled"].(bool); ok && enabled {
|
||||
interval, ok := toInt(hb["interval_seconds"])
|
||||
interval, ok := hb["interval_seconds"].(int64)
|
||||
if !ok || interval < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: heartbeat interval must be positive",
|
||||
pipelineName, sinkIndex, serverType)
|
||||
@ -91,14 +91,14 @@ func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, rl
|
||||
}
|
||||
|
||||
// Validate requests per second
|
||||
rps, ok := toFloat(rl["requests_per_second"])
|
||||
rps, ok := rl["requests_per_second"].(float64)
|
||||
if !ok || rps <= 0 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: requests_per_second must be positive",
|
||||
pipelineName, sinkIndex, serverType)
|
||||
}
|
||||
|
||||
// Validate burst size
|
||||
burst, ok := toInt(rl["burst_size"])
|
||||
burst, ok := rl["burst_size"].(int64)
|
||||
if !ok || burst < 1 {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: burst_size must be at least 1",
|
||||
pipelineName, sinkIndex, serverType)
|
||||
@ -114,7 +114,7 @@ func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, rl
|
||||
}
|
||||
|
||||
// Validate response code
|
||||
if respCode, ok := toInt(rl["response_code"]); ok {
|
||||
if respCode, ok := rl["response_code"].(int64); ok {
|
||||
if respCode > 0 && (respCode < 400 || respCode >= 600) {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: response_code must be 4xx or 5xx: %d",
|
||||
pipelineName, sinkIndex, serverType, respCode)
|
||||
@ -122,8 +122,8 @@ func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, rl
|
||||
}
|
||||
|
||||
// Validate connection limits
|
||||
maxPerIP, perIPOk := toInt(rl["max_connections_per_ip"])
|
||||
maxTotal, totalOk := toInt(rl["max_total_connections"])
|
||||
maxPerIP, perIPOk := rl["max_connections_per_ip"].(int64)
|
||||
maxTotal, totalOk := rl["max_total_connections"].(int64)
|
||||
|
||||
if perIPOk && totalOk && maxPerIP > 0 && maxTotal > 0 {
|
||||
if maxPerIP > maxTotal {
|
||||
|
||||
@ -23,7 +23,7 @@ func (c *Config) validate() error {
|
||||
}
|
||||
|
||||
// Track used ports across all pipelines
|
||||
allPorts := make(map[int]string)
|
||||
allPorts := make(map[int64]string)
|
||||
pipelineNames := make(map[string]bool)
|
||||
|
||||
for i, pipeline := range c.Pipelines {
|
||||
|
||||
Reference in New Issue
Block a user