Configuration
Humus uses YAML-based configuration with Go template support. This provides a flexible, environment-aware configuration system.
Basic Configuration
A minimal configuration file looks like this:
rest:
port: 8080
otel:
service:
name: my-service
Configuration Structure
Service Type Sections
Each service type has its own configuration section:
REST Services:
rest:
port: 8080
host: localhost # optional, defaults to all interfaces
gRPC Services:
grpc:
port: 9090
host: localhost # optional
Job Services:
# Jobs don't need server configuration
# Just OTel and app-specific config
OpenTelemetry Configuration
The otel section configures observability:
otel:
service:
name: my-service
version: 1.0.0 # optional
sdk:
disabled: false # Set to true to disable OTel entirely
traces:
exporter:
otlp:
endpoint: http://localhost:4318
protocol: http/protobuf
metrics:
exporter:
otlp:
endpoint: http://localhost:4318
protocol: http/protobuf
logs:
exporter:
otlp:
endpoint: http://localhost:4318
protocol: http/protobuf
Go Template Support
Configuration files support Go template syntax for dynamic values:
Environment Variables
Use the env function to read environment variables:
otel:
service:
name: {{env "SERVICE_NAME"}}
rest:
port: {{env "PORT"}}
Default Values
Use the default function to provide fallbacks:
otel:
service:
name: {{env "SERVICE_NAME" | default "my-service"}}
rest:
port: {{env "PORT" | default "8080"}}
Complete Example
rest:
port: {{env "HTTP_PORT" | default "8080"}}
host: {{env "HTTP_HOST" | default "0.0.0.0"}}
otel:
service:
name: {{env "OTEL_SERVICE_NAME" | default "my-service"}}
version: {{env "APP_VERSION" | default "dev"}}
sdk:
disabled: {{env "OTEL_DISABLED" | default "false"}}
traces:
exporter:
otlp:
endpoint: {{env "OTEL_EXPORTER_OTLP_ENDPOINT" | default "http://localhost:4318"}}
Configuration in Code
Basic Config Struct
Embed the appropriate config type for your service:
type Config struct {
rest.Config `config:",squash"` // For REST services
// Add your custom config fields here
}
For gRPC:
type Config struct {
grpc.Config `config:",squash"`
}
For Jobs:
type Config struct {
humus.Config `config:",squash"` // Base OTel config only
}
Custom Configuration Fields
Add your own configuration fields using struct tags:
type Config struct {
rest.Config `config:",squash"`
Database struct {
Host string `config:"host"`
Port int `config:"port"`
Name string `config:"name"`
} `config:"database"`
Features struct {
EnableCache bool `config:"enable_cache"`
} `config:"features"`
}
Corresponding YAML:
rest:
port: 8080
database:
host: localhost
port: 5432
name: mydb
features:
enable_cache: true
Configuration Sources
YAML File
The most common source:
rest.Run(rest.YamlSource("config.yaml"), Init)
Multiple Sources
Use bedrockcfg.MultiSource to compose configurations:
import (
"github.com/z5labs/bedrock/pkg/config"
bedrockcfg "github.com/z5labs/bedrock/pkg/config"
)
func main() {
source := bedrockcfg.MultiSource(
bedrockcfg.FromYaml("default_config.yaml"), // Defaults
bedrockcfg.FromYaml("config.yaml"), // Overrides
)
rest.Run(source, Init)
}
Environment-Specific Configs
import "os"
func main() {
env := os.Getenv("ENV")
if env == "" {
env = "dev"
}
configFile := fmt.Sprintf("config.%s.yaml", env)
rest.Run(rest.YamlSource(configFile), Init)
}
This allows you to have:
config.dev.yamlconfig.staging.yamlconfig.prod.yaml
Default Configuration
Humus includes a default_config.yaml with sensible defaults for OpenTelemetry. You can compose this with your config:
source := bedrockcfg.MultiSource(
bedrockcfg.FromYaml("default_config.yaml"), // Framework defaults
bedrockcfg.FromYaml("config.yaml"), // Your overrides
)
Best Practices
Use Environment Variables for Secrets: Never commit credentials to YAML files. Use
envfunction:database: password: {{env "DB_PASSWORD"}}Provide Defaults: Always use
defaultwithenvfor non-secret values:port: {{env "PORT" | default "8080"}}Separate Environments: Use different config files or environment variables for dev/staging/prod.
Document Your Config: Add comments to your YAML files explaining each section.
Validate Early: Use the
Initfunction to validate configuration:func Init(ctx context.Context, cfg Config) (*rest.Api, error) { if cfg.Database.Host == "" { return nil, fmt.Errorf("database host is required") } // ... }
Next Steps
- Learn about Project Structure for organizing your config files
- Explore Core Concepts for advanced configuration patterns
- See Observability for OTel configuration details