diff options
Diffstat (limited to 'go/internal/logger/logger.go')
-rw-r--r-- | go/internal/logger/logger.go | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/go/internal/logger/logger.go b/go/internal/logger/logger.go new file mode 100644 index 0000000..6a4f2e3 --- /dev/null +++ b/go/internal/logger/logger.go @@ -0,0 +1,73 @@ +package logger + +import ( + "fmt" + "io" + "log" + "log/syslog" + "os" + "sync" + "time" + + "gitlab.com/gitlab-org/gitlab-shell/go/internal/config" +) + +var ( + logWriter io.Writer + bootstrapLogger *log.Logger + pid int + mutex sync.Mutex + ProgName string +) + +func Configure(cfg *config.Config) error { + mutex.Lock() + defer mutex.Unlock() + + pid = os.Getpid() + + var err error + logWriter, err = os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND, 0) + return err +} + +func logPrint(msg string, err error) { + mutex.Lock() + defer mutex.Unlock() + + if logWriter == nil { + bootstrapLogPrint(msg, err) + return + } + + // Emulate the existing log format of gitlab-shell + t := time.Now().Format("2006-01-02T15:04:05.999999") + prefix := fmt.Sprintf("E, [%s #%d] ERROR -- : %s:", t, pid, ProgName) + fmt.Fprintf(logWriter, "%s %s: %v\n", prefix, msg, err) +} + +func Fatal(msg string, err error) { + logPrint(msg, err) + // We don't show the error to the end user because it can leak + // information that is private to the GitLab server. + fmt.Fprintf(os.Stderr, "%s: fatal: %s\n", ProgName, msg) + os.Exit(1) +} + +// If our log file is not available we want to log somewhere else, but +// not to standard error because that leaks information to the user. This +// function attemps to log to syslog. +// +// We assume the logging mutex is already locked. +func bootstrapLogPrint(msg string, err error) { + if bootstrapLogger == nil { + var err error + bootstrapLogger, err = syslog.NewLogger(syslog.LOG_ERR|syslog.LOG_USER, 0) + if err != nil { + // The message will not be logged. + return + } + } + + bootstrapLogger.Print(ProgName+":", msg+":", err) +} |