From d085d0f3ee0bade6bc1224c541b369d4f41698c0 Mon Sep 17 00:00:00 2001 From: brent s Date: Fri, 26 Feb 2021 15:52:29 -0500 Subject: [PATCH] logging --- go.mod | 8 +++ go.sum | 5 ++ logging/consts.go | 25 +++++++++ logging/funcs.go | 117 ++++++++++++++++++++++++++++++++++++++++ logging/funcs_file.go | 41 ++++++++++++++ logging/funcs_std.go | 41 ++++++++++++++ logging/funcs_sysd.go | 41 ++++++++++++++ logging/funcs_syslog.go | 41 ++++++++++++++ logging/types.go | 44 +++++++++++++++ types/bitmasks.go | 44 +++++++++++++++ 10 files changed, 407 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 logging/consts.go create mode 100644 logging/funcs.go create mode 100644 logging/funcs_file.go create mode 100644 logging/funcs_std.go create mode 100644 logging/funcs_sysd.go create mode 100644 logging/funcs_syslog.go create mode 100644 logging/types.go create mode 100644 types/bitmasks.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a9c808e --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module r00t2.io/goutils + +go 1.16 + +require ( + github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf + r00t2.io/sysutils v0.0.0-20210224054841-55ac47c86928 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..4da76d9 --- /dev/null +++ b/go.sum @@ -0,0 +1,5 @@ +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/jszwec/csvutil v1.5.0/go.mod h1:Rpu7Uu9giO9subDyMCIQfHVDuLrcaC36UA4YcJjGBkg= +r00t2.io/sysutils v0.0.0-20210224054841-55ac47c86928 h1:aYEn20eguqsmqT3J9VjkzdhyPwmOVDGzzffcEfV18a4= +r00t2.io/sysutils v0.0.0-20210224054841-55ac47c86928/go.mod h1:XzJkBF6SHAODEszJlOcjtGoTHwYnZZNmseA6PyOujes= diff --git a/logging/consts.go b/logging/consts.go new file mode 100644 index 0000000..b59f348 --- /dev/null +++ b/logging/consts.go @@ -0,0 +1,25 @@ +package logging + +import ( + `os` + + `r00t2.io/goutils/types` +) + +const ( + devlog string = "/dev/log" + logPerm os.FileMode = 0600 +) + +// Flags for logger configuration +const ( + LogUndefined types.MaskBit = 1 << iota + LogJournald + LogSyslog + LogFile + LogStdout +) + +var ( + defLogPaths = []string{"/var/log/golang/program.log", "~/.local/log/golang/program.log"} +) diff --git a/logging/funcs.go b/logging/funcs.go new file mode 100644 index 0000000..10beada --- /dev/null +++ b/logging/funcs.go @@ -0,0 +1,117 @@ +package logging + +import ( + native `log` + `os` + `path` + `strings` + + "r00t2.io/goutils/types" + + sysd `github.com/coreos/go-systemd/journal` + `r00t2.io/sysutils/paths` +) + +var ( + _ = sysd.Enabled() + _ = native.Logger{} + _ = os.Interrupt + _ = types.Env{} +) + +func GetLogger(enableDebug bool, prefix string) (logger Logger, err error) { + + var logPath string + var logflags types.MaskBit + + // Configure system-supported logger(s). + if sysd.Enabled() { + // Use Journald. + logflags.AddFlag(LogJournald) + } else { + // If we can detect syslog, use that. If not, try to use a file logger (+ stdout). + // Last ditch, stdout. + var hasSyslog bool + var stat os.FileInfo + var devlogPath string = devlog + + if hasSyslog, stat, err = paths.RealPathExistsStat(&devlogPath); hasSyslog && err != nil {return} + + if hasSyslog && !stat.Mode().IsRegular() {logflags.AddFlag(LogSyslog)} else { + var exists bool + var success bool + logflags.AddFlag(LogStdout) + for _, p := range defLogPaths { + 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(LogJournald) { + logger = &SystemDLogger{ + Prefix: logPrefix, + } + } else { + if logflags.HasFlag(LogSyslog) { + logger = &SyslogLogger{ + Prefix: logPrefix, + } + } else { + if logflags.HasFlag(LogFile) { + logger = &FileLogger{ + StdLogger: StdLogger{ + Prefix: logPrefix, + }, + Path: logPath, + } + } else { + logger = &StdLogger{ + Prefix: logPrefix, + } + } + } + } + + logger.doDebug(enableDebug) + if strings.TrimSpace(prefix) != "" { + logger.setPrefix(prefix) + } + + return +} + +func testOpen(path string) (success bool, err error) { + var f *os.File + + // Example #2, https://golang.org/pkg/os/#OpenFile + if f, err = os.OpenFile(path, os.O_RDWR | os.O_CREATE, logPerm); err != nil { + return + } + defer f.Close() + + success = true + + return +} diff --git a/logging/funcs_file.go b/logging/funcs_file.go new file mode 100644 index 0000000..a302c92 --- /dev/null +++ b/logging/funcs_file.go @@ -0,0 +1,41 @@ +package logging + +func (l *FileLogger) doDebug(d bool) { + l.EnableDebug = d +} + +func (l *FileLogger) setPrefix(prefix string) { + l.Prefix = prefix +} + +func (l *FileLogger) Alert(s string, v ...interface{}) (err error) { + return +} + +func (l *FileLogger) Crit(s string, v ...interface{}) (err error) { + return +} + +func (l *FileLogger) Debug(s string, v ...interface{}) (err error) { + return +} + +func (l *FileLogger) Emerg(s string, v ...interface{}) (err error) { + return +} + +func (l *FileLogger) Err(s string, v ...interface{}) (err error) { + return +} + +func (l *FileLogger) Info(s string, v ...interface{}) (err error) { + return +} + +func (l *FileLogger) Notice(s string, v ...interface{}) (err error) { + return +} + +func (l *FileLogger) Warning(s string, v ...interface{}) (err error) { + return +} diff --git a/logging/funcs_std.go b/logging/funcs_std.go new file mode 100644 index 0000000..05b69e7 --- /dev/null +++ b/logging/funcs_std.go @@ -0,0 +1,41 @@ +package logging + +func (l *StdLogger) doDebug(d bool) { + l.EnableDebug = d +} + +func (l *StdLogger) setPrefix(prefix string) { + l.Prefix = prefix +} + +func (l *StdLogger) Alert(s string, v ...interface{}) (err error) { + return +} + +func (l *StdLogger) Crit(s string, v ...interface{}) (err error) { + return +} + +func (l *StdLogger) Debug(s string, v ...interface{}) (err error) { + return +} + +func (l *StdLogger) Emerg(s string, v ...interface{}) (err error) { + return +} + +func (l *StdLogger) Err(s string, v ...interface{}) (err error) { + return +} + +func (l *StdLogger) Info(s string, v ...interface{}) (err error) { + return +} + +func (l *StdLogger) Notice(s string, v ...interface{}) (err error) { + return +} + +func (l *StdLogger) Warning(s string, v ...interface{}) (err error) { + return +} diff --git a/logging/funcs_sysd.go b/logging/funcs_sysd.go new file mode 100644 index 0000000..0892830 --- /dev/null +++ b/logging/funcs_sysd.go @@ -0,0 +1,41 @@ +package logging + +func (l *SystemDLogger) doDebug(d bool) { + l.EnableDebug = d +} + +func (l *SystemDLogger) setPrefix(prefix string) { + l.Prefix = prefix +} + +func (l *SystemDLogger) Alert(s string, v ...interface{}) (err error) { + return +} + +func (l *SystemDLogger) Crit(s string, v ...interface{}) (err error) { + return +} + +func (l *SystemDLogger) Debug(s string, v ...interface{}) (err error) { + return +} + +func (l *SystemDLogger) Emerg(s string, v ...interface{}) (err error) { + return +} + +func (l *SystemDLogger) Err(s string, v ...interface{}) (err error) { + return +} + +func (l *SystemDLogger) Info(s string, v ...interface{}) (err error) { + return +} + +func (l *SystemDLogger) Notice(s string, v ...interface{}) (err error) { + return +} + +func (l *SystemDLogger) Warning(s string, v ...interface{}) (err error) { + return +} diff --git a/logging/funcs_syslog.go b/logging/funcs_syslog.go new file mode 100644 index 0000000..1122202 --- /dev/null +++ b/logging/funcs_syslog.go @@ -0,0 +1,41 @@ +package logging + +func (l *SyslogLogger) doDebug(d bool) { + l.EnableDebug = d +} + +func (l *SyslogLogger) setPrefix(prefix string) { + l.Prefix = prefix +} + +func (l *SyslogLogger) Alert(s string, v ...interface{}) (err error) { + return +} + +func (l *SyslogLogger) Crit(s string, v ...interface{}) (err error) { + return +} + +func (l *SyslogLogger) Debug(s string, v ...interface{}) (err error) { + return +} + +func (l *SyslogLogger) Emerg(s string, v ...interface{}) (err error) { + return +} + +func (l *SyslogLogger) Err(s string, v ...interface{}) (err error) { + return +} + +func (l *SyslogLogger) Info(s string, v ...interface{}) (err error) { + return +} + +func (l *SyslogLogger) Notice(s string, v ...interface{}) (err error) { + return +} + +func (l *SyslogLogger) Warning(s string, v ...interface{}) (err error) { + return +} diff --git a/logging/types.go b/logging/types.go new file mode 100644 index 0000000..1ee8cb9 --- /dev/null +++ b/logging/types.go @@ -0,0 +1,44 @@ +package logging + +import ( + `log` + `log/syslog` +) + +type Logger interface { + Alert(string, ...interface{}) error + Crit(string, ...interface{}) error + Debug(string, ...interface{}) error + Emerg(string, ...interface{}) error + Err(string, ...interface{}) error + Info(string, ...interface{}) error + Notice(string, ...interface{}) error + Warning(string, ...interface{}) error + doDebug(bool) + setPrefix(string) +} + +type SystemDLogger struct { + EnableDebug bool + Prefix string +} + +type SyslogLogger struct { + syslog.Writer + EnableDebug bool + Prefix string +} + +type StdLogger struct { + log.Logger + EnableDebug bool + Prefix string +} + +type FileLogger struct { + log.Logger + StdLogger + EnableDebug bool + Path string + Prefix string +} diff --git a/types/bitmasks.go b/types/bitmasks.go new file mode 100644 index 0000000..5c5451f --- /dev/null +++ b/types/bitmasks.go @@ -0,0 +1,44 @@ +package types + +type BitMask interface { + HasFlag(bit MaskBit) bool + AddFlag(bit MaskBit) + ClearFlag(bit MaskBit) + ToggleFlag(bit MaskBit) +} + +// BitMasks +type MaskBit uint8 + +// LDAP Connection flags +const ( + LdapBindUndefined MaskBit = 1 << iota + LdapBindNone // GSSAPI via SASL or (TODO) Anonymous bind + LdapBindNet + LdapBindTls + LdapBindStartTls + LdapBindSasl + LdapBindNoPassword +) + +func (f MaskBit) HasFlag(flag MaskBit) (r bool) { + if f&flag != 0 { + r = true + } + return +} + +func (f *MaskBit) AddFlag(flag MaskBit) { + *f |= flag + return +} + +func (f *MaskBit) ClearFlag(flag MaskBit) { + *f &= flag + return +} + +func (f *MaskBit) ToggleFlag(flag MaskBit) { + *f ^= flag + return +}