This document provides guidelines for working with Outpost configuration.
When adding new configuration fields to Outpost, follow these steps to ensure consistency and proper logging:
Add your new field to the appropriate config struct in internal/config/:
type Config struct {
// ... existing fields ...
MyNewField string `yaml:"my_new_field" env:"MY_NEW_FIELD" desc:"Description of the field" required:"N"`
}Update InitDefaults() in internal/config/config.go:
func (c *Config) InitDefaults() {
// ... existing defaults ...
c.MyNewField = "default_value"
}To maintain visibility into startup configuration, you MUST update the configuration logging helper in internal/config/logging.go:
Add your field to LogConfigurationSummary():
func (c *Config) LogConfigurationSummary() []zap.Field {
fields := []zap.Field{
// ... existing fields ...
// For non-sensitive fields:
zap.String("my_new_field", c.MyNewField),
// For sensitive fields (passwords, secrets, keys):
zap.Bool("my_secret_field_configured", c.MySecretField != ""),
// ... rest of fields ...
}
return fields
}If adding MQ-specific fields, update getMQSpecificFields():
func (c *Config) getMQSpecificFields(mqType string) []zap.Field {
switch mqType {
case "rabbitmq":
return []zap.Field{
// ... existing fields ...
zap.String("rabbitmq_my_field", c.MQs.RabbitMQ.MyField),
}
// ... other cases ...
}
}Always mask sensitive data in logs:
- ✅ DO: Use
zap.Bool("field_configured", value != "")for secrets - ✅ DO: Use helper functions like
maskURL()for URLs with credentials - ❌ DON'T: Log actual passwords, API keys, tokens, or secrets
- ❌ DON'T: Log full connection strings with credentials
Examples:
// Good - shows if configured without exposing value
zap.Bool("api_key_configured", c.APIKey != "")
// Good - masks credentials in URL
zap.String("database_url", maskPostgresURLHost(c.PostgresURL))
// Bad - exposes sensitive data
zap.String("api_key", c.APIKey) // ❌ NEVER DO THISIf your field requires validation, update Validate() in internal/config/validation.go.
Don't forget to regenerate the configuration documentation:
go generate ./internal/config/...This will update docs/pages/references/configuration.mdx with your new field's description.
When adding or modifying configuration fields, use this checklist:
- Field added to appropriate struct with
yaml,env,desc, andrequiredtags - Default value added to
InitDefaults()(if applicable) - Field added to
LogConfigurationSummary()ininternal/config/logging.go - Sensitive fields are masked (showing only if configured, not actual value)
- MQ-specific fields added to
getMQSpecificFields()(if applicable) - Validation added (if required)
- Documentation regenerated with
go generate - Changes tested with
LOG_LEVEL=infoto verify logs appear correctly
Configuration logging serves several critical purposes:
- Troubleshooting: When users report issues, configuration logs help identify misconfiguration quickly
- Security Auditing: Shows what's configured without exposing sensitive values
- Deployment Verification: Confirms the application started with expected configuration
- Documentation: Provides a real-world example of what configuration is being used
Keeping configuration logging up-to-date prevents "configuration drift" where the code and logs don't match, making troubleshooting harder.
TBD
To support OpenTelemetry, you must have this env OTEL_SERVICE_NAME. Its value is your service name when sending to OTEL. You can use whichever value you see fit.
In production, if Outpost is run as a singular service, then the service name can be outpost. If Outpost is run in multiple processes (for API, delivery, log, etc.), you can provide more granularity by including the service type such as outpost.api or outpost.delivery, etc. Ultimately, it's up to the end users which value they want to see in their telemetry data.
Besides OTEL_SERVICE_NAME, we support the official OpenTelemetry Environment Variable Specification.
To specify the exporter endpoint, you can use OTEL_EXPORTER_OTLP_ENDPOINT or individual exporters such as OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, or OTEL_EXPORTER_OTLP_LOGS_ENDPOINT.
By default, Outpost will export all Telemetry data. You can disable specific telemetry by setting its exporter to none. For example, if you only want to receive traces & metrics:
OTEL_TRACES_EXPORTER="otlp" # default
OTEL_METRICS_EXPORTER="otlp" # default
OTEL_LOGS_EXPORTER="none" # disable logs
Currently, we only support otlp exporter. If you have specific needs for other exporter configuration (like Prometheus), you must set up your own OTEL collector and configure it accordingly.