6 Commits

Author SHA1 Message Date
a445a51c0d Adding GetDebug method to loggers. 2022-09-07 06:03:28 -04:00
a2a849600b Add docs for NullLogger. 2022-09-06 01:01:39 -04:00
94145fb4c7 Add NullLogger to MultiLogger. 2022-03-13 13:34:24 -04:00
81a2d308f0 Add NullLogger.
For when you need a Logger but don't want one. ;)
2022-03-13 13:29:31 -04:00
c4b3c6441a adding Bytes() to MaskBit 2022-02-01 18:27:45 -05:00
1c5abd4083 modifying bitmask to allow specifying an explicit value, and changing to uint instead of uint8 2022-02-01 15:36:56 -05:00
13 changed files with 386 additions and 144 deletions

118
bitmask/bitmask.go Normal file
View File

@@ -0,0 +1,118 @@
package bitmask
import (
"bytes"
"errors"
"encoding/binary"
"math/bits"
)
// MaskBit is a flag container.
type MaskBit uint
/*
NewMaskBit is a convenience function.
It will return a MaskBit with a (referenced) value of 0, so set your consts up accordingly.
It is highly recommended to set this default as a "None" flag (separate from your iotas!)
as shown in the example.
*/
func NewMaskBit() (m *MaskBit) {
m = new(MaskBit)
return
}
// NewMaskBitExplicit is like NewMaskBit, but allows you to specify a non-zero (0x0) value.
func NewMaskBitExplicit(value uint) (m *MaskBit) {
var v MaskBit = MaskBit(value)
m = &v
return
}
// HasFlag is true if m has MaskBit flag set/enabled.
func (m *MaskBit) HasFlag(flag MaskBit) (r bool) {
var b MaskBit = *m
if b&flag != 0 {
r = true
}
return
}
// AddFlag adds MaskBit flag to m.
func (m *MaskBit) AddFlag(flag MaskBit) {
*m |= flag
return
}
// ClearFlag removes MaskBit flag from m.
func (m *MaskBit) ClearFlag(flag MaskBit) {
*m &= flag
return
}
// ToggleFlag switches MaskBit flag in m to its inverse; if true, it is now false and vice versa.
func (m *MaskBit) ToggleFlag(flag MaskBit) {
*m ^= flag
return
}
/*
Bytes returns the current value of a MasBit as a byte slice (big-endian).
If trim is false, b will (probably) be 4 bytes long if you're on a 32-bit size system,
and b will (probably) be 8 bytes long if you're on a 64-bit size system. You can determine
the size of the resulting slice via (math/)bits.UintSize / 8.
If trim is true, it will trim leading null bytes (if any). This will lead to an unpredictable
byte slice length in b, but is most likely preferred for byte operations.
*/
func (m *MaskBit) Bytes(trim bool) (b []byte) {
var b2 []byte
var size int = bits.UintSize / 8
var err error
b2 = make([]byte, size)
switch s := bits.UintSize; s {
case 32:
binary.BigEndian.PutUint32(b2[:], uint32(*m))
case 64:
binary.BigEndian.PutUint64(b2[:], uint64(*m))
default:
err = errors.New("unsupported Uint/system bit size")
panic(err)
}
if trim {
b = bytes.TrimLeft(b2, "\x00")
return
} else {
b = b2
return
}
return
}
// Value returns the current raw uint value of a MaskBit.
func (m *MaskBit) Value() (v uint) {
v = uint(*m)
return
}

View File

