summaryrefslogtreecommitdiff
path: root/internal/logger/logger.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/logger/logger.go')
-rw-r--r--internal/logger/logger.go105
1 files changed, 29 insertions, 76 deletions
diff --git a/internal/logger/logger.go b/internal/logger/logger.go
index 4d40d24..f836555 100644
--- a/internal/logger/logger.go
+++ b/internal/logger/logger.go
@@ -1,100 +1,53 @@
package logger
import (
- "fmt"
- "io"
"io/ioutil"
- golog "log"
"log/syslog"
- "math"
"os"
- "sync"
- "time"
-
- "gitlab.com/gitlab-org/gitlab-shell/internal/config"
log "github.com/sirupsen/logrus"
+ "gitlab.com/gitlab-org/gitlab-shell/internal/config"
)
-var (
- logWriter io.Writer
- bootstrapLogger *golog.Logger
- pid int
- mutex sync.Mutex
- ProgName string
-)
-
-func Configure(cfg *config.Config) error {
- mutex.Lock()
- defer mutex.Unlock()
-
- pid = os.Getpid()
- ProgName, _ = os.Executable()
-
- // Avoid leaking output if we can't set up the logging output
- log.SetOutput(ioutil.Discard)
-
- output, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
- if err != nil {
- setupBootstrapLogger()
- logPrint("Unable to configure logging", err)
- return err
- }
-
- logWriter = output
- log.SetOutput(logWriter)
+func configureLogFormat(cfg *config.Config) {
if cfg.LogFormat == "json" {
log.SetFormatter(&log.JSONFormatter{})
}
-
- return nil
}
-// 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 attempts to log to syslog.
-func logPrint(msg string, err error) {
- if logWriter == nil {
- if bootstrapLogger != nil {
- bootstrapLogger.Print(ProgName+":", msg+":", err)
- }
- return
- }
+// Configure configures the logging singleton for operation inside a remote TTY (like SSH). In this
+// mode an empty LogFile is not accepted and syslog is used as a fallback when LogFile could not be
+// opened for writing.
+func Configure(cfg *config.Config) {
+ logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
+ if err != nil {
+ progName, _ := os.Executable()
+ syslogLogger, err := syslog.NewLogger(syslog.LOG_ERR|syslog.LOG_USER, 0)
+ syslogLogger.Print(progName + ": Unable to configure logging: " + err.Error())
- log.WithError(err).WithFields(log.Fields{
- "pid": pid,
- }).Error(msg)
-}
+ // Discard logs since a log file was specified but couldn't be opened
+ log.SetOutput(ioutil.Discard)
+ }
-func Fatal(msg string, err error) {
- mutex.Lock()
- defer mutex.Unlock()
- setupBootstrapLogger()
+ log.SetOutput(logFile)
- 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)
+ configureLogFormat(cfg)
}
-// We assume the logging mutex is already locked.
-func setupBootstrapLogger() {
- if bootstrapLogger == nil {
- bootstrapLogger, _ = syslog.NewLogger(syslog.LOG_ERR|syslog.LOG_USER, 0)
+// ConfigureStandalone configures the logging singleton for standalone operation. In this mode an
+// empty LogFile is treated as logging to standard output and standard output is used as a fallback
+// when LogFile could not be opened for writing.
+func ConfigureStandalone(cfg *config.Config) {
+ if cfg.LogFile == "" {
+ return
}
-}
-func ElapsedTimeMs(start time.Time, end time.Time) float64 {
- // Later versions of Go support Milliseconds directly:
- // https://go-review.googlesource.com/c/go/+/167387/
- return roundFloat(end.Sub(start).Seconds() * 1e3)
-}
-
-func roundFloat(x float64) float64 {
- return round(x, 1000)
-}
+ logFile, err := os.OpenFile(cfg.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
+ if err != nil {
+ log.Printf("Unable to configure logging, falling back to stdout: %v", err)
+ return
+ }
+ log.SetOutput(logFile)
-func round(x, unit float64) float64 {
- return math.Round(x*unit) / unit
+ configureLogFormat(cfg)
}