aboutsummaryrefslogtreecommitdiff
path: root/internal/setting/setting.go
diff options
context:
space:
mode:
authorᴜɴᴋɴᴡᴏɴ <u@gogs.io>2020-02-20 02:25:02 +0800
committerGitHub <noreply@github.com>2020-02-20 02:25:02 +0800
commit1c09373b4f7dbc68154c817b4ee44bfa3b3f637c (patch)
treeaeec9a80d10f9ef28f0d0b128f8a84bf3cb5bdb1 /internal/setting/setting.go
parent422a20648466f270de195dce3bca04e977bacd13 (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.go318
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()