@@ -1,46 +0,0 @@
package bitmask
// MaskBit is a flag container.
type MaskBit uint8
/*
NewMaskBit is a convenience function.
It will return a MaskBit with a (referenced) value of 0, so set your consts up accordingly.
It is highly recommended to set this default as a "None" flag (separate from your iotas!)
as shown in the example.
*/
func NewMaskBit() (m *MaskBit) {
m = new(MaskBit)
return
}
// HasFlag is true if m has MaskBit flag set/enabled.
func (m *MaskBit) HasFlag(flag MaskBit) (r bool) {
var b MaskBit = *m
if b&flag != 0 {
r = true
}
return
}
// AddFlag adds MaskBit flag to m.
func (m *MaskBit) AddFlag(flag MaskBit) {
*m |= flag
return
}
// ClearFlag removes MaskBit flag from m.
func (m *MaskBit) ClearFlag(flag MaskBit) {
*m &= flag
return
}
// ToggleFlag switches MaskBit flag in m to its inverse; if true, it is now false and vice versa.
func (m *MaskBit) ToggleFlag(flag MaskBit) {
*m ^= flag
return
}

View File

@@ -11,18 +11,18 @@ To use this, set constants like thus:
"r00t2.io/goutils/bitmask"
)
const OPTNONE types.MaskBit = 0
const OPTNONE bitmask.MaskBit = 0
const (
OPT1 types.MaskBit = 1 << iota
OPT1 bitmask.MaskBit = 1 << iota
OPT2
OPT3
// ...
)
var MyMask *MaskBit
var MyMask *bitmask.MaskBit
func main() {
MyMask = types.NewMaskBit
MyMask = bitmask.NewMaskBit()
MyMask.AddFlag(OPT1)
MyMask.AddFlag(OPT3)
@@ -41,5 +41,13 @@ As would this:
But this would return false:
MyMask.HasFlag(OPT2)
If you need something with more flexibility (as always, at the cost of complexity),
you may be interested in one of the following libraries:
. github.com/alvaroloes/enumer
. github.com/abice/go-enum
. github.com/jeffreyrichter/enum/enum
*/
package bitmask

View File

@@ -3,18 +3,19 @@ Package logging implements and presents various loggers under a unified interfac
These particular loggers (logging.Logger) available are:
NullLogger
StdLogger
FileLogger
SystemDLogger (Linux only)
SyslogLogger (Linux only)
WinLogger (Windows only)
There is a sixth type of logging.Logger, MultiLogger, that allows for multiple loggers to be written to with a single call.
There is a seventh type of logging.Logger, MultiLogger, that allows for multiple loggers to be written to with a single call.
As you may have guessed, NullLogger doesn't actually log anything but is fully "functional" as a logging.Logger.
Note that for some Loggers, the prefix may be modified - "literal" loggers (StdLogger and FileLogger) will append a space to the end of the prefix.
If this is undesired (unlikely), you will need to modify (Logger).Prefix and run (Logger).Logger.SetPrefix(yourPrefixHere) for the respective logger.
Every logging.Logger type has the following methods that correspond to certain "levels".
Alert(s string, v ...interface{}) (err error)
@@ -36,6 +37,7 @@ 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:
DoDebug(d bool) (err error)
GetDebug() (d bool)
SetPrefix(p string) (err error)
GetPrefix() (p string, err error)
Setup() (err error)

View File

@@ -1,12 +1,12 @@
package logging
import (
`errors`
"errors"
"fmt"
`io/fs`
"io/fs"
"log"
"os"
`strings`
"strings"
)
// Setup sets up/configures a FileLogger and prepares it for use.
@@ -43,8 +43,8 @@ func (l *FileLogger) Shutdown() (err error) {
}
/*
GetPrefix returns the prefix used by this FileLogger.
err will always be nil; it's there for interface-compat.
GetPrefix returns the prefix used by this FileLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *FileLogger) GetPrefix() (prefix string, err error) {
@@ -54,9 +54,9 @@ func (l *FileLogger) GetPrefix() (prefix string, err error) {
}
/*
DoDebug sets the debug state of this FileLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
DoDebug sets the debug state of this FileLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
*/
func (l *FileLogger) DoDebug(d bool) (err error) {
@@ -65,9 +65,17 @@ func (l *FileLogger) DoDebug(d bool) (err error) {
return
}
// GetDebug returns the debug status of this FileLogger.
func (l *FileLogger) GetDebug() (d bool) {
d = l.EnableDebug
return
}
/*
SetPrefix sets the prefix for this FileLogger.
err will always be nil; it's there for interface-compat.
SetPrefix sets the prefix for this FileLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *FileLogger) SetPrefix(prefix string) (err error) {

View File

@@ -1,11 +1,11 @@
package logging
import (
`errors`
`fmt`
`sync`
"errors"
"fmt"
"sync"
`r00t2.io/goutils/multierr`
"r00t2.io/goutils/multierr"
)
// Setup sets up/configures a MultiLogger (and all its MultiLogger.Loggers) and prepares it for use.
@@ -67,8 +67,8 @@ func (m *MultiLogger) Shutdown() (err error) {
}
/*
GetPrefix returns the prefix used by this MultiLogger (and all its MultiLogger.Loggers).
err will always be nil; it's there for interface-compat.
GetPrefix returns the prefix used by this MultiLogger (and all its MultiLogger.Loggers).
err will always be nil; it's there for interface-compat.
*/
func (m *MultiLogger) GetPrefix() (prefix string, err error) {
@@ -79,10 +79,10 @@ func (m *MultiLogger) GetPrefix() (prefix string, err error) {
}
/*
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.
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.
If you had a logger-specific EnableDebug set, you will need to re-set it to your desired state after running this method.
If you had a logger-specific EnableDebug set, you will need to re-set it to your desired state after running this method.
*/
func (m *MultiLogger) DoDebug(d bool) (err error) {
@@ -114,10 +114,18 @@ func (m *MultiLogger) DoDebug(d bool) (err error) {
return
}
/*
SetPrefix sets the prefix for this MultiLogger (and all its MultiLogger.Loggers).
// GetDebug returns the debug status of this MultiLogger.
func (m *MultiLogger) GetDebug() (d bool) {
If you had a logger-specific Prefix set, you will need to re-set it to your desired prefix after running this method.
d = m.EnableDebug
return
}
/*
SetPrefix sets the prefix for this MultiLogger (and all its MultiLogger.Loggers).
If you had a logger-specific Prefix set, you will need to re-set it to your desired prefix after running this method.
*/
func (m *MultiLogger) SetPrefix(prefix string) (err error) {

View File

@@ -1,10 +1,10 @@
package logging
import (
`path`
"path"
`github.com/google/uuid`
`r00t2.io/sysutils/paths`
"github.com/google/uuid"
"r00t2.io/sysutils/paths"
)
/*
@@ -145,6 +145,40 @@ func (m *MultiLogger) AddFileLogger(identifier string, logFlags int, logfilePath
return
}
/*
AddNullLogger adds a NullLogger to a MultiLogger.
identifier is a string to use to identify the added NullLogger in MultiLogger.Loggers.
If empty, one will be automatically generated.
*/
func (m *MultiLogger) AddNullLogger(identifier string) (err error) {
var exists bool
var prefix string
if identifier == "" {
identifier = uuid.New().String()
}
if _, exists = m.Loggers[identifier]; exists {
err = ErrExistingLogger
return
}
m.Loggers[identifier] = &NullLogger{}
if err = m.Loggers[identifier].Setup(); err != nil {
return
}
if prefix, err = m.Loggers[identifier].GetPrefix(); err != nil {
return
}
m.Loggers[identifier].Debug("logger initialized of type %T with prefix %v", m.Loggers[identifier], prefix)
return
}
// RemoveLogger will let you remove a Logger from MultiLogger.Loggers.
func (m *MultiLogger) RemoveLogger(identifier string) (err error) {

View File

@@ -0,0 +1,74 @@
package logging
// Setup does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Setup() (err error) {
return
}
// DoDebug does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) DoDebug(d bool) (err error) {
return
}
// GetDebug returns the debug status of this NullLogger. It will always return true. 🙃
func (n *NullLogger) GetDebug() (d bool) {
d = true
return
}
// SetPrefix does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) SetPrefix(p string) (err error) {
return
}
// GetPrefix does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) GetPrefix() (p string, err error) {
return
}
// Shutdown does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Shutdown() (err error) {
return
}
// Alert does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Alert(s string, v ...interface{}) (err error) {
return
}
// Crit does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Crit(s string, v ...interface{}) (err error) {
return
}
// Debug does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Debug(s string, v ...interface{}) (err error) {
return
}
// Emerg does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Emerg(s string, v ...interface{}) (err error) {
return
}
// Err does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Err(s string, v ...interface{}) (err error) {
return
}
// Info does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Info(s string, v ...interface{}) (err error) {
return
}
// Notice does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Notice(s string, v ...interface{}) (err error) {
return
}
// Warning does nothing at all; it's here for interface compat. 🙃
func (l *NullLogger) Warning(s string, v ...interface{}) (err error) {
return
}

