Mercurial > gemma
view pkg/log/log.go @ 5637:7f9600ab5461
merge
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Wed, 14 Jun 2023 08:45:11 +0200 |
parents | 1222b777f51f |
children | 2dd155cc95ec |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2021 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package log import ( "fmt" lg "log" "os" "strings" "sync" "sync/atomic" ) // Level is an enumeration symbolizing a log level. type Level uint32 const ( // TraceLogLevel is the TRACE log level. TraceLogLevel = Level(iota) // DebugLogLevel is the DEBUG log level. DebugLogLevel // InfoLogLevel is the INFO log level. InfoLogLevel // WarnLogLevel is the WARN log level. WarnLogLevel // ErrorLogLevel is the ERROR log level. ErrorLogLevel // FatalLogLevel is the FATAL log level. FatalLogLevel ) var ( logLevel = uint32(InfoLogLevel) logFileMu sync.Mutex logFile *os.File ) func init() { lg.SetFlags(lg.LstdFlags | lg.Lshortfile) } const callDepth = 2 // SetupLog redirects the log output to a given file. // The file is opened in append mode with the given // permisssions. A previously opened log file will // be closed. func SetupLog(filename string, perm os.FileMode) error { f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, perm) if err != nil { return err } logFileMu.Lock() defer logFileMu.Unlock() if logFile != nil { logFile.Close() } logFile = f lg.SetOutput(logFile) return nil } // ShutdownLog closes an open log file (if there is any in use) // and redirects the output to stderr. func ShutdownLog() { logFileMu.Lock() defer logFileMu.Unlock() if logFile != nil { logFile.Close() logFile = nil } lg.SetOutput(os.Stderr) } // ParseLogLevel converts a strings representation // of a log level to the reprective log level. // If the log level is unknown InfoLogLevel is // returned. func ParseLogLevel(s string) Level { switch strings.ToLower(s) { case "trace": return TraceLogLevel case "debug": return DebugLogLevel case "info": return InfoLogLevel case "warn": return WarnLogLevel case "error": return ErrorLogLevel case "fatal": return FatalLogLevel default: return InfoLogLevel } } // String implements the fmt.Stringer interface. func (level Level) String() string { switch level { case TraceLogLevel: return "trace" case DebugLogLevel: return "debug" case InfoLogLevel: return "info" case WarnLogLevel: return "warn" case ErrorLogLevel: return "error" case FatalLogLevel: return "fatal" default: return "unknown" } } // GetLogLevel returns the currently active log level. func GetLogLevel() Level { return Level(atomic.LoadUint32(&logLevel)) } // SetLogLevel sets the log level to be active. func SetLogLevel(level Level) { atomic.StoreUint32(&logLevel, uint32(level)) } // Tracef formats a log message as a TRACE output. func Tracef(f string, args ...interface{}) { if TraceLogLevel >= GetLogLevel() { s := fmt.Sprintf(f, args...) lg.Output(callDepth, "[TRACE] "+s) } } // Traceln line prints a log message as a TRACE output. func Traceln(s string) { if TraceLogLevel >= GetLogLevel() { lg.Output(callDepth, "[TRACE] "+s) } } // Debugf formats a log message as a DEBUG output. func Debugf(f string, args ...interface{}) { if DebugLogLevel >= GetLogLevel() { s := fmt.Sprintf(f, args...) lg.Output(callDepth, "[DEBUG] "+s) } } // Debugln line prints a log message as a DEBUG output. func Debugln(s string) { if DebugLogLevel >= GetLogLevel() { lg.Output(callDepth, "[DEBUG] "+s) } } // Infof formats a log message as a INFO output. func Infof(f string, args ...interface{}) { if InfoLogLevel >= GetLogLevel() { s := fmt.Sprintf(f, args...) lg.Output(callDepth, "[INFO] "+s) } } // Infoln line prints a log message as a INFO output. func Infoln(s string) { if InfoLogLevel >= GetLogLevel() { lg.Output(callDepth, "[INFO] "+s) } } // Warnf formats a log message as a WARN output. func Warnf(f string, args ...interface{}) { if WarnLogLevel >= GetLogLevel() { s := fmt.Sprintf(f, args...) lg.Output(callDepth, "[WARN] "+s) } } // Warnln line prints a log message as a WARN output. func Warnln(s string) { if WarnLogLevel >= GetLogLevel() { lg.Output(callDepth, "[WARN] "+s) } } // Errorf formats a log message as an ERROR output. func Errorf(f string, args ...interface{}) { if ErrorLogLevel >= GetLogLevel() { s := fmt.Sprintf(f, args...) lg.Output(callDepth, "[ERROR] "+s) } } // Errorln line prints a log message as an ERROR output. func Errorln(s string) { if ErrorLogLevel >= GetLogLevel() { lg.Output(callDepth, "[ERROR] "+s) } } // Fatalf formats a log message as a FATAL output // and terminates the programs with an error code (1). func Fatalf(f string, args ...interface{}) { if FatalLogLevel >= GetLogLevel() { s := fmt.Sprintf(f, args...) lg.Output(callDepth, "[FATAL] "+s) os.Exit(1) } } // Fatalln line prints a log message as a FATAL output // and terminates the programs with an error code (1). func Fatalln(s string) { if FatalLogLevel >= GetLogLevel() { lg.Output(callDepth, "[FATAL] "+s) os.Exit(1) } } // Panicf formats a log message as a PANIC output // and throws a panic. func Panicf(f string, args ...interface{}) { s := fmt.Sprintf(f, args...) lg.Output(callDepth, "[PANIC] "+s) panic(s) } // Panicln line prints a log message as a PANIC output // and throws a panic. func Panicln(s string) { lg.Output(callDepth, "[PANIC] "+s) panic(s) }