diff options
author | ᴜɴᴋɴᴡᴏɴ <u@gogs.io> | 2020-02-20 02:25:02 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-20 02:25:02 +0800 |
commit | 1c09373b4f7dbc68154c817b4ee44bfa3b3f637c (patch) | |
tree | aeec9a80d10f9ef28f0d0b128f8a84bf3cb5bdb1 /internal/setting/setting.go | |
parent | 422a20648466f270de195dce3bca04e977bacd13 (diff) |
log: migrate to unknwon.dev/clog/v2 (#5927)
* Add unknwon.dev/clog/v2
* Update all places
Diffstat (limited to 'internal/setting/setting.go')
-rw-r--r-- | internal/setting/setting.go | 318 |
1 files changed, 182 insertions, 136 deletions
diff --git a/internal/setting/setting.go b/internal/setting/setting.go index 0306b1ea..fd8d14c0 100644 --- a/internal/setting/setting.go +++ b/internal/setting/setting.go @@ -22,8 +22,8 @@ import ( _ "github.com/go-macaron/session/redis" "github.com/mcuadros/go-version" "github.com/unknwon/com" - log "gopkg.in/clog.v1" "gopkg.in/ini.v1" + log "unknwon.dev/clog/v2" "github.com/gogs/go-libravatar" @@ -346,15 +346,19 @@ func execPath() (string, error) { func init() { IsWindows = runtime.GOOS == "windows" - log.New(log.CONSOLE, log.ConsoleConfig{}) - var err error - if AppPath, err = execPath(); err != nil { - log.Fatal(2, "Fail to get app path: %v\n", err) + err := log.NewConsole() + if err != nil { + panic("init console logger: " + err.Error()) + } + + AppPath, err = execPath() + if err != nil { + log.Fatal("Failed to get executable path: %v", err) } - // Note: we don't use path.Dir here because it does not handle case - // which path starts with two "/" in Windows: "//psf/Home/..." + // NOTE: we don't use path.Dir here because it does not handle case + // which path starts with two "/" in Windows: "//psf/Home/..." AppPath = strings.Replace(AppPath, "\\", "/", -1) } @@ -374,7 +378,7 @@ func WorkDir() (string, error) { func forcePathSeparator(path string) { if strings.Contains(path, "\\") { - log.Fatal(2, "Do not use '\\' or '\\\\' in paths, instead, please use '/' in all places") + log.Fatal("Do not use '\\' or '\\\\' in paths, please use '/' in all places") } } @@ -394,31 +398,33 @@ func IsRunUserMatchCurrentUser(runUser string) (string, bool) { // getOpenSSHVersion parses and returns string representation of OpenSSH version // returned by command "ssh -V". func getOpenSSHVersion() string { - // Note: somehow version is printed to stderr - _, stderr, err := process.Exec("getOpenSSHVersion", "ssh", "-V") + // NOTE: Somehow the version is printed to stderr. + _, stderr, err := process.Exec("setting.getOpenSSHVersion", "ssh", "-V") if err != nil { - log.Fatal(2, "Fail to get OpenSSH version: %v - %s", err, stderr) + log.Fatal("Failed to get OpenSSH version: %v - %s", err, stderr) } - // Trim unused information: https://gogs.io/gogs/issues/4507#issuecomment-305150441 + // Trim unused information: https://github.com/gogs/gogs/issues/4507#issuecomment-305150441 version := strings.TrimRight(strings.Fields(stderr)[0], ",1234567890") version = strings.TrimSuffix(strings.TrimPrefix(version, "OpenSSH_"), "p") return version } -// NewContext initializes configuration context. -// NOTE: do not print any log except error. -func NewContext() { +// Init initializes configuration by loading from sources. +// ⚠️ WARNING: Do not print anything in this function other than wanrings or errors. +func Init() { workDir, err := WorkDir() if err != nil { - log.Fatal(2, "Fail to get work directory: %v", err) + log.Fatal("Failed to get work directory: %v", err) + return } Cfg, err = ini.LoadSources(ini.LoadOptions{ IgnoreInlineComment: true, }, conf.MustAsset("conf/app.ini")) if err != nil { - log.Fatal(2, "Fail to parse 'conf/app.ini': %v", err) + log.Fatal("Failed to parse 'conf/app.ini': %v", err) + return } CustomPath = os.Getenv("GOGS_CUSTOM") @@ -432,16 +438,18 @@ func NewContext() { if com.IsFile(CustomConf) { if err = Cfg.Append(CustomConf); err != nil { - log.Fatal(2, "Fail to load custom conf '%s': %v", CustomConf, err) + log.Fatal("Failed to load custom conf %q: %v", CustomConf, err) + return } } else { - log.Warn("Custom config '%s' not found, ignore this if you're running first time", CustomConf) + log.Warn("Custom config '%s' not found, ignore this warning if you're running the first time", CustomConf) } - Cfg.NameMapper = ini.AllCapsUnderscore + Cfg.NameMapper = ini.SnackCase homeDir, err := com.HomeDir() if err != nil { - log.Fatal(2, "Fail to get home directory: %v", err) + log.Fatal("Failed to get home directory: %v", err) + return } homeDir = strings.Replace(homeDir, "\\", "/", -1) @@ -458,7 +466,8 @@ func NewContext() { // Check if has app suburl. url, err := url.Parse(AppURL) if err != nil { - log.Fatal(2, "Invalid ROOT_URL '%s': %s", AppURL, err) + log.Fatal("Failed to parse ROOT_URL %q: %s", AppURL, err) + return } // Suburl should start with '/' and end without '/', such as '/{subpath}'. // This value is empty if site does not have sub-url. @@ -479,7 +488,8 @@ func NewContext() { UnixSocketPermissionRaw := sec.Key("UNIX_SOCKET_PERMISSION").MustString("666") UnixSocketPermissionParsed, err := strconv.ParseUint(UnixSocketPermissionRaw, 8, 32) if err != nil || UnixSocketPermissionParsed > 0777 { - log.Fatal(2, "Fail to parse unixSocketPermission: %s", UnixSocketPermissionRaw) + log.Fatal("Failed to parse unixSocketPermission %q: %v", UnixSocketPermissionRaw, err) + return } UnixSocketPermission = uint32(UnixSocketPermissionParsed) } @@ -506,7 +516,8 @@ func NewContext() { SSH.ServerCiphers = sec.Key("SSH_SERVER_CIPHERS").Strings(",") SSH.KeyTestPath = os.TempDir() if err = Cfg.Section("server").MapTo(&SSH); err != nil { - log.Fatal(2, "Fail to map SSH settings: %v", err) + log.Fatal("Failed to map SSH settings: %v", err) + return } if SSH.Disabled { SSH.StartBuiltinServer = false @@ -515,9 +526,11 @@ func NewContext() { if !SSH.Disabled && !SSH.StartBuiltinServer { if err := os.MkdirAll(SSH.RootPath, 0700); err != nil { - log.Fatal(2, "Fail to create '%s': %v", SSH.RootPath, err) + log.Fatal("Failed to create '%s': %v", SSH.RootPath, err) + return } else if err = os.MkdirAll(SSH.KeyTestPath, 0644); err != nil { - log.Fatal(2, "Fail to create '%s': %v", SSH.KeyTestPath, err) + log.Fatal("Failed to create '%s': %v", SSH.KeyTestPath, err) + return } } @@ -589,7 +602,8 @@ func NewContext() { if InstallLock { currentUser, match := IsRunUserMatchCurrentUser(RunUser) if !match { - log.Fatal(2, "Expect user '%s' but current user is: %s", RunUser, currentUser) + log.Fatal("The user configured to run Gogs is %q, but the current user is %q", RunUser, currentUser) + return } } @@ -606,11 +620,14 @@ func NewContext() { } ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash") if err = Cfg.Section("repository").MapTo(&Repository); err != nil { - log.Fatal(2, "Fail to map Repository settings: %v", err) + log.Fatal("Failed to map Repository settings: %v", err) + return } else if err = Cfg.Section("repository.editor").MapTo(&Repository.Editor); err != nil { - log.Fatal(2, "Fail to map Repository.Editor settings: %v", err) + log.Fatal("Failed to map Repository.Editor settings: %v", err) + return } else if err = Cfg.Section("repository.upload").MapTo(&Repository.Upload); err != nil { - log.Fatal(2, "Fail to map Repository.Upload settings: %v", err) + log.Fatal("Failed to map Repository.Upload settings: %v", err) + return } if !filepath.IsAbs(Repository.Upload.TempPath) { @@ -663,29 +680,41 @@ func NewContext() { } if err = Cfg.Section("http").MapTo(&HTTP); err != nil { - log.Fatal(2, "Failed to map HTTP settings: %v", err) + log.Fatal("Failed to map HTTP settings: %v", err) + return } else if err = Cfg.Section("webhook").MapTo(&Webhook); err != nil { - log.Fatal(2, "Failed to map Webhook settings: %v", err) + log.Fatal("Failed to map Webhook settings: %v", err) + return } else if err = Cfg.Section("release.attachment").MapTo(&Release.Attachment); err != nil { - log.Fatal(2, "Failed to map Release.Attachment settings: %v", err) + log.Fatal("Failed to map Release.Attachment settings: %v", err) + return } else if err = Cfg.Section("markdown").MapTo(&Markdown); err != nil { - log.Fatal(2, "Failed to map Markdown settings: %v", err) + log.Fatal("Failed to map Markdown settings: %v", err) + return } else if err = Cfg.Section("smartypants").MapTo(&Smartypants); err != nil { - log.Fatal(2, "Failed to map Smartypants settings: %v", err) + log.Fatal("Failed to map Smartypants settings: %v", err) + return } else if err = Cfg.Section("admin").MapTo(&Admin); err != nil { - log.Fatal(2, "Failed to map Admin settings: %v", err) + log.Fatal("Failed to map Admin settings: %v", err) + return } else if err = Cfg.Section("cron").MapTo(&Cron); err != nil { - log.Fatal(2, "Failed to map Cron settings: %v", err) + log.Fatal("Failed to map Cron settings: %v", err) + return } else if err = Cfg.Section("git").MapTo(&Git); err != nil { - log.Fatal(2, "Failed to map Git settings: %v", err) + log.Fatal("Failed to map Git settings: %v", err) + return } else if err = Cfg.Section("mirror").MapTo(&Mirror); err != nil { - log.Fatal(2, "Failed to map Mirror settings: %v", err) + log.Fatal("Failed to map Mirror settings: %v", err) + return } else if err = Cfg.Section("api").MapTo(&API); err != nil { - log.Fatal(2, "Failed to map API settings: %v", err) + log.Fatal("Failed to map API settings: %v", err) + return } else if err = Cfg.Section("ui").MapTo(&UI); err != nil { - log.Fatal(2, "Failed to map UI settings: %v", err) + log.Fatal("Failed to map UI settings: %v", err) + return } else if err = Cfg.Section("prometheus").MapTo(&Prometheus); err != nil { - log.Fatal(2, "Failed to map Prometheus settings: %v", err) + log.Fatal("Failed to map Prometheus settings: %v", err) + return } if Mirror.DefaultInterval <= 0 { @@ -702,123 +731,139 @@ func NewContext() { HasRobotsTxt = com.IsFile(path.Join(CustomPath, "robots.txt")) } -var Service struct { - ActiveCodeLives int - ResetPwdCodeLives int - RegisterEmailConfirm bool - DisableRegistration bool - ShowRegistrationButton bool - RequireSignInView bool - EnableNotifyMail bool - EnableReverseProxyAuth bool - EnableReverseProxyAutoRegister bool - EnableCaptcha bool -} - -func newService() { - sec := Cfg.Section("service") - Service.ActiveCodeLives = sec.Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180) - Service.ResetPwdCodeLives = sec.Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180) - Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool() - Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!Service.DisableRegistration) - Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool() - Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() - Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() - Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool() -} - -func newLogService() { - if len(BuildTime) > 0 { - log.Trace("Build time: %s", BuildTime) - log.Trace("Build commit: %s", BuildCommit) - } - - // Because we always create a console logger as primary logger before all settings are loaded, - // thus if user doesn't set console logger, we should remove it after other loggers are created. +// InitLogging initializes the logging infrastructure of the application. +func InitLogging() { + // Because we always create a console logger as the primary logger at init time, + // we need to remove it in case the user doesn't configure to use it after the + // logging infrastructure is initalized. hasConsole := false - // Get and check log modes. + // Iterate over [log.*] sections to initialize individual logger. LogModes = strings.Split(Cfg.Section("log").Key("MODE").MustString("console"), ",") LogConfigs = make([]interface{}, len(LogModes)) - levelNames := map[string]log.LEVEL{ - "trace": log.TRACE, - "info": log.INFO, - "warn": log.WARN, - "error": log.ERROR, - "fatal": log.FATAL, + levelMappings := map[string]log.Level{ + "trace": log.LevelTrace, + "info": log.LevelInfo, + "warn": log.LevelWarn, + "error": log.LevelError, + "fatal": log.LevelFatal, + } + + type config struct { + Buffer int64 + Config interface{} } for i, mode := range LogModes { mode = strings.ToLower(strings.TrimSpace(mode)) - sec, err := Cfg.GetSection("log." + mode) + secName := "log." + mode + sec, err := Cfg.GetSection(secName) if err != nil { - log.Fatal(2, "Unknown logger mode: %s", mode) + log.Fatal("Missing configuration section [%s] for %q logger", secName, mode) + return } - validLevels := []string{"trace", "info", "warn", "error", "fatal"} - name := Cfg.Section("log." + mode).Key("LEVEL").Validate(func(v string) string { - v = strings.ToLower(v) - if com.IsSliceContainsStr(validLevels, v) { - return v - } - return "trace" - }) - level := levelNames[name] - - // Generate log configuration. - switch log.MODE(mode) { - case log.CONSOLE: + level := levelMappings[sec.Key("LEVEL").MustString("trace")] + buffer := sec.Key("BUFFER_LEN").MustInt64(100) + c := new(config) + switch mode { + case log.DefaultConsoleName: hasConsole = true - LogConfigs[i] = log.ConsoleConfig{ - Level: level, - BufferSize: Cfg.Section("log").Key("BUFFER_LEN").MustInt64(100), + c = &config{ + Buffer: buffer, + Config: log.ConsoleConfig{ + Level: level, + }, } - - case log.FILE: - logPath := path.Join(LogRootPath, "gogs.log") - if err = os.MkdirAll(path.Dir(logPath), os.ModePerm); err != nil { - log.Fatal(2, "Fail to create log directory '%s': %v", path.Dir(logPath), err) + err = log.NewConsole(c.Buffer, c.Config) + + case log.DefaultFileName: + logPath := filepath.Join(LogRootPath, "gogs.log") + logDir := filepath.Dir(logPath) + err = os.MkdirAll(logDir, os.ModePerm) + if err != nil { + log.Fatal("Failed to create log directory %q: %v", logDir, err) + return } - LogConfigs[i] = log.FileConfig{ - Level: level, - BufferSize: Cfg.Section("log").Key("BUFFER_LEN").MustInt64(100), - Filename: logPath, - FileRotationConfig: log.FileRotationConfig{ - Rotate: sec.Key("LOG_ROTATE").MustBool(true), - Daily: sec.Key("DAILY_ROTATE").MustBool(true), - MaxSize: 1 << uint(sec.Key("MAX_SIZE_SHIFT").MustInt(28)), - MaxLines: sec.Key("MAX_LINES").MustInt64(1000000), - MaxDays: sec.Key("MAX_DAYS").MustInt64(7), + c = &config{ + Buffer: buffer, + Config: log.FileConfig{ + Level: level, + Filename: logPath, + FileRotationConfig: log.FileRotationConfig{ + Rotate: sec.Key("LOG_ROTATE").MustBool(true), + Daily: sec.Key("DAILY_ROTATE").MustBool(true), + MaxSize: 1 << uint(sec.Key("MAX_SIZE_SHIFT").MustInt(28)), + MaxLines: sec.Key("MAX_LINES").MustInt64(1000000), + MaxDays: sec.Key("MAX_DAYS").MustInt64(7), + }, }, } - - case log.SLACK: - LogConfigs[i] = log.SlackConfig{ - Level: level, - BufferSize: Cfg.Section("log").Key("BUFFER_LEN").MustInt64(100), - URL: sec.Key("URL").String(), + err = log.NewFile(c.Buffer, c.Config) + + case log.DefaultSlackName: + c = &config{ + Buffer: buffer, + Config: log.SlackConfig{ + Level: level, + URL: sec.Key("URL").String(), + }, } - - case log.DISCORD: - LogConfigs[i] = log.DiscordConfig{ - Level: level, - BufferSize: Cfg.Section("log").Key("BUFFER_LEN").MustInt64(100), - URL: sec.Key("URL").String(), - Username: sec.Key("USERNAME").String(), + err = log.NewSlack(c.Buffer, c.Config) + + case log.DefaultDiscordName: + c = &config{ + Buffer: buffer, + Config: log.DiscordConfig{ + Level: level, + URL: sec.Key("URL").String(), + Username: sec.Key("USERNAME").String(), + }, } + + default: + continue } - log.New(log.MODE(mode), LogConfigs[i]) - log.Trace("Log mode: %s (%s)", strings.Title(mode), strings.Title(name)) + if err != nil { + log.Fatal("Failed to init %s logger: %v", mode, err) + return + } + LogConfigs[i] = c + + log.Trace("Log mode: %s (%s)", strings.Title(mode), strings.Title(strings.ToLower(level.String()))) } - // Make sure everyone gets version info printed. - log.Info("%s %s", AppName, AppVersion) if !hasConsole { - log.Delete(log.CONSOLE) + log.Remove(log.DefaultConsoleName) } } +var Service struct { + ActiveCodeLives int + ResetPwdCodeLives int + RegisterEmailConfirm bool + DisableRegistration bool + ShowRegistrationButton bool + RequireSignInView bool + EnableNotifyMail bool + EnableReverseProxyAuth bool + EnableReverseProxyAutoRegister bool + EnableCaptcha bool +} + +func newService() { + sec := Cfg.Section("service") + Service.ActiveCodeLives = sec.Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180) + Service.ResetPwdCodeLives = sec.Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180) + Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool() + Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!Service.DisableRegistration) + Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool() + Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() + Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() + Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool() +} + func newCacheService() { CacheAdapter = Cfg.Section("cache").Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache"}) switch CacheAdapter { @@ -827,7 +872,8 @@ func newCacheService() { case "redis", "memcache": CacheConn = strings.Trim(Cfg.Section("cache").Key("HOST").String(), "\" ") default: - log.Fatal(2, "Unknown cache adapter: %s", CacheAdapter) + log.Fatal("Unrecognized cache adapter %q", CacheAdapter) + return } log.Trace("Cache service is enabled") @@ -896,7 +942,8 @@ func newMailService() { if len(MailService.From) > 0 { parsed, err := mail.ParseAddress(MailService.From) if err != nil { - log.Fatal(2, "Invalid mailer.FROM (%s): %v", MailService.From, err) + log.Fatal("Failed to parse value %q for '[mailer] FROM': %v", MailService.From, err) + return } MailService.FromEmail = parsed.Address } @@ -941,7 +988,6 @@ func NewService() { func NewServices() { newService() - newLogService() newCacheService() newSessionService() newMailService() |