111 lines
3.1 KiB
Go
111 lines
3.1 KiB
Go
package logging
|
|
|
|
import (
|
|
`errors`
|
|
`strings`
|
|
)
|
|
|
|
/*
|
|
GetLogger returns an instance of Logger that best suits your system's capabilities. Note that this is a VERY generalized interface to the Windows Event Log.
|
|
|
|
If you require more robust logging capabilities (e.g. custom event IDs per uniquely identifiable event),
|
|
you will want to set up your own logger (golang.org/x/sys/windows/svc/eventlog).
|
|
|
|
If enableDebug is true, debug messages (which according to your program may or may not contain sensitive data) are rendered and written (otherwise they are ignored).
|
|
|
|
A blank source will return an error as it's used as the source name. Other functions, struct fields, etc. will refer to this as the "prefix".
|
|
|
|
A pointer to a WinEventID struct may be specified for eventIDs to map extended logging levels (as Windows only supports three levels natively).
|
|
If it is nil, a default one (DefaultEventID) will be used.
|
|
|
|
logPaths is an (optional) list of strings to use as paths to test for writing. If the file can be created/written to,
|
|
it will be used (assuming you have no higher-level loggers available).
|
|
|
|
Only the first logPaths entry that "works" will be used, later entries will be ignored.
|
|
Currently this will almost always return a WinLogger.
|
|
|
|
If you call GetLogger, you will only get a single ("best") logger your system supports.
|
|
If you want to log to multiple Logger destinations at once (or want to log to an explicit Logger type),
|
|
use GetMultiLogger.
|
|
*/
|
|
func GetLogger(enableDebug bool, source string, eventIDs *WinEventID, logPaths ...string) (logger Logger, err error) {
|
|
|
|
var logPath string
|
|
var logFlags bitmask.MaskBit
|
|
var exists bool
|
|
var success bool
|
|
var ckLogPaths []string
|
|
|
|
if strings.TrimSpace(source) == "" {
|
|
err = errors.New("invalid source for Windows logging")
|
|
return
|
|
}
|
|
|
|
// Configure system-supported logger(s). The Windows Event Logger (should) ALWAYS be available.
|
|
logFlags.AddFlag(LogWinLogger)
|
|
if eventIDs == nil {
|
|
eventIDs = DefaultEventID
|
|
}
|
|
|
|
if logPaths != nil {
|
|
ckLogPaths = logPaths
|
|
ckLogPaths = append(ckLogPaths, defLogPaths...)
|
|
|
|
for _, p := range ckLogPaths {
|
|
if exists, _ = paths.RealPathExists(&p); exists {
|
|
if success, err = testOpen(p); err != nil {
|
|
continue
|
|
} else if !success {
|
|
continue
|
|
}
|
|
logFlags.AddFlag(LogFile)
|
|
logPath = p
|
|
break
|
|
} else {
|
|
dirPath := path.Dir(p)
|
|
if err = paths.MakeDirIfNotExist(dirPath); err != nil {
|
|
continue
|
|
}
|
|
if success, err = testOpen(p); err != nil {
|
|
continue
|
|
} else if !success {
|
|
continue
|
|
}
|
|
logFlags.AddFlag(LogFile)
|
|
logPath = p
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if logFlags.HasFlag(LogWinLogger) {
|
|
logger = &WinLogger{
|
|
Prefix: source,
|
|
EnableDebug: enableDebug,
|
|
eids: eventIDs,
|
|
}
|
|
} else {
|
|
if logFlags.HasFlag(LogFile) {
|
|
logger = &FileLogger{
|
|
StdLogger: StdLogger{
|
|
Prefix: source,
|
|
EnableDebug: enableDebug,
|
|
},
|
|
Path: logPath,
|
|
}
|
|
} else {
|
|
logger = &StdLogger{
|
|
Prefix: source,
|
|
EnableDebug: enableDebug,
|
|
}
|
|
}
|
|
}
|
|
|
|
logger.Setup()
|
|
|
|
logger.Info("logger initialized of type %T with source %v", logger, logger.GetPrefix())
|
|
|
|
return
|
|
|
|
}
|