Skip to content

Config Manager

The Config Manager provides a unified configuration system that loads settings from multiple sources with intelligent merging and priority handling.

Settings are loaded in the following order (highest to lowest priority):

  1. Command line arguments (--host, --port)
  2. Environment variables (SIDESEAT_HOST, SIDESEAT_PORT)
  3. Workdir config (./sideseat.json)
  4. User config (~/.sideseat/config.json)
  5. Default values

Higher priority sources override lower priority sources. Objects are deep-merged, allowing partial overrides.

Located in the user config directory. This file is optional and provides user-level defaults.

{
"server": {
"host": "127.0.0.1",
"port": 5001
},
"logging": {
"level": "info",
"format": "compact"
}
}

Located in the current working directory. Project-specific settings that override user config.

{
"server": {
"port": 3000
},
"logging": {
"level": "debug"
}
}
VariableDescriptionDefault
SIDESEAT_HOSTServer host address127.0.0.1
SIDESEAT_PORTServer port5001
SIDESEAT_LOGLog level/filterinfo
SIDESEAT_AUTH_ENABLEDEnable/disable authenticationtrue
SIDESEAT_CONFIG_DIROverride config directoryPlatform default
SIDESEAT_DATA_DIROverride data directoryPlatform default
SIDESEAT_CACHE_DIROverride cache directoryPlatform default
Terminal window
# Example: Run on a different port
export SIDESEAT_PORT=8080
sideseat start
# Or pass directly
SIDESEAT_PORT=8080 sideseat start
Terminal window
sideseat start --host 0.0.0.0 --port 3000
sideseat start -H 0.0.0.0 -p 3000 # Short form
sideseat start --no-auth # Disable authentication

CLI arguments have the highest priority and always override other sources.

{
"server": {
"host": "127.0.0.1",
"port": 5001
},
"logging": {
"level": "info",
"format": "compact"
},
"storage": {
"config_dir": "/custom/config/path",
"data_dir": "/custom/data/path",
"cache_dir": "/custom/cache/path"
},
"auth": {
"enabled": true
},
"otel": {
"enabled": true,
"grpc": {
"enabled": true,
"port": 4317
},
"ingestion": {
"channel_capacity": 10000,
"buffer_max_spans": 5000,
"buffer_max_bytes": 10485760,
"flush_interval_ms": 100,
"flush_batch_size": 500
},
"retention": {
"days": null,
"check_interval_secs": 300
},
"limits": {
"max_span_name_len": 1000,
"max_attribute_count": 100,
"max_attribute_value_len": 10240,
"max_events_per_span": 100
},
"sse": {
"max_connections": 100,
"timeout_secs": 3600,
"keepalive_secs": 30
}
}
}
FieldTypeDefaultDescription
hoststring"127.0.0.1"Server bind address
portnumber5001Server port
FieldTypeDefaultDescription
levelstring"info"Log level (trace, debug, info, warn, error)
formatstring"compact"Log output format
FieldTypeDefaultDescription
config_dirstringnullOverride config directory path
data_dirstringnullOverride data directory path
cache_dirstringnullOverride cache directory path
FieldTypeDefaultDescription
enabledbooleantrueEnable/disable authentication

Authentication can be disabled via:

  • Config file: "auth": { "enabled": false }
  • Environment variable: SIDESEAT_AUTH_ENABLED=false
  • CLI flag: --no-auth

OpenTelemetry collector configuration for trace ingestion and storage. Settings are organized into logical sub-groups.

FieldTypeDefaultDescription
enabledbooleantrueEnable/disable OTel collector
FieldTypeDefaultDescription
enabledbooleantrueEnable gRPC endpoint
portnumber4317gRPC listener port (OTLP standard)
FieldTypeDefaultDescription
channel_capacitynumber10000Bounded channel capacity for ingestion
buffer_max_spansnumber5000Maximum spans in buffer before flush
buffer_max_bytesnumber10485760Maximum bytes in buffer (10MB)
flush_interval_msnumber100Flush interval in milliseconds
flush_batch_sizenumber500Batch size for flush operations
FieldTypeDefaultDescription
daysnumbernullRetention period in days (null = no limit)
check_interval_secsnumber300Retention check interval (5 min)
FieldTypeDefaultDescription
max_span_name_lennumber1000Maximum span name length
max_attribute_countnumber100Maximum attributes per span
max_attribute_value_lennumber10240Maximum attribute value length (10KB)
max_events_per_spannumber100Maximum events per span
FieldTypeDefaultDescription
max_connectionsnumber100Maximum concurrent SSE connections
timeout_secsnumber3600SSE connection timeout (1 hour)
keepalive_secsnumber30SSE keepalive interval