View File

@@ -2,15 +2,15 @@ package logging
import (
"fmt"
`io`
`log`
`os`
`strings`
"io"
"log"
"os"
"strings"
)
/*
Setup sets up/configures a StdLogger and prepares it for use.
err will always be nil; it's there for interface-compat.
Setup sets up/configures a StdLogger and prepares it for use.
err will always be nil; it's there for interface-compat.
*/
func (l *StdLogger) Setup() (err error) {
@@ -47,8 +47,8 @@ func (l *StdLogger) Setup() (err error) {
}
/*
Shutdown cleanly shuts down a StdLogger.
err will always be nil; it's there for interface-compat.
Shutdown cleanly shuts down a StdLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *StdLogger) Shutdown() (err error) {
@@ -58,8 +58,8 @@ func (l *StdLogger) Shutdown() (err error) {
}
/*
GetPrefix returns the prefix used by this StdLogger.
err will always be nil; it's there for interface-compat.
GetPrefix returns the prefix used by this StdLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *StdLogger) GetPrefix() (prefix string, err error) {
@@ -69,9 +69,9 @@ func (l *StdLogger) GetPrefix() (prefix string, err error) {
}
/*
DoDebug sets the debug state of this StdLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
DoDebug sets the debug state of this StdLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
*/
func (l *StdLogger) DoDebug(d bool) (err error) {
@@ -80,9 +80,17 @@ func (l *StdLogger) DoDebug(d bool) (err error) {
return
}
// GetDebug returns the debug status of this StdLogger.
func (l *StdLogger) GetDebug() (d bool) {
d = l.EnableDebug
return
}
/*
SetPrefix sets the prefix for this StdLogger.
err will always be nil; it's there for interface-compat.
SetPrefix sets the prefix for this StdLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *StdLogger) SetPrefix(prefix string) (err error) {

View File

@@ -8,8 +8,8 @@ import (
)
/*
Setup sets up/configures a SystemDLogger and prepares it for use.
err will always be nil; it's there for interface-compat.
Setup sets up/configures a SystemDLogger and prepares it for use.
err will always be nil; it's there for interface-compat.
*/
func (l *SystemDLogger) Setup() (err error) {
@@ -19,8 +19,8 @@ func (l *SystemDLogger) Setup() (err error) {
}
/*
Shutdown cleanly shuts down a SystemDLogger.
err will always be nil; it's there for interface-compat.
Shutdown cleanly shuts down a SystemDLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *SystemDLogger) Shutdown() (err error) {
@@ -30,8 +30,8 @@ func (l *SystemDLogger) Shutdown() (err error) {
}
/*
GetPrefix returns the prefix used by this SystemDLogger.
err will always be nil; it's there for interface-compat.
GetPrefix returns the prefix used by this SystemDLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *SystemDLogger) GetPrefix() (prefix string, err error) {
@@ -41,9 +41,9 @@ func (l *SystemDLogger) GetPrefix() (prefix string, err error) {
}
/*
DoDebug sets the debug state of this SystemDLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
DoDebug sets the debug state of this SystemDLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
*/
func (l *SystemDLogger) DoDebug(d bool) (err error) {
@@ -52,9 +52,17 @@ func (l *SystemDLogger) DoDebug(d bool) (err error) {
return
}
// GetDebug returns the debug status of this SystemDLogger.
func (l *SystemDLogger) GetDebug() (d bool) {
d = l.EnableDebug
return
}
/*
SetPrefix sets the prefix for this SystemDLogger.
err will always be nil; it's there for interface-compat.
SetPrefix sets the prefix for this SystemDLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *SystemDLogger) SetPrefix(prefix string) (err error) {

View File

@@ -5,7 +5,7 @@ import (
"log"
"log/syslog"
`r00t2.io/goutils/multierr`
"r00t2.io/goutils/multierr"
)
// Setup sets up/configures a SyslogLogger and prepares it for use.
@@ -73,8 +73,8 @@ func (l *SyslogLogger) Shutdown() (err error) {
}
/*
GetPrefix returns the prefix used by this SyslogLogger.
err will always be nil; it's there for interface-compat.
GetPrefix returns the prefix used by this SyslogLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *SyslogLogger) GetPrefix() (prefix string, err error) {
@@ -84,9 +84,9 @@ func (l *SyslogLogger) GetPrefix() (prefix string, err error) {
}
/*
DoDebug sets the debug state of this SyslogLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
DoDebug sets the debug state of this SyslogLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
*/
func (l *SyslogLogger) DoDebug(d bool) (err error) {
@@ -95,6 +95,14 @@ func (l *SyslogLogger) DoDebug(d bool) (err error) {
return
}
// GetDebug returns the debug status of this SyslogLogger.
func (l *SyslogLogger) GetDebug() (d bool) {
d = l.EnableDebug
return
}
// SetPrefix sets the prefix for this SyslogLogger.
func (l *SyslogLogger) SetPrefix(prefix string) (err error) {

View File

@@ -1,26 +1,26 @@
package logging
import (
`errors`
`fmt`
`os`
`os/exec`
`syscall`
"errors"
"fmt"
"os"
"os/exec"
"syscall"
`golang.org/x/sys/windows/registry`
`golang.org/x/sys/windows/svc/eventlog`
`r00t2.io/sysutils/paths`
"golang.org/x/sys/windows/registry"
"golang.org/x/sys/windows/svc/eventlog"
"r00t2.io/sysutils/paths"
)
/*
Setup sets up/configures a WinLogger and prepares it for use.
This will fail with an Access Denied (the first time, at least) unless running with elevated permissions unless WinLogger.Prefix is
a registered Event Log source.
Setup sets up/configures a WinLogger and prepares it for use.
This will fail with an Access Denied (the first time, at least) unless running with elevated permissions unless WinLogger.Prefix is
a registered Event Log source.
If a failure occurs while trying to open the log with the given WinLogger.Prefix ("source"), a new Event Log source will be registered.
If WinLogger.Executable is not empty at the time of calling WinLogger.Setup (or WinLogger.ForceService is true),
eventlog.Install will be used (with the WinLogger.ExpandKey field).
Otherwise eventlog.InstallAsEventCreate will be used.
If a failure occurs while trying to open the log with the given WinLogger.Prefix ("source"), a new Event Log source will be registered.
If WinLogger.Executable is not empty at the time of calling WinLogger.Setup (or WinLogger.ForceService is true),
eventlog.Install will be used (with the WinLogger.ExpandKey field).
Otherwise eventlog.InstallAsEventCreate will be used.
*/
func (l *WinLogger) Setup() (err error) {
@@ -108,8 +108,8 @@ func (l *WinLogger) Remove() (err error) {
}
/*
Shutdown cleanly shuts down a WinLogger but keep the source registered. Use WinLogger.Remove
(or set WinLogger.RemoveOnClose to true before calling WinLogger.Shutdown) to remove the registered source.
Shutdown cleanly shuts down a WinLogger but keep the source registered. Use WinLogger.Remove
(or set WinLogger.RemoveOnClose to true before calling WinLogger.Shutdown) to remove the registered source.
*/
func (l *WinLogger) Shutdown() (err error) {
@@ -128,8 +128,8 @@ func (l *WinLogger) Shutdown() (err error) {
}
/*
GetPrefix returns the prefix used by this WinLogger.
err will always be nil; it's there for interface-compat.
GetPrefix returns the prefix used by this WinLogger.
err will always be nil; it's there for interface-compat.
*/
func (l *WinLogger) GetPrefix() (prefix string, err error) {
@@ -139,9 +139,9 @@ func (l *WinLogger) GetPrefix() (prefix string, err error) {
}
/*
DoDebug sets the debug state of this WinLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
DoDebug sets the debug state of this WinLogger.
Note that this merely acts as a *safety filter* for debug messages to avoid sensitive information being written to the log.
err will always be nil; it's there for interface-compat.
*/
func (l *WinLogger) DoDebug(d bool) (err error) {
@@ -150,6 +150,14 @@ func (l *WinLogger) DoDebug(d bool) (err error) {
return
}
// GetDebug returns the debug status of this WinLogger.
func (l *WinLogger) GetDebug() (d bool) {
d = l.EnableDebug
return
}
// SetPrefix sets the prefix for this WinLogger.
func (l *WinLogger) SetPrefix(prefix string) (err error) {

View File

@@ -2,11 +2,11 @@ package logging
import (
"log"
`os`
"os"
)
/*
Logger is one of the various loggers offered by this module.
Logger is one of the various loggers offered by this module.
*/
type Logger interface {
Alert(s string, v ...interface{}) (err error)
@@ -18,6 +18,7 @@ type Logger interface {
Notice(s string, v ...interface{}) (err error)
Warning(s string, v ...interface{}) (err error)
DoDebug(d bool) (err error)
GetDebug() (d bool)
SetPrefix(p string) (err error)
GetPrefix() (p string, err error)
Setup() (err error)
@@ -25,8 +26,8 @@ type Logger interface {
}
/*
StdLogger uses the log package in stdlib to perform all logging. The default is to write to STDOUT.
If you wish to modify the underling log.Logger object, you can access it directly via StdLogger.Logger.
StdLogger uses the log package in stdlib to perform all logging. The default is to write to STDOUT.
If you wish to modify the underling log.Logger object, you can access it directly via StdLogger.Logger.
*/
type StdLogger struct {
// All log.Logger fields/methods are exposed.
@@ -71,11 +72,11 @@ type StdLogger struct {
}
/*
FileLogger uses a StdLogger with a file handle writer to write to the file given at Path.
FileLogger uses a StdLogger with a file handle writer to write to the file given at Path.
NOTE: If you wish to change the FileLogger.StdLogger.LogFlags, do *not* run FileLogger.StdLogger.Setup after doing so as this
will instead create a logger detached from the file handler. Instead, be sure to call FileLogger.Setup.
(Alternatively, run FileLogger.Shutdown and replace your logger with a new FileLogger.)
NOTE: If you wish to change the FileLogger.StdLogger.LogFlags, do *not* run FileLogger.StdLogger.Setup after doing so as this
will instead create a logger detached from the file handler. Instead, be sure to call FileLogger.Setup.
(Alternatively, run FileLogger.Shutdown and replace your logger with a new FileLogger.)
*/
type FileLogger struct {
// StdLogger is used for the log formation and handling. See StdLogger for more details.
@@ -86,6 +87,9 @@ type FileLogger struct {
writer *os.File
}
// NullLogger is used mainly for test implementations, mockup code, etc. It does absolutely nothing with all messages sent to it.
type NullLogger struct{}
// MultiLogger is used to contain one or more Loggers and present them all as a single Logger.
type MultiLogger struct {
/*