src.dualinventive.com/go/lib/config/config.go

102 lines
2.6 KiB
Go

package config
import (
"io/ioutil"
"os"
"strings"
"github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v2"
"src.dualinventive.com/go/lib/dilog"
)
var (
// searchPaths contain the list of paths to search for config-files
// must include trailing slash
searchPaths = []string{
"./",
"../",
"/etc/di/",
}
)
const (
// DefaultLoglevel is info
DefaultLoglevel = "info"
// DefaultLogfile is empty i.e. stdout
DefaultLogfile = ""
// ConfigExtension is the default extension of config-files
ConfigExtension = ".conf"
// ConfigTrimPrefix is the prefix which is trimmed from names when searching for config-files
ConfigTrimPrefix = "di-"
)
// Config type which other application configurations can inherit from to
// comply with Configuration interface
type Config struct {
Loglevel string
Logfile string
}
// GetLoglevel returns the provided loglevel or DefaultLoglevel when empty
func (c *Config) GetLoglevel() string {
if c.Loglevel == "" {
return DefaultLoglevel
}
return c.Loglevel
}
// GetLogfile returns the provided log-file or DefaultLogfile when empty
func (c *Config) GetLogfile() string {
if c.Logfile == "" {
return DefaultLogfile
}
return c.Logfile
}
// Configuration interface checks if all log-facility parameters are present
// for initialization of the logger
type Configuration interface {
GetLoglevel() string
GetLogfile() string
}
// Load loads the provided configuration from a file into cfg.
// first it shall try to load the file as provided with the name, when not found,
// the file is searched in the search-paths (./, ../, /etc/di/) removing a possible ConfigTrimPrefix
// it is searched with and without a ConfigExtension
func Load(name string, cfg Configuration) (dilog.Logger, error) {
// check if a file with the provided name exist
if _, err := os.Stat(name); err == nil {
return loadFile(name, cfg)
}
namestrip := strings.TrimLeft(name, ConfigTrimPrefix)
for _, path := range searchPaths {
if _, err := os.Stat(path + namestrip); err == nil {
return loadFile(path+namestrip+ConfigExtension, cfg)
}
if _, err := os.Stat(path + namestrip + ConfigExtension); err == nil {
return loadFile(path+namestrip+ConfigExtension, cfg)
}
}
return nil, os.ErrNotExist
}
func loadFile(filePath string, cfg Configuration) (dilog.Logger, error) {
// #nosec Ignore possible file inclusion warning
b, errr := ioutil.ReadFile(filePath)
if errr != nil {
return nil, errr
}
if err := yaml.Unmarshal(b, cfg); err != nil {
return nil, err
}
logger, err := dilog.NewLogger(cfg.GetLogfile(), cfg.GetLoglevel())
if err != nil {
logrus.WithError(err).Fatal("invalid logger")
}
return logger, nil
}