Documentation Index
Fetch the complete documentation index at: https://mintlify.com/raystack/salt/llms.txt
Use this file to discover all available pages before exploring further.
This guide will walk you through creating a simple Go application using Salt’s configuration management and logging packages.
Prerequisites
- Go 1.22 or later installed
- Basic familiarity with Go modules
Step-by-step guide
Create a new Go project
Create a new directory and initialize a Go module:mkdir my-salt-app
cd my-salt-app
go mod init example.com/my-salt-app
Install Salt
Add Salt to your project:go get github.com/raystack/salt
Create your configuration
Create a config.yaml file in your project root:app:
name: "my-app"
environment: "development"
port: 8080
database:
host: "localhost"
port: 5432
name: "mydb"
log:
level: "info"
Create your application config struct
Create a main.go file and define your configuration struct:package main
import (
"fmt"
"github.com/raystack/salt/config"
"github.com/raystack/salt/log"
)
type AppConfig struct {
App struct {
Name string `mapstructure:"name" default:"app"`
Environment string `mapstructure:"environment" default:"development"`
Port int `mapstructure:"port" default:"8080" validate:"required,min=1,max=65535"`
} `mapstructure:"app"`
Database struct {
Host string `mapstructure:"host" default:"localhost"`
Port int `mapstructure:"port" default:"5432"`
Name string `mapstructure:"name" validate:"required"`
} `mapstructure:"database"`
Log struct {
Level string `mapstructure:"level" default:"info"`
} `mapstructure:"log"`
}
Load configuration and initialize logging
Add the main function to load configuration and set up logging:func main() {
// Create configuration loader
loader := config.NewLoader(
config.WithFile("./config.yaml"),
config.WithEnvPrefix("MYAPP"),
)
// Load configuration
var cfg AppConfig
if err := loader.Load(&cfg); err != nil {
panic(fmt.Sprintf("failed to load config: %v", err))
}
// Initialize logger
logger := log.NewLogrus(
log.LogrusWithLevel(cfg.Log.Level),
)
// Log application startup
logger.Info("application starting",
"name", cfg.App.Name,
"environment", cfg.App.Environment,
"port", cfg.App.Port,
)
logger.Info("database configuration",
"host", cfg.Database.Host,
"port", cfg.Database.Port,
"name", cfg.Database.Name,
)
// Your application logic here
logger.Info("application ready")
}
Run your application
Run your application:You should see output like:INFO[0000] application starting environment=development name=my-app port=8080
INFO[0000] database configuration host=localhost port=5432 name=mydb
INFO[0000] application ready
Try overriding configuration with environment variables:MYAPP_APP_PORT=9090 MYAPP_LOG_LEVEL=debug go run main.go
Configuration precedence
Salt uses the following configuration precedence (highest to lowest):
- Command-line flags (if
WithFlags() is used)
- Environment variables (with the specified prefix)
- Configuration file (YAML/JSON)
- Default values (from struct tags)
This allows you to:
- Use sensible defaults for development
- Override with config files for different environments
- Override specific values with environment variables in production
- Override everything with command-line flags for testing
Next steps
Now that you have a basic Salt application running, explore more features:
Configuration Package
Learn about advanced configuration features like dynamic flag binding and validation
Logging Package
Explore structured logging with Logrus and Zap
Database Package
Add database connectivity with connection pooling and migrations
CLI Utilities
Build powerful CLI tools with commander, printer, and prompter
Complete example
Here’s the complete working example:
package main
import (
"fmt"
"github.com/raystack/salt/config"
"github.com/raystack/salt/log"
)
type AppConfig struct {
App struct {
Name string `mapstructure:"name" default:"app"`
Environment string `mapstructure:"environment" default:"development"`
Port int `mapstructure:"port" default:"8080" validate:"required,min=1,max=65535"`
} `mapstructure:"app"`
Database struct {
Host string `mapstructure:"host" default:"localhost"`
Port int `mapstructure:"port" default:"5432"`
Name string `mapstructure:"name" validate:"required"`
} `mapstructure:"database"`
Log struct {
Level string `mapstructure:"level" default:"info"`
} `mapstructure:"log"`
}
func main() {
// Create configuration loader
loader := config.NewLoader(
config.WithFile("./config.yaml"),
config.WithEnvPrefix("MYAPP"),
)
// Load configuration
var cfg AppConfig
if err := loader.Load(&cfg); err != nil {
panic(fmt.Sprintf("failed to load config: %v", err))
}
// Initialize logger
logger := log.NewLogrus(
log.LogrusWithLevel(cfg.Log.Level),
)
// Log application startup
logger.Info("application starting",
"name", cfg.App.Name,
"environment", cfg.App.Environment,
"port", cfg.App.Port,
)
logger.Info("database configuration",
"host", cfg.Database.Host,
"port", cfg.Database.Port,
"name", cfg.Database.Name,
)
// Your application logic here
logger.Info("application ready")
}
View complete config.yaml
app:
name: "my-app"
environment: "development"
port: 8080
database:
host: "localhost"
port: 5432
name: "mydb"
log:
level: "info"