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 }