view pkg/log/log.go @ 5490:5f47eeea988d logging

Use own logging package.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 20 Sep 2021 17:45:39 +0200
parents
children b4f59aef3f9e
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"
)

type LogLevel uint32

const (
	TraceLogLevel = LogLevel(iota)
	DebugLogLevel
	InfoLogLevel
	WarnLogLevel
	ErrorLogLevel
	FatalLogLevel
)

var (
	logLevel  = uint32(InfoLogLevel)
	logFileMu sync.Mutex
	logFile   *os.File
)

func init() {
	lg.SetFlags(lg.LstdFlags | lg.Lshortfile)
}

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
}

func ShutdownLog() {
	logFileMu.Lock()
	defer logFileMu.Unlock()
	if logFile != nil {
		logFile.Close()
		logFile = nil
	}
	lg.SetOutput(os.Stderr)
}

func ParseLogLevel(s string) LogLevel {
	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
	}
}

func (level LogLevel) 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"
	}
}

func GetLogLevel() LogLevel {
	return LogLevel(atomic.LoadUint32(&logLevel))
}

func SetLogLevel(level LogLevel) {
	atomic.StoreUint32(&logLevel, uint32(level))
}

func Tracef(f string, args ...interface{}) {
	if TraceLogLevel >= GetLogLevel() {
		s := fmt.Sprintf(f, args...)
		lg.Output(4, "[TRACE] "+s)
	}
}

func Traceln(s string) {
	if TraceLogLevel >= GetLogLevel() {
		lg.Output(4, "[TRACE] "+s)
	}
}

func Debugf(f string, args ...interface{}) {
	if DebugLogLevel >= GetLogLevel() {
		s := fmt.Sprintf(f, args...)
		lg.Output(4, "[DEBUG] "+s)
	}
}

func Debugln(s string) {
	if DebugLogLevel >= GetLogLevel() {
		lg.Output(4, "[DEBUG] "+s)
	}
}

func Infof(f string, args ...interface{}) {
	if InfoLogLevel >= GetLogLevel() {
		s := fmt.Sprintf(f, args...)
		lg.Output(4, "[INFO] "+s)
	}
}

func Infoln(s string) {
	if InfoLogLevel >= GetLogLevel() {
		lg.Output(4, "[INFO] "+s)
	}
}

func Warnf(f string, args ...interface{}) {
	if WarnLogLevel >= GetLogLevel() {
		s := fmt.Sprintf(f, args...)
		lg.Output(4, "[WARN] "+s)
	}
}

func Warnln(s string) {
	if WarnLogLevel >= GetLogLevel() {
		lg.Output(4, "[WARN] "+s)
	}
}

func Errorf(f string, args ...interface{}) {
	if ErrorLogLevel >= GetLogLevel() {
		s := fmt.Sprintf(f, args...)
		lg.Output(4, "[ERROR] "+s)
	}
}

func Errorln(s string) {
	if ErrorLogLevel >= GetLogLevel() {
		lg.Output(4, "[ERROR] "+s)
	}
}

func Fatalf(f string, args ...interface{}) {
	if FatalLogLevel >= GetLogLevel() {
		s := fmt.Sprintf(f, args...)
		lg.Output(4, "[FATAL] "+s)
		os.Exit(1)
	}
}

func Fatalln(s string) {
	if FatalLogLevel >= GetLogLevel() {
		lg.Output(4, "[FATAL] "+s)
		os.Exit(1)
	}
}

func Panicf(f string, args ...interface{}) {
	s := fmt.Sprintf(f, args...)
	lg.Output(4, "[PANIC] "+s)
	panic(s)
}

func Panicln(s string) {
	lg.Output(4, "[PANIC] "+s)
	panic(s)
}