ADDED:
* logging.Logger objects now are able to return a stdlib *log.Logger.
This commit is contained in:
brent saner 2024-06-19 18:57:26 -04:00
parent ae49f42c0c
commit e5191383a7
Signed by: bts
GPG Key ID: 8C004C2F93481F6B
12 changed files with 198 additions and 0 deletions

View File

@ -12,3 +12,16 @@ const (
// appendFlags are the flags used for testing the file (and opening/writing).
appendFlags int = os.O_APPEND | os.O_CREATE | os.O_WRONLY
)

const PriorityNone logPrio = 0
const (
PriorityEmergency logPrio = 1 << iota
PriorityAlert
PriorityCritical
PriorityError
PriorityWarning
PriorityNotice
PriorityInformational
PriorityDebug
)
const PriorityAll logPrio = PriorityEmergency | PriorityAlert | PriorityCritical | PriorityError | PriorityWarning | PriorityNotice | PriorityInformational | PriorityDebug

View File

@ -220,6 +220,14 @@ func (l *FileLogger) Warning(s string, v ...interface{}) (err error) {
return
}

// ToLogger returns a stdlib log.Logger.
func (l *FileLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {

stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)

return
}

// renderWrite prepares/formats a log message to be written to this FileLogger.
func (l *FileLogger) renderWrite(msg, prio string) {


23
logging/funcs_logprio.go Normal file
View File

@ -0,0 +1,23 @@
package logging

import (
`r00t2.io/goutils/bitmask`
)

// HasFlag provides a wrapper for functionality to the underlying bitmask.MaskBit.
func (l *logPrio) HasFlag(prio logPrio) (hasFlag bool) {

var m *bitmask.MaskBit
var p *bitmask.MaskBit

if l == nil {
return
}

m = bitmask.NewMaskBitExplicit(uint(*l))
p = bitmask.NewMaskBitExplicit(uint(prio))

hasFlag = m.HasFlag(*p)

return
}

View File

@ -0,0 +1,74 @@
package logging

import (
`r00t2.io/goutils/multierr`
)

// Write writes bytes b to the underlying Logger's priority level if the logWriter's priority level(s) match.
func (l *logWriter) Write(b []byte) (n int, err error) {

var s string
var mErr *multierr.MultiError = multierr.NewMultiError(nil)

if b == nil {
return
}

s = string(b)

if l.prio.HasFlag(PriorityEmergency) {
if err = l.backend.Emerg(s); err != nil {
mErr.AddError(err)
err = nil
}
}
if l.prio.HasFlag(PriorityAlert) {
if err = l.backend.Alert(s); err != nil {
mErr.AddError(err)
err = nil
}
}
if l.prio.HasFlag(PriorityCritical) {
if err = l.backend.Crit(s); err != nil {
mErr.AddError(err)
err = nil
}
}
if l.prio.HasFlag(PriorityError) {
if err = l.backend.Err(s); err != nil {
mErr.AddError(err)
err = nil
}
}
if l.prio.HasFlag(PriorityWarning) {
if err = l.backend.Warning(s); err != nil {
mErr.AddError(err)
err = nil
}
}
if l.prio.HasFlag(PriorityNotice) {
if err = l.backend.Notice(s); err != nil {
mErr.AddError(err)
err = nil
}
}
if l.prio.HasFlag(PriorityInformational) {
if err = l.backend.Info(s); err != nil {
mErr.AddError(err)
err = nil
}
}
if l.prio.HasFlag(PriorityDebug) {
if err = l.backend.Debug(s); err != nil {
mErr.AddError(err)
err = nil
}
}

if !mErr.IsEmpty() {
err = mErr
return
}

return
}

View File

@ -3,6 +3,7 @@ package logging
import (
"errors"
"fmt"
`log`
"sync"

"r00t2.io/goutils/multierr"
@ -370,3 +371,11 @@ func (m *MultiLogger) Warning(s string, v ...interface{}) (err error) {

return
}

// ToLogger returns a stdlib log.Logger.
func (m *MultiLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {

stdLibLog = log.New(&logWriter{backend: m, prio: prio}, "", 0)

return
}

View File

@ -1,5 +1,9 @@
package logging

import (
`log`
)

// Setup does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Setup() (err error) {
return
@ -72,3 +76,11 @@ func (l *NullLogger) Notice(s string, v ...interface{}) (err error) {
func (l *NullLogger) Warning(s string, v ...interface{}) (err error) {
return
}

// ToLogger returns a stdlib log.Logger (that doesn't actually write to anything).
func (l *NullLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {

stdLibLog = log.New(&nullWriter{}, "", 0)

return
}

View File

@ -0,0 +1,12 @@
package logging

// nulLWriter writes... nothing. To avoid errors, however, in downstream code it pretends it does (n will *always* == len(b)).
func (nw *nullWriter) Write(b []byte) (n int, err error) {

if b == nil {
return
}
n = len(b)

return
}

View File

@ -244,3 +244,11 @@ func (l *StdLogger) renderWrite(msg, prio string) {

return
}

// ToLogger returns a stdlib log.Logger.
func (l *StdLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {

stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)

return
}

View File

@ -223,3 +223,11 @@ func (l *SystemDLogger) renderWrite(msg string, prio journal.Priority) {

return
}

// ToLogger returns a stdlib log.Logger.
func (l *SystemDLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {

stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)

return
}

View File

@ -266,3 +266,11 @@ func (l *SyslogLogger) Warning(s string, v ...interface{}) (err error) {

return
}

// ToLogger returns a stdlib log.Logger.
func (l *SyslogLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {

stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)

return
}

View File

@ -3,6 +3,7 @@ package logging
import (
"errors"
"fmt"
`log`
"os"
"os/exec"
"syscall"
@ -342,3 +343,11 @@ func (l *WinLogger) Warning(s string, v ...interface{}) (err error) {
return

}

// ToLogger returns a stdlib log.Logger.
func (l *WinLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {

stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)

return
}

View File

@ -3,8 +3,12 @@ package logging
import (
"log"
"os"

`r00t2.io/goutils/bitmask`
)

type logPrio bitmask.MaskBit

/*
Logger is one of the various loggers offered by this module.
*/
@ -23,6 +27,7 @@ type Logger interface {
GetPrefix() (p string, err error)
Setup() (err error)
Shutdown() (err error)
ToLogger(prio logPrio) (stdLibLog *log.Logger)
}

/*
@ -105,3 +110,12 @@ type MultiLogger struct {
*/
Loggers map[string]Logger
}

// logWriter is used as a log.Logger and is returned by <Logger>.ToLogger.
type logWriter struct {
backend Logger
prio logPrio
}

// nullWriter is used as a shortcut by NullLogger.ToLogger.
type nullWriter struct{}