Configure which attributes to extract and index for flexible filtering using the EAV storage pattern.

FieldTypeDefaultDescription
trace_attributesstring[]See belowAttributes to index at trace level
span_attributesstring[]See belowAttributes to index at span level
auto_index_genaibooleantrueAuto-index all gen_ai.* attributes

Default trace_attributes:

  • environment
  • deployment.environment
  • service.version
  • user.id
  • session.id

Default span_attributes:

  • gen_ai.system
  • gen_ai.operation.name
  • gen_ai.request.model
  • level

Example configuration:

{
"otel": {
"attributes": {
"trace_attributes": [
"environment",
"user.id",
"tenant.id",
"custom.field"
],
"span_attributes": [
"gen_ai.system",
"level"
],
"auto_index_genai": true
}
}
}

See OpenTelemetry Collector - Attribute Filtering for usage details.

Configuration objects are deep-merged, not replaced. This allows partial overrides:

// User config (~/.sideseat/config.json)
{
"server": {
"host": "127.0.0.1",
"port": 5001
},
"logging": {
"level": "info",
"format": "compact"
}
}
// Workdir config (./sideseat.json)
{
"server": {
"port": 3000
},
"logging": {
"level": "debug"
}
}
// Resulting merged config:
{
"server": {
"host": "127.0.0.1", // From user config
"port": 3000 // From workdir config (higher priority)
},
"logging": {
"level": "debug", // From workdir config
"format": "compact" // From user config
}
}
pub struct CliConfig {
pub host: Option<String>,
pub port: Option<u16>,
pub no_auth: bool,
}
pub struct Config {
pub server: ServerConfig,
pub logging: LoggingConfig,
pub storage: StorageConfig,
pub auth: AuthConfig,
}
pub struct ServerConfig {
pub host: String,
pub port: u16,
}
pub struct LoggingConfig {
pub level: String,
pub format: String,
}
pub struct StorageConfig {
pub config_dir: Option<String>,
pub data_dir: Option<String>,
pub cache_dir: Option<String>,
}
pub struct AuthConfig {
pub enabled: bool,
}
MethodDescription
init(storage, cli_args)Initialize config from all sources
config()Get reference to merged configuration
sources()Get all configuration sources
loaded_sources()Get only successfully loaded sources
use sideseat::core::{ConfigManager, CliConfig, StorageManager};
// Initialize storage first
let storage = StorageManager::init().await?;
// Create CLI config from parsed arguments
let cli_config = CliConfig {
host: Some("0.0.0.0".to_string()),
port: None,
};
// Initialize config manager
let config_manager = ConfigManager::init(&storage, &cli_config)?;
let config = config_manager.config();
println!("Server: {}:{}", config.server.host, config.server.port);
println!("Log level: {}", config.logging.level);
// List loaded configuration sources
for source in config_manager.loaded_sources() {
if let Some(ref path) = source.path {
println!("Loaded from: {}", path.display());
}
}

The Config Manager returns detailed errors for invalid configuration files:

Invalid JSON in '/home/user/.sideseat/config.json' at line 5, column 12: expected `,` or `}`

Common error scenarios:

  • Invalid JSON syntax (returns error with line/column)
  • File read permission denied
  • Invalid port number in environment variable (warning logged, value ignored)

Missing configuration files are silently skipped and do not cause errors.

SideSeat loads environment variables from a .env file in the current directory using dotenvy. This is processed before configuration initialization.

.env
SIDESEAT_HOST=0.0.0.0
SIDESEAT_PORT=8080
SIDESEAT_LOG=debug
  1. Use workdir config for project settings - Keep project-specific settings in sideseat.json
  2. Use user config for personal defaults - Store your preferred defaults in ~/.sideseat/config.json
  3. Use environment variables for deployment - Override settings without modifying files
  4. Use CLI arguments for one-off changes - Quick overrides without changing any files
  5. Partial configs are fine - Only specify the settings you want to override
  6. Don’t store secrets in config files - Use the Secret Manager for credentials