app/system/setup.go

163 lines
3.5 KiB
Go

package system
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
"github.com/fatih/color"
"github.com/rs/zerolog"
"github.com/spf13/viper"
"kumoly.io/kumoly/app/util"
)
func init() {
Home, err := os.UserHomeDir()
if err != nil {
Home = "/"
}
// Setup defaults
// =========================================================
// App
viper.SetDefault("name", "app")
viper.SetDefault("domain", "kumoly.io")
viper.SetDefault("timezone", "Asia/Taipei")
// mode [prod, dev]
viper.SetDefault("prod", true)
// log.level : [-1(trace):5(panic)] 7 to disable
viper.SetDefault("log.level", int(zerolog.InfoLevel))
viper.SetDefault("log.pretty", false)
// data: data dir
viper.SetDefault("data", filepath.Join(Home, ".kumoly"))
// =========================================================
// viper settings
viper.SetEnvPrefix("app")
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
viper.AutomaticEnv()
viper.SetConfigType("json")
}
var setupped bool = false
func SetupLogger(l zerolog.Logger, skip ...int) zerolog.Logger {
if !util.PROD && len(skip) == 0 {
l = l.With().Caller().Logger()
}
if viper.GetBool("log.pretty") {
l = l.Output(zerolog.ConsoleWriter{
Out: os.Stdout,
TimeFormat: "2006/01/02 15:04:05",
FormatCaller: func(i interface{}) string {
var c string
if cc, ok := i.(string); ok {
c = cc
}
if len(c) > 0 {
// shorten caller to mod/file:line
segs := strings.Split(c, ":")
file := segs[len(segs)-2]
short := file
ptr := 0
for i := len(file) - 1; i > 0; i-- {
if file[i] == '/' {
if ptr == 0 {
short = file[i+1:]
ptr = i
} else {
short = fmt.Sprintf("%v/%v", file[i+1:ptr], short)
break
}
}
if file[i] == '@' {
ptr = i
}
}
return color.GreenString("%v:%v >", short, segs[len(segs)-1])
}
return c
},
})
}
return l
}
func Setup() {
if setupped {
return
} else {
setupped = true
}
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
zerolog.DurationFieldInteger = true
zerolog.SetGlobalLevel(zerolog.Level(viper.GetInt("log.level")))
util.PROD = viper.GetBool("prod")
util.Klog = SetupLogger(util.Klog)
l = util.Klog.With().Str("mod", "system").Logger()
tz, err := time.LoadLocation(viper.GetString("timezone"))
if err == nil {
time.Local = tz
} else {
l.Error().Err(err).Msg("setup error")
}
}
func SetConfigPath(path string) {
ConfigRead(path)
}
func SetDataPath(path string) {
viper.Set("data", path)
}
// ConfigRead read in config
func ConfigRead(cfgFile string) {
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
// read config from default path
viper.SetConfigName("app")
viper.AddConfigPath(viper.GetString("data"))
}
if err := viper.ReadInConfig(); err != nil {
l.Error().Err(err).Msg("ReadInConfig error")
}
Setup()
}
// ConfigWrite write current config to file
func ConfigWrite(file string) {
viper.WriteConfigAs(file)
}
// ConfigShow print config to stdout
func ConfigShow(format string) (string, error) {
if format == "" {
format = "json"
}
path := filepath.Join(viper.GetString("data"), "tmp")
util.Mkdir(path)
file := filepath.Join(path, "config."+format)
err := viper.WriteConfigAs(file)
if err != nil {
l.Error().Err(err).Msg("WriteConfigAs error")
return "", err
}
data, err := ioutil.ReadFile(file)
if err != nil {
l.Error().Err(err).Msg("ReadFile error")
return "", err
}
return string(data), nil
}