summary history files

internal/logwrap/logwrap.go
// Package logwrap is a wrapper around stdlib log that provides log levels.
//
// Copied from https://codereview.stackexchange.com/questions/272990/go-logging-wrapper-that-adds-log-levels
//
package logwrap

import (
	"fmt"
	"io"
	"log"
	"path/filepath"
	"runtime"
	"sync"
)

const (
	// DEBUG for debugging.
	DEBUG = 0
	// INFO for info messages.
	INFO = 10
	// WARNING for warning messages.
	WARNING = 20
	// ERROR for error messages.
	ERROR = 30
	// NONE for no messages.
	NONE = 100
)

var (
	pkgLock sync.Mutex
	allLogs = make(map[string]*LogWrap)
)

// LogWrap is a struct.
type LogWrap struct {
	name         string
	level        int
	debugLogWrap *log.Logger
	infoLogWrap  *log.Logger
	logfileinfo  bool
	lock         sync.Mutex
}

// New is the constructor for logger.
func New(name string, dest io.Writer, logfileinfo bool, flags ...int) *LogWrap {
	pkgLock.Lock()
	defer pkgLock.Unlock()
	if _, exists := allLogs[name]; exists {
		panic(fmt.Sprintf("Unable to create logger with %s: name already in use", name))
	}

	var logFlags int
	if flags == nil {
		logFlags = log.Ldate | log.Ltime | log.Lmsgprefix
	} else {
		logFlags = flags[0]
	}

	logger := &LogWrap{
		name:         name,
		debugLogWrap: log.New(dest, "DEBUG: ", logFlags),
		infoLogWrap:  log.New(dest, "INFO: ", logFlags),
	}

	allLogs[name] = logger
	return logger
}

// getfileinfo gets the calling filename and line number.
func getfileinfo() string {
	_, filename, line, ok := runtime.Caller(2)
	if !ok {
		filename = "Unknown"
		line = 0
	}
	return fmt.Sprintf("%s:%d: ", filepath.Base(filename), line)
}

// SetLevel sets the log level for the respective LogWrap. Each level is an int
// that can be set via pkg consts (eg; logger.DEBUG) or via literal ints.
// Messages sent to LogWraps with a log level lower than the current level are
// not written.
func (l *LogWrap) SetLevel(level int) {
	l.lock.Lock()
	defer l.lock.Unlock()
	l.level = level
}

// Info prints info messages.
func (l *LogWrap) Info(msg string) {
	l.lock.Lock()
	defer l.lock.Unlock()
	if l.level > INFO {
		return
	}
	if l.logfileinfo {
		msg = getfileinfo() + msg
	}
	l.infoLogWrap.Println(msg)
}

// Debug prints debug messages.
func (l *LogWrap) Debug(msg string) {
	l.lock.Lock()
	defer l.lock.Unlock()
	if l.level > DEBUG {
		return
	}
	if l.logfileinfo {
		msg = getfileinfo() + msg
	}
	l.infoLogWrap.Println(msg)
}

// Get returns a reference to an existing LogWrap if one exists, othewise nil.
func Get(name string) *LogWrap {
	pkgLock.Lock()
	defer pkgLock.Unlock()
	if foundLog, ok := allLogs[name]; ok {
		return foundLog
	}
	return nil
}