Finalizing for 1.2.0
This commit is contained in:
parent
39e0a1fd43
commit
d98363c0d7
1
.gitignore
vendored
1
.gitignore
vendored
@ -31,6 +31,7 @@
|
|||||||
# But DO include the actual tests.
|
# But DO include the actual tests.
|
||||||
!_test.go
|
!_test.go
|
||||||
!*_test.go
|
!*_test.go
|
||||||
|
!*_test_*.go
|
||||||
!*_test/
|
!*_test/
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
- Implement code line/func/etc. (only for debug?):
|
- Implement code line/func/etc. (only for debug?):
|
||||||
https://stackoverflow.com/a/24809646
|
https://stackoverflow.com/a/24809646
|
||||||
https://golang.org/pkg/runtime/#Caller
|
https://golang.org/pkg/runtime/#Caller
|
||||||
|
-- log.LlongFile and log.Lshortfile flags don't currently work properly for StdLogger/FileLogger; they refer to the file in logging package rather than the caller.
|
||||||
|
|
||||||
- Suport remote loggers? (eventlog, syslog, systemd)
|
- Suport remote loggers? (eventlog, syslog, systemd)
|
||||||
|
|
||||||
|
- JSON logger? YAML logger? XML logger?
|
||||||
|
|
||||||
- DOCS.
|
- DOCS.
|
||||||
-- Done, but flesh out.
|
-- Done, but flesh out.
|
||||||
|
|
||||||
- Unit/Integration tests.
|
|
||||||
|
39
logging/consts_test.go
Normal file
39
logging/consts_test.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
`log`
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following are strings written to the Logger in the various tests.
|
||||||
|
The %v is populated with the name of the type of Logger.
|
||||||
|
*/
|
||||||
|
const (
|
||||||
|
testAlert string = "This is a test ALERT-priority log message for logger %v."
|
||||||
|
testCrit string = "This is a test CRITICAL-priority (CRIT) log message for logger %v."
|
||||||
|
testDebug string = "This is a test DEBUG-priority log message for logger %v."
|
||||||
|
testEmerg string = "This is a test EMERGENCY-priority (EMERG) log message for logger %v."
|
||||||
|
testErr string = "This is a test ERROR-priority (ERR) log message for logger %v."
|
||||||
|
testInfo string = "This is a test INFO-priority log message for logger %v."
|
||||||
|
testNotice string = "This is a test NOTICE-priority log message for logger %v."
|
||||||
|
testWarning string = "This is a test WARNING-priority log message for logger %v."
|
||||||
|
)
|
||||||
|
|
||||||
|
// Prefixes to use for tests.
|
||||||
|
const (
|
||||||
|
// TestLogPrefix is used as the initial prefix.
|
||||||
|
TestLogPrefix string = "LOGGING_TESTRUN"
|
||||||
|
// TestLogAltPrefix is used as the alternative prefix to Logger.SetPrefix.
|
||||||
|
TestLogAltPrefix string = "LOGGING_TESTRUN_ALT"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// EnvVarKeepLog is the env var key/var name to use to suppress removal of FileLogger.Path after tests complete.
|
||||||
|
EnvVarKeepLog string = "LOGGING_KEEP_TEMPLOG"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// logFlags are used to set the log flags for StdLogger (and FileLogger.StdLogger).
|
||||||
|
// logFlags int = log.Ldate | log.Lmicroseconds | log.Llongfile | log.LUTC
|
||||||
|
logFlags int = log.Ldate | log.Lmicroseconds | log.Lshortfile | log.LUTC
|
||||||
|
)
|
@ -55,7 +55,7 @@ var DefaultEventID *WinEventID = &WinEventID{
|
|||||||
Warning: EventWarning,
|
Warning: EventWarning,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default Event IDs for WinEventID.
|
// Default Event IDs for WinEventID (DefaultEventID, specifically).
|
||||||
const (
|
const (
|
||||||
EventAlert uint32 = 1 << iota
|
EventAlert uint32 = 1 << iota
|
||||||
EventCrit
|
EventCrit
|
||||||
|
@ -35,11 +35,11 @@ Note that in the case of a MultiLogger, err (if not nil) will be a (r00t2.io/gou
|
|||||||
|
|
||||||
logging.Logger types also have the following methods:
|
logging.Logger types also have the following methods:
|
||||||
|
|
||||||
DoDebug(d bool)
|
DoDebug(d bool) (err error)
|
||||||
SetPrefix(p string)
|
SetPrefix(p string) (err error)
|
||||||
GetPrefix() (p string)
|
GetPrefix() (p string, err error)
|
||||||
Setup()
|
Setup() (err error)
|
||||||
Shutdown()
|
Shutdown() (err error)
|
||||||
|
|
||||||
In some cases, Logger.Setup and Logger.Shutdown are no-ops. In other cases, they perform necessary initialization/cleanup and closing of the logger.
|
In some cases, Logger.Setup and Logger.Shutdown are no-ops. In other cases, they perform necessary initialization/cleanup and closing of the logger.
|
||||||
It is recommended to *always* run Setup and Shutdown before and after using, respectively, regardless of the actual logging.Logger type.
|
It is recommended to *always* run Setup and Shutdown before and after using, respectively, regardless of the actual logging.Logger type.
|
||||||
|
@ -6,7 +6,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// ErrBadBinPath is returned if installing a binary-registered Event Log source instead of using EventCreate.exe.
|
||||||
ErrBadBinPath error = errors.New("evaluated binary path does not actually exist")
|
ErrBadBinPath error = errors.New("evaluated binary path does not actually exist")
|
||||||
ErrBadPerms error = errors.New("access denied when attempting to register Event Log source")
|
// ErrBadPerms is returned if an access denied error is received when attempting to register, write to, close, etc. a source without proper perms.
|
||||||
ErrBadEid error = errors.New(fmt.Sprintf("event IDs must be between %v and %v inclusive", EIDMin, EIDMax))
|
ErrBadPerms error = errors.New("access denied when attempting to register Event Log source")
|
||||||
|
// ErrBadEid is returned if an event ID is within an invalid range.
|
||||||
|
ErrBadEid error = errors.New(fmt.Sprintf("event IDs must be between %v and %v inclusive", EIDMin, EIDMax))
|
||||||
)
|
)
|
||||||
|
@ -6,13 +6,16 @@ import (
|
|||||||
|
|
||||||
// testOpen attempts to open a file for writing to test for suitability as a LogFile path.
|
// testOpen attempts to open a file for writing to test for suitability as a LogFile path.
|
||||||
func testOpen(path string) (success bool, err error) {
|
func testOpen(path string) (success bool, err error) {
|
||||||
|
|
||||||
var f *os.File
|
var f *os.File
|
||||||
|
|
||||||
// Example #2, https://golang.org/pkg/os/#OpenFile
|
// Example #2, https://golang.org/pkg/os/#OpenFile
|
||||||
if f, err = os.OpenFile(path, appendFlags, logPerm); err != nil {
|
if f, err = os.OpenFile(path, appendFlags, logPerm); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer f.Close()
|
if err = f.Close(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
success = true
|
success = true
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package logging
|
|||||||
import (
|
import (
|
||||||
`errors`
|
`errors`
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
`io/fs`
|
`io/fs`
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@ -13,8 +12,6 @@ import (
|
|||||||
// Setup sets up/configures a FileLogger and prepares it for use.
|
// Setup sets up/configures a FileLogger and prepares it for use.
|
||||||
func (l *FileLogger) Setup() (err error) {
|
func (l *FileLogger) Setup() (err error) {
|
||||||
|
|
||||||
var multi io.Writer
|
|
||||||
|
|
||||||
// This uses a shared handle across the import. We don't want that.
|
// This uses a shared handle across the import. We don't want that.
|
||||||
// l.Logger = log.Default()
|
// l.Logger = log.Default()
|
||||||
if l.Prefix != "" {
|
if l.Prefix != "" {
|
||||||
@ -25,19 +22,7 @@ func (l *FileLogger) Setup() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/36719588/733214
|
l.Logger = log.New(l.writer, l.Prefix, l.LogFlags)
|
||||||
switch {
|
|
||||||
case l.EnableStdErr && l.EnableStdOut:
|
|
||||||
multi = io.MultiWriter(os.Stdout, os.Stderr, l.writer)
|
|
||||||
case l.EnableStdErr:
|
|
||||||
multi = io.MultiWriter(os.Stderr, l.writer)
|
|
||||||
case l.EnableStdOut:
|
|
||||||
multi = io.MultiWriter(os.Stdout, l.writer)
|
|
||||||
default:
|
|
||||||
multi = l.writer
|
|
||||||
}
|
|
||||||
|
|
||||||
l.Logger = log.New(multi, l.Prefix, l.LogFlags)
|
|
||||||
// l.Logger.SetOutput(multi)
|
// l.Logger.SetOutput(multi)
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -50,6 +35,8 @@ func (l *FileLogger) Shutdown() (err error) {
|
|||||||
if !errors.Is(err, fs.ErrClosed) {
|
if !errors.Is(err, fs.ErrClosed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
err = nil
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
270
logging/funcs_linux_test.go
Normal file
270
logging/funcs_linux_test.go
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
`fmt`
|
||||||
|
`os`
|
||||||
|
`testing`
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestSysDLogger tests functionality for SystemDLogger.
|
||||||
|
*/
|
||||||
|
func TestSysDLogger(t *testing.T) {
|
||||||
|
|
||||||
|
var l *SystemDLogger
|
||||||
|
var ltype string = "SystemDLogger"
|
||||||
|
var prefix string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
l = &SystemDLogger{
|
||||||
|
EnableDebug: true,
|
||||||
|
Prefix: TestLogPrefix,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Setup(); err != nil {
|
||||||
|
t.Fatalf("error when running Setup: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed Setup. Logger: %#v", ltype, l)
|
||||||
|
|
||||||
|
if err = l.Alert(testAlert, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Crit(testCrit, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Crit: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Debug(testDebug, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Debug: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Emerg(testEmerg, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Emerg: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Err(testErr, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Err: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Info(testInfo, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Notice(testNotice, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Notice: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Warning(testWarning, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Warning: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix, err = l.GetPrefix(); err != nil {
|
||||||
|
t.Fatalf("error when fetching prefix: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix != TestLogPrefix {
|
||||||
|
t.Fatalf("true prefix ('%v') does not match TestLogPrefix ('%v')", prefix, TestLogPrefix)
|
||||||
|
}
|
||||||
|
if err = l.SetPrefix(TestLogAltPrefix); err != nil {
|
||||||
|
t.Fatalf("error when setting prefix to %v: %v", TestLogAltPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.SetPrefix(TestLogPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.DoDebug(false); err != nil {
|
||||||
|
t.Fatalf("error when changing debug to false: %v", err.Error())
|
||||||
|
} else if l.EnableDebug {
|
||||||
|
t.Fatalf("did not properly set Debug filter state")
|
||||||
|
} else {
|
||||||
|
_ = l.DoDebug(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Shutdown(); err != nil {
|
||||||
|
t.Fatalf("Error when running Shutdown: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed all logging targets.", ltype)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestSyslogLogger tests functionality for SyslogLogger.
|
||||||
|
*/
|
||||||
|
func TestSyslogLogger(t *testing.T) {
|
||||||
|
|
||||||
|
var l *SyslogLogger
|
||||||
|
var ltype string = "SyslogLogger"
|
||||||
|
var prefix string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
l = &SyslogLogger{
|
||||||
|
EnableDebug: true,
|
||||||
|
Prefix: TestLogPrefix,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Setup(); err != nil {
|
||||||
|
t.Fatalf("error when running Setup: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed Setup. Logger: %#v", ltype, l)
|
||||||
|
|
||||||
|
if err = l.Alert(testAlert, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Crit(testCrit, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Crit: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Debug(testDebug, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Debug: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Emerg(testEmerg, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Emerg: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Err(testErr, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Err: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Info(testInfo, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Notice(testNotice, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Notice: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Warning(testWarning, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Warning: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix, err = l.GetPrefix(); err != nil {
|
||||||
|
t.Fatalf("error when fetching prefix: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix != TestLogPrefix {
|
||||||
|
t.Fatalf("true prefix ('%v') does not match TestLogPrefix ('%v')", prefix, TestLogPrefix)
|
||||||
|
}
|
||||||
|
if err = l.SetPrefix(TestLogAltPrefix); err != nil {
|
||||||
|
t.Fatalf("error when setting prefix to %v: %v", TestLogAltPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.SetPrefix(TestLogPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.DoDebug(false); err != nil {
|
||||||
|
t.Fatalf("error when changing debug to false: %v", err.Error())
|
||||||
|
} else if l.EnableDebug {
|
||||||
|
t.Fatalf("did not properly set Debug filter state")
|
||||||
|
} else {
|
||||||
|
_ = l.DoDebug(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Shutdown(); err != nil {
|
||||||
|
t.Fatalf("Error when running Shutdown: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed all logging targets.", ltype)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDefaultLogger tests GetLogger.
|
||||||
|
func TestDefaultLogger(t *testing.T) {
|
||||||
|
|
||||||
|
var l Logger
|
||||||
|
var tempfile *os.File
|
||||||
|
var tempfilePath string
|
||||||
|
var keepLog bool
|
||||||
|
var ltype string
|
||||||
|
var prefix string
|
||||||
|
var testPrefix string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if tempfile, err = os.CreateTemp("", ".LOGGINGTEST_*"); err != nil {
|
||||||
|
t.Fatalf("error when creating temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
tempfilePath = tempfile.Name()
|
||||||
|
// We can close the handler immediately; we don't need it since the FileLogger opens its own.
|
||||||
|
if err = tempfile.Close(); err != nil {
|
||||||
|
t.Fatalf("error when closing handler for temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if l, err = GetLogger(true, TestLogPrefix, logFlags, tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when spawning default Linux logger via GetLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
ltype = fmt.Sprintf("%T", l)
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed Setup. Logger: %#v", ltype, l)
|
||||||
|
|
||||||
|
if err = l.Alert(testAlert, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Crit(testCrit, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Crit: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Debug(testDebug, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Debug: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Emerg(testEmerg, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Emerg: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Err(testErr, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Err: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Info(testInfo, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Notice(testNotice, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Notice: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Warning(testWarning, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Warning: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix, err = l.GetPrefix(); err != nil {
|
||||||
|
t.Fatalf("error when fetching prefix: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if ltype == "StdLogger" || ltype == "FileLogger" { // StdLogger (and thus FileLogger) adds a space at the end.
|
||||||
|
testPrefix = TestLogPrefix + " "
|
||||||
|
} else {
|
||||||
|
testPrefix = TestLogPrefix
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix != testPrefix {
|
||||||
|
t.Fatalf("true prefix ('%v') does not match TestLogPrefix ('%v')", prefix, TestLogPrefix)
|
||||||
|
}
|
||||||
|
if err = l.SetPrefix(TestLogAltPrefix); err != nil {
|
||||||
|
t.Fatalf("error when setting prefix to %v: %v", TestLogAltPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.SetPrefix(TestLogPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.DoDebug(false); err != nil {
|
||||||
|
t.Fatalf("error when changing debug to false: %v", err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.DoDebug(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Shutdown(); err != nil {
|
||||||
|
t.Fatalf("Error when running Shutdown: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, keepLog = os.LookupEnv(EnvVarKeepLog)
|
||||||
|
|
||||||
|
if !keepLog {
|
||||||
|
if err = os.Remove(tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when removing temporary log file '%v': %v", tempfilePath, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed all logging targets.", ltype)
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
`errors`
|
||||||
|
`fmt`
|
||||||
`sync`
|
`sync`
|
||||||
|
|
||||||
`r00t2.io/goutils/multierr`
|
`r00t2.io/goutils/multierr`
|
||||||
@ -12,16 +14,17 @@ func (m *MultiLogger) Setup() (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var errs *multierr.MultiError = multierr.NewMultiError(nil)
|
var errs *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func(logger Logger, lName string) {
|
||||||
var err2 error
|
var err2 error
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err2 = l.Setup(); err2 != nil {
|
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)))
|
||||||
errs.AddError(err2)
|
errs.AddError(err2)
|
||||||
err2 = nil
|
err2 = nil
|
||||||
}
|
}
|
||||||
}()
|
}(l, logName)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -40,16 +43,17 @@ func (m *MultiLogger) Shutdown() (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var errs *multierr.MultiError = multierr.NewMultiError(nil)
|
var errs *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func(logger Logger, lName string) {
|
||||||
var err2 error
|
var err2 error
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err2 = l.Shutdown(); err2 != nil {
|
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)))
|
||||||
errs.AddError(err2)
|
errs.AddError(err2)
|
||||||
err2 = nil
|
err2 = nil
|
||||||
}
|
}
|
||||||
}()
|
}(l, logName)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -87,16 +91,17 @@ func (m *MultiLogger) DoDebug(d bool) (err error) {
|
|||||||
|
|
||||||
m.EnableDebug = d
|
m.EnableDebug = d
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func(logger Logger, lName string) {
|
||||||
var err2 error
|
var err2 error
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err2 = l.DoDebug(d); err2 != nil {
|
if err2 = l.DoDebug(d); err2 != nil {
|
||||||
|
errs.AddError(errors.New(fmt.Sprintf("error on DoDebug for logger %v; follows (may be out of order):", lName)))
|
||||||
errs.AddError(err2)
|
errs.AddError(err2)
|
||||||
err2 = nil
|
err2 = nil
|
||||||
}
|
}
|
||||||
}()
|
}(l, logName)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -121,16 +126,17 @@ func (m *MultiLogger) SetPrefix(prefix string) (err error) {
|
|||||||
|
|
||||||
m.Prefix = prefix
|
m.Prefix = prefix
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func(logger Logger, lName string) {
|
||||||
var err2 error
|
var err2 error
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err2 = l.SetPrefix(prefix); err != nil {
|
if err2 = l.SetPrefix(prefix); err != nil {
|
||||||
|
errs.AddError(errors.New(fmt.Sprintf("error on SetPrefix for logger %v; follows (may be out of order):", lName)))
|
||||||
errs.AddError(err2)
|
errs.AddError(err2)
|
||||||
err2 = nil
|
err2 = nil
|
||||||
}
|
}
|
||||||
}()
|
}(l, logName)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -149,15 +155,16 @@ func (m *MultiLogger) Alert(s string, v ...interface{}) (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(logObj Logger, msg string, rplc ...interface{}) {
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err = logObj.Alert(msg, rplc...); err != nil {
|
if err = logObj.Alert(msg, rplc...); err != nil {
|
||||||
|
e.AddError(errors.New(fmt.Sprintf("error on Alert for logger %v; follows (may be out of order):", lName)))
|
||||||
e.AddError(err)
|
e.AddError(err)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}(l, s, v...)
|
}(l, s, logName, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -175,15 +182,16 @@ func (m *MultiLogger) Crit(s string, v ...interface{}) (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(logObj Logger, msg string, rplc ...interface{}) {
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err = logObj.Crit(msg, rplc...); err != nil {
|
if err = logObj.Crit(msg, rplc...); err != nil {
|
||||||
|
e.AddError(errors.New(fmt.Sprintf("error on Crit for logger %v; follows (may be out of order):", lName)))
|
||||||
e.AddError(err)
|
e.AddError(err)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}(l, s, v...)
|
}(l, s, logName, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -201,15 +209,16 @@ func (m *MultiLogger) Debug(s string, v ...interface{}) (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(logObj Logger, msg string, rplc ...interface{}) {
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err = logObj.Debug(msg, rplc...); err != nil {
|
if err = logObj.Debug(msg, rplc...); err != nil {
|
||||||
|
e.AddError(errors.New(fmt.Sprintf("error on Debug for logger %v; follows (may be out of order):", lName)))
|
||||||
e.AddError(err)
|
e.AddError(err)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}(l, s, v...)
|
}(l, s, logName, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -226,15 +235,16 @@ func (m *MultiLogger) Emerg(s string, v ...interface{}) (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(logObj Logger, msg string, rplc ...interface{}) {
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err = logObj.Emerg(msg, rplc...); err != nil {
|
if err = logObj.Emerg(msg, rplc...); err != nil {
|
||||||
|
e.AddError(errors.New(fmt.Sprintf("error on Emerg for logger %v; follows (may be out of order):", lName)))
|
||||||
e.AddError(err)
|
e.AddError(err)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}(l, s, v...)
|
}(l, s, logName, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -251,15 +261,16 @@ func (m *MultiLogger) Err(s string, v ...interface{}) (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(logObj Logger, msg string, rplc ...interface{}) {
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err = logObj.Err(msg, rplc...); err != nil {
|
if err = logObj.Err(msg, rplc...); err != nil {
|
||||||
|
e.AddError(errors.New(fmt.Sprintf("error on Err for logger %v; follows (may be out of order):", lName)))
|
||||||
e.AddError(err)
|
e.AddError(err)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}(l, s, v...)
|
}(l, s, logName, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -277,15 +288,16 @@ func (m *MultiLogger) Info(s string, v ...interface{}) (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(logObj Logger, msg string, rplc ...interface{}) {
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err = logObj.Info(msg, rplc...); err != nil {
|
if err = logObj.Info(msg, rplc...); err != nil {
|
||||||
|
e.AddError(errors.New(fmt.Sprintf("error on Info for logger %v; follows (may be out of order):", lName)))
|
||||||
e.AddError(err)
|
e.AddError(err)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}(l, s, v...)
|
}(l, s, logName, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -303,15 +315,16 @@ func (m *MultiLogger) Notice(s string, v ...interface{}) (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(logObj Logger, msg string, rplc ...interface{}) {
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err = logObj.Notice(msg, rplc...); err != nil {
|
if err = logObj.Notice(msg, rplc...); err != nil {
|
||||||
|
e.AddError(errors.New(fmt.Sprintf("error on Notice for logger %v; follows (may be out of order):", lName)))
|
||||||
e.AddError(err)
|
e.AddError(err)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}(l, s, v...)
|
}(l, s, logName, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -329,15 +342,16 @@ func (m *MultiLogger) Warning(s string, v ...interface{}) (err error) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
var e *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
for _, l := range m.Loggers {
|
for logName, l := range m.Loggers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(logObj Logger, msg string, rplc ...interface{}) {
|
go func(logObj Logger, msg, lName string, rplc ...interface{}) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err = logObj.Warning(msg, rplc...); err != nil {
|
if err = logObj.Warning(msg, rplc...); err != nil {
|
||||||
|
e.AddError(errors.New(fmt.Sprintf("error on Warning for logger %v; follows (may be out of order):", lName)))
|
||||||
e.AddError(err)
|
e.AddError(err)
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
}(l, s, v...)
|
}(l, s, logName, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
@ -37,9 +37,15 @@ func GetMultiLogger(enableDebug bool, prefix string) (m *MultiLogger) {
|
|||||||
identifier is a string to use to identify the added StdLogger in MultiLogger.Loggers.
|
identifier is a string to use to identify the added StdLogger in MultiLogger.Loggers.
|
||||||
If empty, one will be automatically generated.
|
If empty, one will be automatically generated.
|
||||||
|
|
||||||
|
enableStdOut indicates that messages should be logged to STDOUT;
|
||||||
|
it is *strongly encouraged* to set at least one of enableStdOut or enableStdErr to true.
|
||||||
|
|
||||||
|
enableStdErr indicates that messages should be logged to STDERR;
|
||||||
|
it is *strongly encouraged* to set at least one of enableStdErr or enableStdOut to true.
|
||||||
|
|
||||||
See GetLogger's logConfigFlags argument and StdLogger.LogFlags for details on logFlags.
|
See GetLogger's logConfigFlags argument and StdLogger.LogFlags for details on logFlags.
|
||||||
*/
|
*/
|
||||||
func (m *MultiLogger) AddStdLogger(identifier string, logFlags int) (err error) {
|
func (m *MultiLogger) AddStdLogger(identifier string, enableStdOut, enableStdErr bool, logFlags int) (err error) {
|
||||||
|
|
||||||
var exists bool
|
var exists bool
|
||||||
var prefix string
|
var prefix string
|
||||||
@ -54,10 +60,12 @@ func (m *MultiLogger) AddStdLogger(identifier string, logFlags int) (err error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.Loggers[identifier] = &StdLogger{
|
m.Loggers[identifier] = &StdLogger{
|
||||||
Logger: nil,
|
Logger: nil,
|
||||||
EnableDebug: m.EnableDebug,
|
EnableDebug: m.EnableDebug,
|
||||||
Prefix: m.Prefix,
|
Prefix: m.Prefix,
|
||||||
LogFlags: logFlags,
|
LogFlags: logFlags,
|
||||||
|
EnableStdOut: enableStdOut,
|
||||||
|
EnableStdErr: enableStdErr,
|
||||||
}
|
}
|
||||||
if err = m.Loggers[identifier].Setup(); err != nil {
|
if err = m.Loggers[identifier].Setup(); err != nil {
|
||||||
return
|
return
|
||||||
@ -80,7 +88,7 @@ func (m *MultiLogger) AddStdLogger(identifier string, logFlags int) (err error)
|
|||||||
|
|
||||||
logfilePath is a string for the path to the desired logfile.
|
logfilePath is a string for the path to the desired logfile.
|
||||||
*/
|
*/
|
||||||
func (m *MultiLogger) AddFileLogger(identifier string, enableStdOut, enableStdErr bool, logFlags int, logfilePath string) (err error) {
|
func (m *MultiLogger) AddFileLogger(identifier string, logFlags int, logfilePath string) (err error) {
|
||||||
|
|
||||||
var exists bool
|
var exists bool
|
||||||
var success bool
|
var success bool
|
||||||
@ -122,9 +130,7 @@ func (m *MultiLogger) AddFileLogger(identifier string, enableStdOut, enableStdEr
|
|||||||
Prefix: m.Prefix,
|
Prefix: m.Prefix,
|
||||||
LogFlags: logFlags,
|
LogFlags: logFlags,
|
||||||
},
|
},
|
||||||
Path: logfilePath,
|
Path: logfilePath,
|
||||||
EnableStdOut: enableStdOut,
|
|
||||||
EnableStdErr: enableStdErr,
|
|
||||||
}
|
}
|
||||||
if err = m.Loggers[identifier].Setup(); err != nil {
|
if err = m.Loggers[identifier].Setup(); err != nil {
|
||||||
return
|
return
|
||||||
|
@ -65,7 +65,7 @@ func (m *MultiLogger) AddDefaultLogger(identifier string, eventIDs *WinEventID,
|
|||||||
|
|
||||||
See GetLogger for details.
|
See GetLogger for details.
|
||||||
*/
|
*/
|
||||||
func (m *MultiLogger) AddWinLogger(identifier, source string, eventIDs *WinEventID) (err error) {
|
func (m *MultiLogger) AddWinLogger(identifier string, eventIDs *WinEventID) (err error) {
|
||||||
|
|
||||||
var exists bool
|
var exists bool
|
||||||
var prefix string
|
var prefix string
|
||||||
@ -84,9 +84,9 @@ func (m *MultiLogger) AddWinLogger(identifier, source string, eventIDs *WinEvent
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.Loggers[identifier] = &WinLogger{
|
m.Loggers[identifier] = &WinLogger{
|
||||||
Prefix: source,
|
Prefix: m.Prefix,
|
||||||
EnableDebug: m.EnableDebug,
|
EnableDebug: m.EnableDebug,
|
||||||
eids: eventIDs,
|
EIDs: eventIDs,
|
||||||
}
|
}
|
||||||
if err = m.Loggers[identifier].Setup(); err != nil {
|
if err = m.Loggers[identifier].Setup(); err != nil {
|
||||||
return
|
return
|
||||||
|
@ -2,6 +2,7 @@ package logging
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
`io`
|
||||||
`log`
|
`log`
|
||||||
`os`
|
`os`
|
||||||
`strings`
|
`strings`
|
||||||
@ -13,14 +14,34 @@ import (
|
|||||||
*/
|
*/
|
||||||
func (l *StdLogger) Setup() (err error) {
|
func (l *StdLogger) Setup() (err error) {
|
||||||
|
|
||||||
|
var multi io.Writer
|
||||||
|
|
||||||
// This uses a shared handle across the import. We don't want that.
|
// This uses a shared handle across the import. We don't want that.
|
||||||
// l.Logger = log.Default()
|
// l.Logger = log.Default()
|
||||||
if l.Prefix != "" {
|
if l.Prefix != "" {
|
||||||
l.Prefix = strings.TrimRight(l.Prefix, " ") + " "
|
l.Prefix = strings.TrimRight(l.Prefix, " ") + " "
|
||||||
// l.Logger.SetPrefix(l.Prefix)
|
// l.Logger.SetPrefix(l.Prefix)
|
||||||
}
|
}
|
||||||
// (stdlib).log.std is returned by log.Default(), which uses os.Stderr.
|
// (stdlib).log.std is returned by log.Default(), which uses os.Stderr but we have flags for that.
|
||||||
l.Logger = log.New(os.Stderr, l.Prefix, l.LogFlags)
|
// https://stackoverflow.com/a/36719588/733214
|
||||||
|
switch {
|
||||||
|
case l.EnableStdErr && l.EnableStdOut:
|
||||||
|
multi = io.MultiWriter(os.Stdout, os.Stderr)
|
||||||
|
case l.EnableStdErr:
|
||||||
|
multi = os.Stderr
|
||||||
|
case l.EnableStdOut:
|
||||||
|
multi = os.Stdout
|
||||||
|
default:
|
||||||
|
multi = nil
|
||||||
|
}
|
||||||
|
if multi != nil {
|
||||||
|
l.Logger = log.New(multi, l.Prefix, l.LogFlags)
|
||||||
|
} else {
|
||||||
|
// This honestly should throw an error.
|
||||||
|
l.Logger = &log.Logger{}
|
||||||
|
l.Logger.SetPrefix(l.Prefix)
|
||||||
|
l.Logger.SetFlags(l.LogFlags)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1 +1,196 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
`os`
|
||||||
|
`testing`
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestStdLogger tests functionality for StdLogger.
|
||||||
|
*/
|
||||||
|
func TestStdLogger(t *testing.T) {
|
||||||
|
|
||||||
|
var l *StdLogger
|
||||||
|
var ltype string = "StdLogger"
|
||||||
|
var prefix string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
l = &StdLogger{
|
||||||
|
EnableDebug: true,
|
||||||
|
Prefix: TestLogPrefix,
|
||||||
|
LogFlags: logFlags,
|
||||||
|
EnableStdOut: false,
|
||||||
|
EnableStdErr: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Setup(); err != nil {
|
||||||
|
t.Fatalf("error when running Setup: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed Setup. Logger: %#v", ltype, l)
|
||||||
|
|
||||||
|
if err = l.Alert(testAlert, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Crit(testCrit, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Crit: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Debug(testDebug, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Debug: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Emerg(testEmerg, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Emerg: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Err(testErr, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Err: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Info(testInfo, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Notice(testNotice, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Notice: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Warning(testWarning, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Warning: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix, err = l.GetPrefix(); err != nil {
|
||||||
|
t.Fatalf("error when fetching prefix: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix != (TestLogPrefix + " ") { // StdLogger adds a space at the end.
|
||||||
|
t.Fatalf("true prefix ('%v') does not match TestLogPrefix ('%v')", prefix, TestLogPrefix)
|
||||||
|
}
|
||||||
|
if err = l.SetPrefix(TestLogAltPrefix); err != nil {
|
||||||
|
t.Fatalf("error when setting prefix to %v: %v", TestLogAltPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.SetPrefix(TestLogPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.DoDebug(false); err != nil {
|
||||||
|
t.Fatalf("error when changing debug to false: %v", err.Error())
|
||||||
|
} else if l.EnableDebug {
|
||||||
|
t.Fatalf("did not properly set Debug filter state")
|
||||||
|
} else {
|
||||||
|
_ = l.DoDebug(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Shutdown(); err != nil {
|
||||||
|
t.Fatalf("Error when running Shutdown: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed all logging targets.", ltype)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestFileLogger tests functionality for FileLogger.
|
||||||
|
If the appropriate env var is set (see the EnvVarKeepLog constant), the temporary log file that is created will not be cleaned up.
|
||||||
|
*/
|
||||||
|
func TestFileLogger(t *testing.T) {
|
||||||
|
|
||||||
|
var l *FileLogger
|
||||||
|
var ltype string = "FileLogger"
|
||||||
|
var prefix string
|
||||||
|
var tempfile *os.File
|
||||||
|
var tempfilePath string
|
||||||
|
var keepLog bool
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if tempfile, err = os.CreateTemp("", ".LOGGINGTEST_*"); err != nil {
|
||||||
|
t.Fatalf("error when creating temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
tempfilePath = tempfile.Name()
|
||||||
|
// We can close the handler immediately; we don't need it since the FileLogger opens its own.
|
||||||
|
if err = tempfile.Close(); err != nil {
|
||||||
|
t.Fatalf("error when closing handler for temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
l = &FileLogger{
|
||||||
|
StdLogger: StdLogger{
|
||||||
|
EnableDebug: true,
|
||||||
|
Prefix: TestLogPrefix,
|
||||||
|
LogFlags: logFlags,
|
||||||
|
},
|
||||||
|
Path: tempfilePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Setup(); err != nil {
|
||||||
|
t.Fatalf("error when running Setup: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed Setup. Logger: %#v", ltype, l)
|
||||||
|
|
||||||
|
if err = l.Alert(testAlert, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Crit(testCrit, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Crit: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Debug(testDebug, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Debug: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Emerg(testEmerg, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Emerg: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Err(testErr, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Err: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Info(testInfo, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Notice(testNotice, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Notice: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Warning(testWarning, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Warning: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix, err = l.GetPrefix(); err != nil {
|
||||||
|
t.Fatalf("error when fetching prefix: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix != (TestLogPrefix + " ") { // StdLogger (and thus FileLogger) adds a space at the end.
|
||||||
|
t.Fatalf("true prefix ('%v') does not match TestLogPrefix ('%v')", prefix, TestLogPrefix)
|
||||||
|
}
|
||||||
|
if err = l.SetPrefix(TestLogAltPrefix); err != nil {
|
||||||
|
t.Fatalf("error when setting prefix to %v: %v", TestLogAltPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.SetPrefix(TestLogPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.DoDebug(false); err != nil {
|
||||||
|
t.Fatalf("error when changing debug to false: %v", err.Error())
|
||||||
|
} else if l.EnableDebug {
|
||||||
|
t.Fatalf("did not properly set Debug filter state")
|
||||||
|
} else {
|
||||||
|
_ = l.DoDebug(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Shutdown(); err != nil {
|
||||||
|
t.Fatalf("Error when running Shutdown: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, keepLog = os.LookupEnv(EnvVarKeepLog)
|
||||||
|
|
||||||
|
if !keepLog {
|
||||||
|
if err = os.Remove(tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when removing temporary log file '%v': %v", tempfilePath, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed all logging targets.", ltype)
|
||||||
|
}
|
||||||
|
@ -90,7 +90,7 @@ func GetLogger(enableDebug bool, source string, eventIDs *WinEventID, logConfigF
|
|||||||
logger = &WinLogger{
|
logger = &WinLogger{
|
||||||
Prefix: source,
|
Prefix: source,
|
||||||
EnableDebug: enableDebug,
|
EnableDebug: enableDebug,
|
||||||
eids: eventIDs,
|
EIDs: eventIDs,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if logFlags.HasFlag(LogFile) {
|
if logFlags.HasFlag(LogFile) {
|
||||||
|
205
logging/funcs_windows_test.go
Normal file
205
logging/funcs_windows_test.go
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
`fmt`
|
||||||
|
`os`
|
||||||
|
`testing`
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
TestWinLogger tests functionality for WinLogger.
|
||||||
|
You will probably need to run it with an Administrator shell.
|
||||||
|
*/
|
||||||
|
func TestWinLogger(t *testing.T) {
|
||||||
|
|
||||||
|
var l *WinLogger
|
||||||
|
var ltype string = "WinLogger"
|
||||||
|
var prefix string
|
||||||
|
var exists bool
|
||||||
|
var err error
|
||||||
|
|
||||||
|
l = &WinLogger{
|
||||||
|
EnableDebug: true,
|
||||||
|
Prefix: TestLogPrefix,
|
||||||
|
RemoveOnClose: true,
|
||||||
|
EIDs: DefaultEventID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists, err = l.Exists(); err != nil {
|
||||||
|
t.Fatalf("error when checking for existence of registered Event Log source '%v': %v", TestLogPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
t.Logf("Prefix (source) '%v' exists before setup: %v", TestLogPrefix, exists)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Setup(); err != nil {
|
||||||
|
t.Fatalf("error when running Setup: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists, err = l.Exists(); err != nil {
|
||||||
|
t.Fatalf("error when checking for existence of registered Event Log source '%v': %v", TestLogPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
t.Logf("Prefix (source) '%v' exists after setup: %v", TestLogPrefix, exists)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed Setup. Logger: %#v", ltype, l)
|
||||||
|
|
||||||
|
if err = l.Alert(testAlert, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Crit(testCrit, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Crit: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Debug(testDebug, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Debug: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Emerg(testEmerg, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Emerg: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Err(testErr, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Err: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Info(testInfo, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Notice(testNotice, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Notice: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Warning(testWarning, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Warning: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix, err = l.GetPrefix(); err != nil {
|
||||||
|
t.Fatalf("error when fetching prefix: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix != TestLogPrefix {
|
||||||
|
t.Fatalf("true prefix ('%v') does not match TestLogPrefix ('%v')", prefix, TestLogPrefix)
|
||||||
|
}
|
||||||
|
if err = l.SetPrefix(TestLogAltPrefix); err != nil {
|
||||||
|
t.Fatalf("error when setting prefix to %v: %v", TestLogAltPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.SetPrefix(TestLogPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.DoDebug(false); err != nil {
|
||||||
|
t.Fatalf("error when changing debug to false: %v", err.Error())
|
||||||
|
} else if l.EnableDebug {
|
||||||
|
t.Fatalf("did not properly set Debug filter state")
|
||||||
|
} else {
|
||||||
|
_ = l.DoDebug(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Shutdown(); err != nil {
|
||||||
|
t.Fatalf("Error when running Shutdown: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed all logging targets.", ltype)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDefaultLogger tests GetLogger.
|
||||||
|
func TestDefaultLogger(t *testing.T) {
|
||||||
|
|
||||||
|
var l Logger
|
||||||
|
var tempfile *os.File
|
||||||
|
var tempfilePath string
|
||||||
|
var keepLog bool
|
||||||
|
var ltype string
|
||||||
|
var prefix string
|
||||||
|
var testPrefix string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if tempfile, err = os.CreateTemp("", ".LOGGINGTEST_*"); err != nil {
|
||||||
|
t.Fatalf("error when creating temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
tempfilePath = tempfile.Name()
|
||||||
|
// We can close the handler immediately; we don't need it since the FileLogger opens its own.
|
||||||
|
if err = tempfile.Close(); err != nil {
|
||||||
|
t.Fatalf("error when closing handler for temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if l, err = GetLogger(true, TestLogPrefix, DefaultEventID, logFlags, tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when spawning default Windows logger via GetLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
ltype = fmt.Sprintf("%T", l)
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed Setup. Logger: %#v", ltype, l)
|
||||||
|
|
||||||
|
if err = l.Alert(testAlert, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Crit(testCrit, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Crit: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Debug(testDebug, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Debug: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Emerg(testEmerg, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Emerg: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Err(testErr, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Err: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Info(testInfo, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Notice(testNotice, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Notice: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Warning(testWarning, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Warning: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix, err = l.GetPrefix(); err != nil {
|
||||||
|
t.Fatalf("error when fetching prefix: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if ltype == "StdLogger" || ltype == "FileLogger" { // StdLogger (and thus FileLogger) adds a space at the end.
|
||||||
|
testPrefix = TestLogPrefix + " "
|
||||||
|
} else {
|
||||||
|
testPrefix = TestLogPrefix
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix != testPrefix {
|
||||||
|
t.Fatalf("true prefix ('%v') does not match TestLogPrefix ('%v')", prefix, TestLogPrefix)
|
||||||
|
}
|
||||||
|
if err = l.SetPrefix(TestLogAltPrefix); err != nil {
|
||||||
|
t.Fatalf("error when setting prefix to %v: %v", TestLogAltPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.SetPrefix(TestLogPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.DoDebug(false); err != nil {
|
||||||
|
t.Fatalf("error when changing debug to false: %v", err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.DoDebug(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Shutdown(); err != nil {
|
||||||
|
t.Fatalf("Error when running Shutdown: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, keepLog = os.LookupEnv(EnvVarKeepLog)
|
||||||
|
|
||||||
|
if !keepLog {
|
||||||
|
if err = os.Remove(tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when removing temporary log file '%v': %v", tempfilePath, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed all logging targets.", ltype)
|
||||||
|
}
|
@ -29,14 +29,14 @@ func (l *WinLogger) Setup() (err error) {
|
|||||||
Since we use eventcreate, all Event IDs must be 1 <= eid <= 1000.
|
Since we use eventcreate, all Event IDs must be 1 <= eid <= 1000.
|
||||||
*/
|
*/
|
||||||
for _, eid := range []uint32{
|
for _, eid := range []uint32{
|
||||||
l.eids.Alert,
|
l.EIDs.Alert,
|
||||||
l.eids.Crit,
|
l.EIDs.Crit,
|
||||||
l.eids.Debug,
|
l.EIDs.Debug,
|
||||||
l.eids.Emerg,
|
l.EIDs.Emerg,
|
||||||
l.eids.Err,
|
l.EIDs.Err,
|
||||||
l.eids.Info,
|
l.EIDs.Info,
|
||||||
l.eids.Notice,
|
l.EIDs.Notice,
|
||||||
l.eids.Warning,
|
l.EIDs.Warning,
|
||||||
} {
|
} {
|
||||||
if !((eid <= EIDMax) && (EIDMin <= eid)) {
|
if !((eid <= EIDMax) && (EIDMin <= eid)) {
|
||||||
err = ErrBadEid
|
err = ErrBadEid
|
||||||
@ -204,7 +204,7 @@ func (l *WinLogger) Alert(s string, v ...interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Treat ALERT as Warning
|
// Treat ALERT as Warning
|
||||||
err = l.elog.Warning(l.eids.Alert, msg)
|
err = l.elog.Warning(l.EIDs.Alert, msg)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ func (l *WinLogger) Crit(s string, v ...interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Treat CRIT as Error
|
// Treat CRIT as Error
|
||||||
err = l.elog.Error(l.eids.Crit, msg)
|
err = l.elog.Error(l.EIDs.Crit, msg)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -242,7 +242,7 @@ func (l *WinLogger) Debug(s string, v ...interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Treat DEBUG as Info
|
// Treat DEBUG as Info
|
||||||
err = l.elog.Info(l.eids.Debug, msg)
|
err = l.elog.Info(l.EIDs.Debug, msg)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -260,7 +260,7 @@ func (l *WinLogger) Emerg(s string, v ...interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Treat EMERG as Error
|
// Treat EMERG as Error
|
||||||
err = l.elog.Error(l.eids.Emerg, msg)
|
err = l.elog.Error(l.EIDs.Emerg, msg)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ func (l *WinLogger) Err(s string, v ...interface{}) (err error) {
|
|||||||
msg = s
|
msg = s
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.elog.Error(l.eids.Err, msg)
|
err = l.elog.Error(l.EIDs.Err, msg)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ func (l *WinLogger) Info(s string, v ...interface{}) (err error) {
|
|||||||
msg = s
|
msg = s
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.elog.Info(l.eids.Info, msg)
|
err = l.elog.Info(l.EIDs.Info, msg)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -312,7 +312,7 @@ func (l *WinLogger) Notice(s string, v ...interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Treat NOTICE as Info
|
// Treat NOTICE as Info
|
||||||
err = l.elog.Info(l.eids.Notice, msg)
|
err = l.elog.Info(l.EIDs.Notice, msg)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ func (l *WinLogger) Warning(s string, v ...interface{}) (err error) {
|
|||||||
msg = s
|
msg = s
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.elog.Warning(l.eids.Warning, msg)
|
err = l.elog.Warning(l.EIDs.Warning, msg)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
121
logging/muiltilogger_linux_test.go
Normal file
121
logging/muiltilogger_linux_test.go
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
`os`
|
||||||
|
`testing`
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestMultiLogger tests GetMultiLogger and MultiLogger methods.
|
||||||
|
func TestMultiLogger(t *testing.T) {
|
||||||
|
|
||||||
|
var l *MultiLogger
|
||||||
|
var tempfile *os.File
|
||||||
|
var tempfilePath string
|
||||||
|
var keepLog bool
|
||||||
|
var ltype string = "MultiLogger"
|
||||||
|
var prefix string
|
||||||
|
var testPrefix string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if tempfile, err = os.CreateTemp("", ".LOGGINGTEST_*"); err != nil {
|
||||||
|
t.Fatalf("error when creating temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
tempfilePath = tempfile.Name()
|
||||||
|
// We can close the handler immediately; we don't need it since the FileLogger opens its own.
|
||||||
|
if err = tempfile.Close(); err != nil {
|
||||||
|
t.Fatalf("error when closing handler for temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
l = GetMultiLogger(true, TestLogPrefix)
|
||||||
|
|
||||||
|
if err = l.AddStdLogger("StdLogger", false, true, logFlags); err != nil {
|
||||||
|
t.Fatalf("error when adding StdLogger to MultiLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
if err = l.AddFileLogger("FileLogger", logFlags, tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when adding FileLogger to MultiLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.AddDefaultLogger("DefaultLogger", logFlags, tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when adding default logger to MultiLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.AddSysdLogger("SystemDLogger"); err != nil {
|
||||||
|
t.Fatalf("error when adding SystemDLogger to MultiLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
if err = l.AddSyslogLogger("SyslogLogger"); err != nil {
|
||||||
|
t.Fatalf("error when adding SyslogLogger to MultiLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed Setup. Logger: %#v", ltype, l)
|
||||||
|
|
||||||
|
if err = l.Alert(testAlert, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Crit(testCrit, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Crit: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Debug(testDebug, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Debug: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Emerg(testEmerg, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Emerg: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Err(testErr, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Err: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Info(testInfo, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Notice(testNotice, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Notice: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Warning(testWarning, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Warning: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix, err = l.GetPrefix(); err != nil {
|
||||||
|
t.Fatalf("error when fetching prefix: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if ltype == "StdLogger" || ltype == "FileLogger" { // StdLogger (and thus FileLogger) adds a space at the end.
|
||||||
|
testPrefix = TestLogPrefix + " "
|
||||||
|
} else {
|
||||||
|
testPrefix = TestLogPrefix
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix != testPrefix {
|
||||||
|
t.Fatalf("true prefix ('%v') does not match TestLogPrefix ('%v')", prefix, TestLogPrefix)
|
||||||
|
}
|
||||||
|
if err = l.SetPrefix(TestLogAltPrefix); err != nil {
|
||||||
|
t.Fatalf("error when setting prefix to %v: %v", TestLogAltPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.SetPrefix(TestLogPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.DoDebug(false); err != nil {
|
||||||
|
t.Fatalf("error when changing debug to false: %v", err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.DoDebug(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Shutdown(); err != nil {
|
||||||
|
t.Fatalf("Error when running Shutdown: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, keepLog = os.LookupEnv(EnvVarKeepLog)
|
||||||
|
|
||||||
|
if !keepLog {
|
||||||
|
if err = os.Remove(tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when removing temporary log file '%v': %v", tempfilePath, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed all logging targets.", ltype)
|
||||||
|
}
|
118
logging/multilogger_windows_test.go
Normal file
118
logging/multilogger_windows_test.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
`os`
|
||||||
|
`testing`
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestMultiLogger tests GetMultiLogger and MultiLogger methods.
|
||||||
|
func TestMultiLogger(t *testing.T) {
|
||||||
|
|
||||||
|
var l *MultiLogger
|
||||||
|
var tempfile *os.File
|
||||||
|
var tempfilePath string
|
||||||
|
var keepLog bool
|
||||||
|
var ltype string = "MultiLogger"
|
||||||
|
var prefix string
|
||||||
|
var testPrefix string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if tempfile, err = os.CreateTemp("", ".LOGGINGTEST_*"); err != nil {
|
||||||
|
t.Fatalf("error when creating temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
tempfilePath = tempfile.Name()
|
||||||
|
// We can close the handler immediately; we don't need it since the FileLogger opens its own.
|
||||||
|
if err = tempfile.Close(); err != nil {
|
||||||
|
t.Fatalf("error when closing handler for temporary log file '%v': %v", tempfile.Name(), err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
l = GetMultiLogger(true, TestLogPrefix)
|
||||||
|
|
||||||
|
if err = l.AddStdLogger("StdLogger", false, true, logFlags); err != nil {
|
||||||
|
t.Fatalf("error when adding StdLogger to MultiLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
if err = l.AddFileLogger("FileLogger", logFlags, tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when adding FileLogger to MultiLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.AddDefaultLogger("DefaultLogger", DefaultEventID, logFlags, tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when adding default logger to MultiLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.AddWinLogger("WinLogger", DefaultEventID); err != nil {
|
||||||
|
t.Fatalf("error when adding WinLogger to MultiLogger: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed Setup. Logger: %#v", ltype, l)
|
||||||
|
|
||||||
|
if err = l.Alert(testAlert, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Crit(testCrit, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Crit: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Debug(testDebug, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Debug: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Emerg(testEmerg, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Emerg: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Err(testErr, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Err: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Info(testInfo, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Alert: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Notice(testNotice, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Notice: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Warning(testWarning, ltype); err != nil {
|
||||||
|
t.Fatalf("error for Warning: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix, err = l.GetPrefix(); err != nil {
|
||||||
|
t.Fatalf("error when fetching prefix: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if ltype == "StdLogger" || ltype == "FileLogger" { // StdLogger (and thus FileLogger) adds a space at the end.
|
||||||
|
testPrefix = TestLogPrefix + " "
|
||||||
|
} else {
|
||||||
|
testPrefix = TestLogPrefix
|
||||||
|
}
|
||||||
|
|
||||||
|
if prefix != testPrefix {
|
||||||
|
t.Fatalf("true prefix ('%v') does not match TestLogPrefix ('%v')", prefix, TestLogPrefix)
|
||||||
|
}
|
||||||
|
if err = l.SetPrefix(TestLogAltPrefix); err != nil {
|
||||||
|
t.Fatalf("error when setting prefix to %v: %v", TestLogAltPrefix, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.SetPrefix(TestLogPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.DoDebug(false); err != nil {
|
||||||
|
t.Fatalf("error when changing debug to false: %v", err.Error())
|
||||||
|
} else {
|
||||||
|
_ = l.DoDebug(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = l.Shutdown(); err != nil {
|
||||||
|
t.Fatalf("Error when running Shutdown: %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, keepLog = os.LookupEnv(EnvVarKeepLog)
|
||||||
|
|
||||||
|
if !keepLog {
|
||||||
|
if err = os.Remove(tempfilePath); err != nil {
|
||||||
|
t.Fatalf("error when removing temporary log file '%v': %v", tempfilePath, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Logger %v passed all logging targets.", ltype)
|
||||||
|
}
|
@ -48,6 +48,26 @@ type StdLogger struct {
|
|||||||
You will need to run *StdLogger.Shutdown and then *StdLogger.Setup again if you wish to change this.
|
You will need to run *StdLogger.Shutdown and then *StdLogger.Setup again if you wish to change this.
|
||||||
*/
|
*/
|
||||||
LogFlags int
|
LogFlags int
|
||||||
|
/*
|
||||||
|
EnableStdOut is true if the log will send to STDOUT.
|
||||||
|
If false (default), no output will be written to STDOUT.
|
||||||
|
You will need to run StdLogger.Shutdown and then StdLogger.Setup again if you wish to change this.
|
||||||
|
|
||||||
|
If EnableStdOut is false and EnableStdErr is false, no logging output will occur by default
|
||||||
|
and StdLogger.Logger will be largely useless.
|
||||||
|
It will be up to you to modify the underlying log.Logger to behave as you want.
|
||||||
|
*/
|
||||||
|
EnableStdOut bool
|
||||||
|
/*
|
||||||
|
EnableStdErr is true if the log will send to STDERR.
|
||||||
|
If false (default), no output will be written to STDERR.
|
||||||
|
You will need to run StdLogger.Shutdown and then StdLogger.Setup again if you wish to change this.
|
||||||
|
|
||||||
|
If EnableStdErr is false and EnableStdOut is false, no logging output will occur by default
|
||||||
|
and StdLogger.Logger will be largely useless.
|
||||||
|
It will be up to you to modify the underlying log.Logger to behave as you want.
|
||||||
|
*/
|
||||||
|
EnableStdErr bool
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -62,18 +82,6 @@ type FileLogger struct {
|
|||||||
StdLogger
|
StdLogger
|
||||||
// Path is the path to the logfile.
|
// Path is the path to the logfile.
|
||||||
Path string
|
Path string
|
||||||
/*
|
|
||||||
EnableStdOut is true if the log will send to STDOUT as well as the file (and STDERR if FileLogger.EnableStdErr == true).
|
|
||||||
If false (default), it will only (silently) write to the log file.
|
|
||||||
You will need to run FileLogger.Shutdown and then FileLogger.Setup again if you wish to change this.
|
|
||||||
*/
|
|
||||||
EnableStdOut bool
|
|
||||||
/*
|
|
||||||
EnableStdErr is true if the log will send to STDERR as well as the file (and STDOUT if FileLogger.EnableStdOut == true).
|
|
||||||
If false (default), it will only (silently) write to the log file.
|
|
||||||
You will need to run *FileLogger.Shutdown and then *FileLogger.Setup again if you wish to change this.
|
|
||||||
*/
|
|
||||||
EnableStdErr bool
|
|
||||||
// writer is used for the writing out of the log file.
|
// writer is used for the writing out of the log file.
|
||||||
writer *os.File
|
writer *os.File
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,15 @@ import (
|
|||||||
`log/syslog`
|
`log/syslog`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
SystemDLogger (yes, I'm aware it's actually written as "systemd") writes to journald on systemd-enabled systems.
|
||||||
|
*/
|
||||||
type SystemDLogger struct {
|
type SystemDLogger struct {
|
||||||
EnableDebug bool
|
EnableDebug bool
|
||||||
Prefix string
|
Prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SyslogLogger writes to syslog on syslog-enabled systems.
|
||||||
type SyslogLogger struct {
|
type SyslogLogger struct {
|
||||||
EnableDebug bool
|
EnableDebug bool
|
||||||
Prefix string
|
Prefix string
|
||||||
|
@ -39,8 +39,8 @@ type WinLogger struct {
|
|||||||
RemoveOnClose bool
|
RemoveOnClose bool
|
||||||
// elog is the actual writer to the Event Log.
|
// elog is the actual writer to the Event Log.
|
||||||
elog *eventlog.Log
|
elog *eventlog.Log
|
||||||
// eids is used to look up what event ID to use when writing to a WinLogger.elog.
|
// EIDs is used to look up what event ID to use when writing to a WinLogger.elog.
|
||||||
eids *WinEventID
|
EIDs *WinEventID
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user