go_goutils/logging/funcs_windows.go

132 lines
3.7 KiB
Go

package logging
import (
`errors`
`path`
`strings`
`r00t2.io/goutils/bitmask`
`r00t2.io/sysutils/paths`
)
/*
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.
logConfigFlags is the corresponding flag(s) OR'd for StdLogger.LogFlags / FileLogger.StdLogger.LogFlags if either is selected. See StdLogger.LogFlags and
https://pkg.go.dev/log#pkg-constants for details.
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, logConfigFlags int, logPaths ...string) (logger Logger, err error) {
var logPath string
var logFlags bitmask.MaskBit
var exists bool
var success bool
var ckLogPaths []string
var prefix 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,
LogFlags: logConfigFlags,
},
Path: logPath,
}
} else {
logger = &StdLogger{
Prefix: source,
EnableDebug: enableDebug,
LogFlags: logConfigFlags,
}
}
}
if err = logger.Setup(); err != nil {
return
}
if source != "\x00" {
if err = logger.SetPrefix(source); err != nil {
return
}
}
if prefix, err = logger.GetPrefix(); err != nil {
return
}
logger.Debug("logger initialized of type %T with source %v", logger, prefix)
return
}