speedy/pkg/config.go

138 lines
4.9 KiB
Go
Raw Normal View History

2021-10-04 11:03:36 +00:00
package pkg
import (
"errors"
"github.com/getsentry/sentry-go"
"github.com/goccy/go-json"
"github.com/spf13/viper"
"math"
)
// Configuration holds all the application's configurable settings.
type Configuration struct {
// LoggingLevel is the logging level.
LoggingLevel string `json:"logging_level"`
// SentryDSN is the DSN used by Sentry, for reporting errors.
SentryDSN string `json:"sentry_dsn"`
// KafkaPollingGoroutines is the number of goroutines that will poll Kafka for new messages.
KafkaPollingGoroutines int `json:"kafka_polling_goroutines"`
// KafkaPollingTimeoutMs is the timeout in milliseconds for the message poll().
KafkaPollingTimeoutMs int `json:"kafka_polling_timeout_ms"`
// KafkaBoostrapServers is a string of comma separated boostrap servers.
KafkaBoostrapServers string `json:"kafka_boostrap_servers"`
// KafkaGroupId is the Kafka consumer group id.
KafkaGroupId string `json:"kafka_group_id"`
// SubscribeTopics is the list of topics or patterns to subscribe to.
SubscribeTopics []string `json:"subscribe_topics"`
// LokiPushUrl is the full URL of the Loki push API endpoint.
LokiPushUrl string `json:"loki_push_url"`
// LokiPushMode is the mode used to push data to Loki, http or proto.
LokiPushMode string `json:"loki_push_mode"`
// BufferMaxBatchSize is the batch size that will be sent to Loki.
BufferMaxBatchSize int `json:"buffer_max_batch_size"`
// BufferMaxBytesSize is max buffer size in bytes uncompressed and unserialized that will be sent to Loki.
BufferMaxBytesSize int `json:"buffer_max_bytes_size"`
// KafkaOffsetReset is analogous to https://kafka.apache.org/documentation/#consumerconfigs_auto.offset.reset
KafkaOffsetReset string `json:"kafka_offset_reset"`
}
// ToPrettyJson transforms the current configuration to a pretty json.
func (c Configuration) ToPrettyJson() string {
prettyJson, err := json.MarshalIndent(c, "", " ")
if err != nil {
SugaredLogger.Error("failed to convert config to pretty json")
return ""
}
return string(prettyJson)
}
// ViperConfigurator is a convenient wrapper over Viper.
type ViperConfigurator struct {
viper *viper.Viper
configuration Configuration
}
func NewViperConfigurator() (*ViperConfigurator, error) {
viperInstance := viper.New()
viperInstance.SetConfigName("config")
viperInstance.SetConfigType("json")
viperInstance.AddConfigPath("$HOME/.speedy")
viperInstance.AddConfigPath(".")
viperInstance.SetEnvPrefix("SG")
viperInstance.AutomaticEnv()
if err := viperInstance.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
SugaredLogger.Warn("Config file not found")
} else {
SugaredLogger.Error("Error loading config file.")
sentry.CaptureException(err)
return nil, err
}
}
viperConfigurator := ViperConfigurator{viperInstance, Configuration{}}
err := viperConfigurator.loadConfig()
if err != nil {
SugaredLogger.Error(err)
sentry.CaptureException(err)
return nil, err
}
return &viperConfigurator, nil
}
// GetConfig returns a copy of the Configuration data structure.
func (v *ViperConfigurator) GetConfig() Configuration {
return v.configuration
}
// loadConfig loads configuration from viper onto the internal data structures.
func (v *ViperConfigurator) loadConfig() error {
v.configuration.KafkaBoostrapServers = v.viper.GetString("kafka_bootstrap_servers")
if v.configuration.KafkaBoostrapServers == "" {
return errors.New("kafka_bootstrap_servers is empty")
}
v.configuration.KafkaGroupId = v.viper.GetString("kafka_group_id")
if v.configuration.KafkaGroupId == "" {
return errors.New("kafka_group_id is empty")
}
v.configuration.LokiPushUrl = v.viper.GetString("loki_push_url")
if v.configuration.LokiPushUrl == "" {
return errors.New("loki_push_url is empty")
}
v.configuration.SubscribeTopics = v.viper.GetStringSlice("subscribe_topics")
if len(v.configuration.SubscribeTopics) == 0 {
return errors.New("subscribe_topics is empty")
}
v.viper.SetDefault("buffer_max_batch_size", 10_000)
v.configuration.BufferMaxBatchSize = v.viper.GetInt("buffer_max_batch_size")
v.viper.SetDefault("buffer_max_bytes_size", math.MaxInt32)
v.configuration.BufferMaxBytesSize = v.viper.GetInt("buffer_max_bytes_size")
v.viper.SetDefault("loki_push_mode", "http")
v.configuration.LokiPushMode = v.viper.GetString("loki_push_mode")
v.viper.SetDefault("kafka_offset_reset", "earliest")
v.configuration.KafkaOffsetReset = v.viper.GetString("kafka_offset_reset")
v.viper.SetDefault("logging_level", "info")
v.configuration.LoggingLevel = v.viper.GetString("logging_level")
v.viper.SetDefault("kafka_polling_goroutines", 5)
v.configuration.KafkaPollingGoroutines = v.viper.GetInt("kafka_polling_goroutines")
v.viper.SetDefault("kafka_polling_timeout_ms", 30_000)
v.configuration.KafkaPollingTimeoutMs = v.viper.GetInt("kafka_polling_timeout_ms")
v.viper.SetDefault("sentry_dsn", "")
v.configuration.SentryDSN = v.viper.GetString("sentry_dsn")
return nil
}