2022-01-05 05:15:38 -05:00
|
|
|
package logging
|
|
|
|
|
|
|
|
import (
|
2022-09-07 06:03:28 -04:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
2022-01-05 05:15:38 -05:00
|
|
|
|
2022-09-07 06:03:28 -04:00
|
|
|
"r00t2.io/goutils/multierr"
|
2022-01-05 05:15:38 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
// Setup sets up/configures a MultiLogger (and all its MultiLogger.Loggers) and prepares it for use.
|
2022-01-16 02:05:42 -05:00
|
|
|
func (m *MultiLogger) Setup() (err error) {
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
2022-01-16 02:05:42 -05:00
|
|
|
var errs *multierr.MultiError = multierr.NewMultiError(nil)
|
2022-01-05 05:15:38 -05:00
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logger Logger, lName string) {
|
2022-01-16 02:05:42 -05:00
|
|
|
var err2 error
|
2022-01-05 05:15:38 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 06:55:29 -05:00
|
|
|
if err2 = logger.Setup(); err2 != nil {
|
|
|
|
errs.AddError(errors.New(fmt.Sprintf("error on Setup for logger %v; follows (may be out of order):", lName)))
|
2022-01-16 02:05:42 -05:00
|
|
|
errs.AddError(err2)
|
|
|
|
err2 = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, logName)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
2022-01-16 02:05:42 -05:00
|
|
|
|
|
|
|
if errs.Count() > 0 {
|
|
|
|
err = errs
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Shutdown cleanly shuts down a MultiLogger (and all its MultiLogger.Loggers).
|
2022-01-16 02:05:42 -05:00
|
|
|
func (m *MultiLogger) Shutdown() (err error) {
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
2022-01-16 02:05:42 -05:00
|
|
|
var errs *multierr.MultiError = multierr.NewMultiError(nil)
|
2022-01-05 05:15:38 -05:00
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logger Logger, lName string) {
|
2022-01-16 02:05:42 -05:00
|
|
|
var err2 error
|
2022-01-05 05:15:38 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 06:55:29 -05:00
|
|
|
if err2 = logger.Shutdown(); err2 != nil {
|
|
|
|
errs.AddError(errors.New(fmt.Sprintf("error on Shutdown for logger %v; follows (may be out of order):", lName)))
|
2022-01-16 02:05:42 -05:00
|
|
|
errs.AddError(err2)
|
|
|
|
err2 = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, logName)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
2022-01-16 02:05:42 -05:00
|
|
|
|
|
|
|
if errs.Count() > 0 {
|
|
|
|
err = errs
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
2022-01-16 02:05:42 -05:00
|
|
|
/*
|
2022-09-07 06:03:28 -04:00
|
|
|
GetPrefix returns the prefix used by this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
err will always be nil; it's there for interface-compat.
|
2022-01-16 02:05:42 -05:00
|
|
|
*/
|
|
|
|
func (m *MultiLogger) GetPrefix() (prefix string, err error) {
|
|
|
|
|
|
|
|
prefix = m.Prefix
|
2022-01-05 05:15:38 -05:00
|
|
|
|
2022-01-16 02:05:42 -05:00
|
|
|
return
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2022-09-07 06:03:28 -04:00
|
|
|
DoDebug sets the debug state of this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
|
2022-01-05 05:15:38 -05:00
|
|
|
|
2022-09-07 06:03:28 -04:00
|
|
|
If you had a logger-specific EnableDebug set, you will need to re-set it to your desired state after running this method.
|
2022-01-05 05:15:38 -05:00
|
|
|
*/
|
2022-01-16 02:05:42 -05:00
|
|
|
func (m *MultiLogger) DoDebug(d bool) (err error) {
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
2022-01-16 02:05:42 -05:00
|
|
|
var errs *multierr.MultiError = multierr.NewMultiError(nil)
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
m.EnableDebug = d
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logger Logger, lName string) {
|
2022-01-16 02:05:42 -05:00
|
|
|
var err2 error
|
2022-01-05 05:15:38 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err2 = l.DoDebug(d); err2 != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
errs.AddError(errors.New(fmt.Sprintf("error on DoDebug for logger %v; follows (may be out of order):", lName)))
|
2022-01-16 02:05:42 -05:00
|
|
|
errs.AddError(err2)
|
|
|
|
err2 = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, logName)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
2022-01-16 02:05:42 -05:00
|
|
|
|
|
|
|
if errs.Count() > 0 {
|
|
|
|
err = errs
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
2022-09-07 06:03:28 -04:00
|
|
|
// GetDebug returns the debug status of this MultiLogger.
|
|
|
|
func (m *MultiLogger) GetDebug() (d bool) {
|
|
|
|
|
|
|
|
d = m.EnableDebug
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-01-05 05:15:38 -05:00
|
|
|
/*
|
2022-09-07 06:03:28 -04:00
|
|
|
SetPrefix sets the prefix for this MultiLogger (and all its MultiLogger.Loggers).
|
2022-01-05 05:15:38 -05:00
|
|
|
|
2022-09-07 06:03:28 -04:00
|
|
|
If you had a logger-specific Prefix set, you will need to re-set it to your desired prefix after running this method.
|
2022-01-05 05:15:38 -05:00
|
|
|
*/
|
2022-01-16 02:05:42 -05:00
|
|
|
func (m *MultiLogger) SetPrefix(prefix string) (err error) {
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
2022-01-16 02:05:42 -05:00
|
|
|
var errs *multierr.MultiError = multierr.NewMultiError(nil)
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
m.Prefix = prefix
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logger Logger, lName string) {
|
2022-01-16 02:05:42 -05:00
|
|
|
var err2 error
|
2022-01-05 05:15:38 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err2 = l.SetPrefix(prefix); err != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
errs.AddError(errors.New(fmt.Sprintf("error on SetPrefix for logger %v; follows (may be out of order):", lName)))
|
2022-01-16 02:05:42 -05:00
|
|
|
errs.AddError(err2)
|
|
|
|
err2 = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, logName)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
2022-01-16 02:05:42 -05:00
|
|
|
|
|
|
|
if errs.Count() > 0 {
|
|
|
|
err = errs
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Alert writes an ALERT-level message to this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
func (m *MultiLogger) Alert(s string, v ...interface{}) (err error) {
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
2022-01-05 16:16:24 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err = logObj.Alert(msg, rplc...); err != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
e.AddError(errors.New(fmt.Sprintf("error on Alert for logger %v; follows (may be out of order):", lName)))
|
2022-01-05 05:15:38 -05:00
|
|
|
e.AddError(err)
|
|
|
|
err = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, s, logName, v...)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2022-01-05 16:36:20 -05:00
|
|
|
if !e.IsEmpty() {
|
|
|
|
err = e
|
|
|
|
}
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Crit writes an CRITICAL-level message to this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
func (m *MultiLogger) Crit(s string, v ...interface{}) (err error) {
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
2022-01-05 16:16:24 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err = logObj.Crit(msg, rplc...); err != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
e.AddError(errors.New(fmt.Sprintf("error on Crit for logger %v; follows (may be out of order):", lName)))
|
2022-01-05 05:15:38 -05:00
|
|
|
e.AddError(err)
|
|
|
|
err = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, s, logName, v...)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2022-01-05 16:36:20 -05:00
|
|
|
if !e.IsEmpty() {
|
|
|
|
err = e
|
|
|
|
}
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Debug writes a DEBUG-level message to this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
func (m *MultiLogger) Debug(s string, v ...interface{}) (err error) {
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
2022-01-05 16:16:24 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err = logObj.Debug(msg, rplc...); err != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
e.AddError(errors.New(fmt.Sprintf("error on Debug for logger %v; follows (may be out of order):", lName)))
|
2022-01-05 05:15:38 -05:00
|
|
|
e.AddError(err)
|
|
|
|
err = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, s, logName, v...)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2022-01-05 16:36:20 -05:00
|
|
|
if !e.IsEmpty() {
|
|
|
|
err = e
|
|
|
|
}
|
2022-01-05 05:15:38 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Emerg writes an EMERGENCY-level message to this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
func (m *MultiLogger) Emerg(s string, v ...interface{}) (err error) {
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
2022-01-05 16:16:24 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err = logObj.Emerg(msg, rplc...); err != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
e.AddError(errors.New(fmt.Sprintf("error on Emerg for logger %v; follows (may be out of order):", lName)))
|
2022-01-05 05:15:38 -05:00
|
|
|
e.AddError(err)
|
|
|
|
err = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, s, logName, v...)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2022-01-05 16:36:20 -05:00
|
|
|
if !e.IsEmpty() {
|
|
|
|
err = e
|
|
|
|
}
|
2022-01-05 05:15:38 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Err writes an ERROR-level message to this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
func (m *MultiLogger) Err(s string, v ...interface{}) (err error) {
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
2022-01-05 16:16:24 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err = logObj.Err(msg, rplc...); err != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
e.AddError(errors.New(fmt.Sprintf("error on Err for logger %v; follows (may be out of order):", lName)))
|
2022-01-05 05:15:38 -05:00
|
|
|
e.AddError(err)
|
|
|
|
err = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, s, logName, v...)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2022-01-05 16:36:20 -05:00
|
|
|
if !e.IsEmpty() {
|
|
|
|
err = e
|
|
|
|
}
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Info writes an INFO-level message to this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
func (m *MultiLogger) Info(s string, v ...interface{}) (err error) {
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
2022-01-05 16:16:24 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err = logObj.Info(msg, rplc...); err != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
e.AddError(errors.New(fmt.Sprintf("error on Info for logger %v; follows (may be out of order):", lName)))
|
2022-01-05 05:15:38 -05:00
|
|
|
e.AddError(err)
|
|
|
|
err = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, s, logName, v...)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2022-01-05 16:36:20 -05:00
|
|
|
if !e.IsEmpty() {
|
|
|
|
err = e
|
|
|
|
}
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Notice writes a NOTICE-level message to this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
func (m *MultiLogger) Notice(s string, v ...interface{}) (err error) {
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
2022-01-05 16:16:24 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err = logObj.Notice(msg, rplc...); err != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
e.AddError(errors.New(fmt.Sprintf("error on Notice for logger %v; follows (may be out of order):", lName)))
|
2022-01-05 05:15:38 -05:00
|
|
|
e.AddError(err)
|
|
|
|
err = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, s, logName, v...)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2022-01-05 16:36:20 -05:00
|
|
|
if !e.IsEmpty() {
|
|
|
|
err = e
|
|
|
|
}
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Warning writes a WARNING/WARN-level message to this MultiLogger (and all its MultiLogger.Loggers).
|
|
|
|
func (m *MultiLogger) Warning(s string, v ...interface{}) (err error) {
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
|
|
|
|
2022-01-16 06:55:29 -05:00
|
|
|
for logName, l := range m.Loggers {
|
2022-01-05 05:15:38 -05:00
|
|
|
wg.Add(1)
|
2022-01-16 06:55:29 -05:00
|
|
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
2022-01-05 16:16:24 -05:00
|
|
|
defer wg.Done()
|
2022-01-16 02:05:42 -05:00
|
|
|
if err = logObj.Warning(msg, rplc...); err != nil {
|
2022-01-16 06:55:29 -05:00
|
|
|
e.AddError(errors.New(fmt.Sprintf("error on Warning for logger %v; follows (may be out of order):", lName)))
|
2022-01-05 05:15:38 -05:00
|
|
|
e.AddError(err)
|
|
|
|
err = nil
|
|
|
|
}
|
2022-01-16 06:55:29 -05:00
|
|
|
}(l, s, logName, v...)
|
2022-01-05 05:15:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2022-01-05 16:36:20 -05:00
|
|
|
if !e.IsEmpty() {
|
|
|
|
err = e
|
|
|
|
}
|
2022-01-05 05:15:38 -05:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|