Compare commits
No commits in common. "master" and "v1.7.1" have entirely different histories.
@ -1,9 +1,3 @@
|
|||||||
- macOS support beyond the legacy NIX stuff. it apparently uses something called "ULS", "Unified Logging System".
|
|
||||||
-- https://developer.apple.com/documentation/os/logging
|
|
||||||
-- https://developer.apple.com/documentation/os/generating-log-messages-from-your-code
|
|
||||||
-- no native Go support (yet)?
|
|
||||||
--- https://developer.apple.com/forums/thread/773369
|
|
||||||
|
|
||||||
- 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
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
package logging
|
|
||||||
|
|
||||||
var (
|
|
||||||
// defLogPaths indicates default log paths.
|
|
||||||
defLogPaths = []string{
|
|
||||||
"/var/log/golang/program.log",
|
|
||||||
"~/Library/Logs/Golang/program.log",
|
|
||||||
}
|
|
||||||
)
|
|
@ -1,5 +1,32 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
`log/syslog`
|
||||||
|
|
||||||
|
`r00t2.io/goutils/bitmask`
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// devlog is the path to the syslog char device.
|
||||||
|
devlog string = "/dev/log"
|
||||||
|
// syslogFacility is the facility to use; it's a little like a context or scope if you think of it in those terms.
|
||||||
|
syslogFacility syslog.Priority = syslog.LOG_USER
|
||||||
|
)
|
||||||
|
|
||||||
|
// Flags for logger configuration. These are used internally.
|
||||||
|
const (
|
||||||
|
// LogUndefined indicates an undefined Logger type.
|
||||||
|
LogUndefined bitmask.MaskBit = 1 << iota
|
||||||
|
// LogJournald flags a SystemDLogger Logger type.
|
||||||
|
LogJournald
|
||||||
|
// LogSyslog flags a SyslogLogger Logger type.
|
||||||
|
LogSyslog
|
||||||
|
// LogFile flags a FileLogger Logger type.
|
||||||
|
LogFile
|
||||||
|
// LogStdout flags a StdLogger Logger type.
|
||||||
|
LogStdout
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// defLogPaths indicates default log paths.
|
// defLogPaths indicates default log paths.
|
||||||
defLogPaths = []string{
|
defLogPaths = []string{
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
//go:build !(windows || plan9 || wasip1 || js || ios)
|
|
||||||
// +build !windows,!plan9,!wasip1,!js,!ios
|
|
||||||
|
|
||||||
// I mean maybe it works for plan9 and ios, I don't know.
|
|
||||||
|
|
||||||
package logging
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log/syslog"
|
|
||||||
|
|
||||||
"r00t2.io/goutils/bitmask"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// devlog is the path to the syslog char device.
|
|
||||||
devlog string = "/dev/log"
|
|
||||||
// syslogFacility is the facility to use; it's a little like a context or scope if you think of it in those terms.
|
|
||||||
syslogFacility syslog.Priority = syslog.LOG_USER
|
|
||||||
)
|
|
||||||
|
|
||||||
// Flags for logger configuration. These are used internally.
|
|
||||||
|
|
||||||
// LogUndefined indicates an undefined Logger type.
|
|
||||||
const LogUndefined bitmask.MaskBit = iota
|
|
||||||
const (
|
|
||||||
// LogJournald flags a SystemDLogger Logger type.
|
|
||||||
LogJournald = 1 << iota
|
|
||||||
// LogSyslog flags a SyslogLogger Logger type.
|
|
||||||
LogSyslog
|
|
||||||
// LogFile flags a FileLogger Logger type.
|
|
||||||
LogFile
|
|
||||||
// LogStdout flags a StdLogger Logger type.
|
|
||||||
LogStdout
|
|
||||||
)
|
|
@ -7,7 +7,7 @@ These particular loggers (logging.Logger) available are:
|
|||||||
StdLogger
|
StdLogger
|
||||||
FileLogger
|
FileLogger
|
||||||
SystemDLogger (Linux only)
|
SystemDLogger (Linux only)
|
||||||
SyslogLogger (Linux/macOS/other *NIX-like only)
|
SyslogLogger (Linux only)
|
||||||
WinLogger (Windows only)
|
WinLogger (Windows only)
|
||||||
|
|
||||||
There is a seventh 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.
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
`errors`
|
||||||
|
`fmt`
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrNoSysD indicates that the user attempted to add a SystemDLogger to a MultiLogger but systemd is unavailable.
|
// ErrNoSysD indicates that the user attempted to add a SystemDLogger to a MultiLogger but systemd is unavailable.
|
||||||
ErrNoSysD error = errors.New("a systemd (journald) Logger was requested but systemd is unavailable on this system")
|
ErrNoSysD error = errors.New("a systemd (journald) Logger was requested but systemd is unavailable on this system")
|
||||||
|
// ErrNoSyslog indicates that the user attempted to add a SyslogLogger to a MultiLogger but syslog's logger device is unavailable.
|
||||||
|
ErrNoSyslog error = errors.New("a Syslog Logger was requested but Syslog is unavailable on this system")
|
||||||
|
/*
|
||||||
|
ErrInvalidDevLog indicates that the user attempted to add a SyslogLogger to a MultiLogger but
|
||||||
|
the Syslog char device file is... not actually a char device file.
|
||||||
|
*/
|
||||||
|
ErrInvalidDevLog error = errors.New(fmt.Sprintf("a Syslog Logger was requested but %v is not a valid logger handle", devlog))
|
||||||
)
|
)
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
//go:build !(windows || plan9 || wasip1 || js || ios)
|
|
||||||
// +build !windows,!plan9,!wasip1,!js,!ios
|
|
||||||
|
|
||||||
package logging
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrNoSyslog indicates that the user attempted to add a SyslogLogger to a MultiLogger but syslog's logger device is unavailable.
|
|
||||||
ErrNoSyslog error = errors.New("a Syslog Logger was requested but Syslog is unavailable on this system")
|
|
||||||
/*
|
|
||||||
ErrInvalidDevLog indicates that the user attempted to add a SyslogLogger to a MultiLogger but
|
|
||||||
the Syslog char device file is... not actually a char device file.
|
|
||||||
*/
|
|
||||||
ErrInvalidDevLog error = errors.New(fmt.Sprintf("a Syslog Logger was requested but %v is not a valid logger handle", devlog))
|
|
||||||
)
|
|
@ -1,17 +1,20 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
sysd "github.com/coreos/go-systemd/journal"
|
`os`
|
||||||
"github.com/google/uuid"
|
|
||||||
|
sysd `github.com/coreos/go-systemd/journal`
|
||||||
|
`github.com/google/uuid`
|
||||||
|
`r00t2.io/sysutils/paths`
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AddDefaultLogger adds a default Logger (as would be determined by GetLogger) to a MultiLogger.
|
AddDefaultLogger adds a default Logger (as would be determined by GetLogger) to a MultiLogger.
|
||||||
|
|
||||||
identifier is a string to use to identify the added Logger in MultiLogger.Loggers.
|
identifier is a string to use to identify the added Logger in MultiLogger.Loggers.
|
||||||
If empty, one will be automatically generated.
|
If empty, one will be automatically generated.
|
||||||
|
|
||||||
See the documentation for GetLogger for details on other arguments.
|
See the documentation for GetLogger for details on other arguments.
|
||||||
*/
|
*/
|
||||||
func (m *MultiLogger) AddDefaultLogger(identifier string, logFlags int, logPaths ...string) (err error) {
|
func (m *MultiLogger) AddDefaultLogger(identifier string, logFlags int, logPaths ...string) (err error) {
|
||||||
|
|
||||||
@ -37,10 +40,10 @@ func (m *MultiLogger) AddDefaultLogger(identifier string, logFlags int, logPaths
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AddSysdLogger adds a SystemDLogger to a MultiLogger.
|
AddSysdLogger adds a SystemDLogger to a MultiLogger.
|
||||||
|
|
||||||
identifier is a string to use to identify the added SystemDLogger in MultiLogger.Loggers.
|
identifier is a string to use to identify the added SystemDLogger in MultiLogger.Loggers.
|
||||||
If empty, one will be automatically generated.
|
If empty, one will be automatically generated.
|
||||||
*/
|
*/
|
||||||
func (m *MultiLogger) AddSysdLogger(identifier string) (err error) {
|
func (m *MultiLogger) AddSysdLogger(identifier string) (err error) {
|
||||||
|
|
||||||
@ -77,3 +80,55 @@ func (m *MultiLogger) AddSysdLogger(identifier string) (err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
AddSyslogLogger adds a SyslogLogger to a MultiLogger.
|
||||||
|
|
||||||
|
identifier is a string to use to identify the added SyslogLogger in MultiLogger.Loggers.
|
||||||
|
If empty, one will be automatically generated.
|
||||||
|
*/
|
||||||
|
func (m *MultiLogger) AddSyslogLogger(identifier string) (err error) {
|
||||||
|
|
||||||
|
var exists bool
|
||||||
|
var hasSyslog bool
|
||||||
|
var stat os.FileInfo
|
||||||
|
var devlogPath string = devlog
|
||||||
|
var prefix string
|
||||||
|
|
||||||
|
if identifier == "" {
|
||||||
|
identifier = uuid.New().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists = m.Loggers[identifier]; exists {
|
||||||
|
err = ErrExistingLogger
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasSyslog, stat, err = paths.RealPathExistsStat(&devlogPath); hasSyslog && err != nil {
|
||||||
|
return
|
||||||
|
} else if !hasSyslog {
|
||||||
|
err = ErrNoSyslog
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if stat.Mode().IsRegular() {
|
||||||
|
err = ErrInvalidDevLog
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Loggers[identifier] = &SyslogLogger{
|
||||||
|
EnableDebug: m.EnableDebug,
|
||||||
|
Prefix: m.Prefix,
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
//go:build !(windows || plan9 || wasip1 || js || ios)
|
|
||||||
// +build !windows,!plan9,!wasip1,!js,!ios
|
|
||||||
|
|
||||||
package logging
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"r00t2.io/sysutils/paths"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
AddSyslogLogger adds a SyslogLogger to a MultiLogger.
|
|
||||||
|
|
||||||
identifier is a string to use to identify the added SyslogLogger in MultiLogger.Loggers.
|
|
||||||
If empty, one will be automatically generated.
|
|
||||||
*/
|
|
||||||
func (m *MultiLogger) AddSyslogLogger(identifier string) (err error) {
|
|
||||||
|
|
||||||
var exists bool
|
|
||||||
var hasSyslog bool
|
|
||||||
var stat os.FileInfo
|
|
||||||
var devlogPath string = devlog
|
|
||||||
var prefix string
|
|
||||||
|
|
||||||
if identifier == "" {
|
|
||||||
identifier = uuid.New().String()
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, exists = m.Loggers[identifier]; exists {
|
|
||||||
err = ErrExistingLogger
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if hasSyslog, stat, err = paths.RealPathExistsStat(&devlogPath); hasSyslog && err != nil {
|
|
||||||
return
|
|
||||||
} else if !hasSyslog {
|
|
||||||
err = ErrNoSyslog
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if stat.Mode().IsRegular() {
|
|
||||||
err = ErrInvalidDevLog
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Loggers[identifier] = &SyslogLogger{
|
|
||||||
EnableDebug: m.EnableDebug,
|
|
||||||
Prefix: m.Prefix,
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
//go:build !(windows || plan9 || wasip1 || js || ios || linux)
|
|
||||||
// +build !windows,!plan9,!wasip1,!js,!ios,!linux
|
|
||||||
|
|
||||||
// Linux is excluded because it has its own.
|
|
||||||
|
|
||||||
package logging
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
AddDefaultLogger adds a default Logger (as would be determined by GetLogger) to a MultiLogger.
|
|
||||||
|
|
||||||
identifier is a string to use to identify the added Logger in MultiLogger.Loggers.
|
|
||||||
If empty, one will be automatically generated.
|
|
||||||
|
|
||||||
See the documentation for GetLogger for details on other arguments.
|
|
||||||
*/
|
|
||||||
func (m *MultiLogger) AddDefaultLogger(identifier string, logFlags int, logPaths ...string) (err error) {
|
|
||||||
|
|
||||||
var l Logger
|
|
||||||
var exists bool
|
|
||||||
|
|
||||||
if identifier == "" {
|
|
||||||
identifier = uuid.New().String()
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, exists = m.Loggers[identifier]; exists {
|
|
||||||
err = ErrExistingLogger
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if l, err = GetLogger(m.EnableDebug, m.Prefix, logFlags, logPaths...); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Loggers[identifier] = l
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,138 +0,0 @@
|
|||||||
//go:build !(windows || plan9 || wasip1 || js || ios || linux)
|
|
||||||
// +build !windows,!plan9,!wasip1,!js,!ios,!linux
|
|
||||||
|
|
||||||
// Linux is excluded because it has its own.
|
|
||||||
|
|
||||||
package logging
|
|
||||||
|
|
||||||
import (
|
|
||||||
native "log"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
"r00t2.io/goutils/bitmask"
|
|
||||||
"r00t2.io/sysutils/paths"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
_ = native.Logger{}
|
|
||||||
_ = os.Interrupt
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
GetLogger returns an instance of Logger that best suits your system's capabilities.
|
|
||||||
|
|
||||||
If enableDebug is true, debug messages (which according to your program may or may not contain sensitive data) are rendered and written.
|
|
||||||
|
|
||||||
If prefix is "\x00" (a null byte), then the default logging prefix will be used. If anything else, even an empty string,
|
|
||||||
is specified then that will be used instead for the prefix.
|
|
||||||
|
|
||||||
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.
|
|
||||||
If you want to log to multiple files simultaneously, use a MultiLogger instead.
|
|
||||||
|
|
||||||
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, prefix string, logConfigFlags int, logPaths ...string) (logger Logger, err error) {
|
|
||||||
|
|
||||||
var logPath string
|
|
||||||
var logFlags bitmask.MaskBit
|
|
||||||
var currentPrefix string
|
|
||||||
|
|
||||||
// Configure system-supported logger(s).
|
|
||||||
|
|
||||||
// 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
|
|
||||||
var ckLogPaths []string
|
|
||||||
|
|
||||||
logFlags.AddFlag(LogStdout)
|
|
||||||
ckLogPaths = defLogPaths
|
|
||||||
if logPaths != nil {
|
|
||||||
ckLogPaths = logPaths
|
|
||||||
}
|
|
||||||
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(LogSyslog) {
|
|
||||||
logger = &SyslogLogger{
|
|
||||||
Prefix: logPrefix,
|
|
||||||
EnableDebug: enableDebug,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if logFlags.HasFlag(LogFile) {
|
|
||||||
logger = &FileLogger{
|
|
||||||
StdLogger: StdLogger{
|
|
||||||
Prefix: logPrefix,
|
|
||||||
EnableDebug: enableDebug,
|
|
||||||
LogFlags: logConfigFlags,
|
|
||||||
},
|
|
||||||
Path: logPath,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger = &StdLogger{
|
|
||||||
Prefix: logPrefix,
|
|
||||||
EnableDebug: enableDebug,
|
|
||||||
LogFlags: logConfigFlags,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if prefix != "\x00" {
|
|
||||||
if err = logger.SetPrefix(prefix); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = logger.Setup(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if currentPrefix, err = logger.GetPrefix(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Debug("logger initialized of type %T with prefix %v", logger, currentPrefix)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,6 +1,3 @@
|
|||||||
//go:build !(windows || plan9 || wasip1 || js || ios)
|
|
||||||
// +build !windows,!plan9,!wasip1,!js,!ios
|
|
||||||
|
|
||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
@ -1,9 +1,27 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
`log/syslog`
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SystemDLogger (yes, I'm aware it's actually written as "systemd") writes to journald on systemd-enabled systems.
|
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 {
|
||||||
|
EnableDebug bool
|
||||||
|
Prefix string
|
||||||
|
alert,
|
||||||
|
crit,
|
||||||
|
debug,
|
||||||
|
emerg,
|
||||||
|
err,
|
||||||
|
info,
|
||||||
|
notice,
|
||||||
|
warning *syslog.Writer
|
||||||
|
}
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
//go:build !(windows || plan9 || wasip1 || js || ios)
|
|
||||||
// +build !windows,!plan9,!wasip1,!js,!ios
|
|
||||||
|
|
||||||
package logging
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log/syslog"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SyslogLogger writes to syslog on syslog-enabled systems.
|
|
||||||
type SyslogLogger struct {
|
|
||||||
EnableDebug bool
|
|
||||||
Prefix string
|
|
||||||
alert,
|
|
||||||
crit,
|
|
||||||
debug,
|
|
||||||
emerg,
|
|
||||||
err,
|
|
||||||
info,
|
|
||||||
notice,
|
|
||||||
warning *syslog.Writer
|
|
||||||
}
|
|
@ -69,9 +69,6 @@ func (e *MultiError) Error() (errStr string) {
|
|||||||
numErrs = len(e.Errors)
|
numErrs = len(e.Errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.lock.Lock()
|
|
||||||
defer e.lock.Unlock()
|
|
||||||
|
|
||||||
for idx, err := range e.Errors {
|
for idx, err := range e.Errors {
|
||||||
if (idx + 1) < numErrs {
|
if (idx + 1) < numErrs {
|
||||||
errStr += fmt.Sprintf("%v%v", err.Error(), e.ErrorSep)
|
errStr += fmt.Sprintf("%v%v", err.Error(), e.ErrorSep)
|
||||||
@ -90,9 +87,6 @@ func (e *MultiError) AddError(err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
e.lock.Lock()
|
|
||||||
defer e.lock.Unlock()
|
|
||||||
|
|
||||||
e.Errors = append(e.Errors, err)
|
e.Errors = append(e.Errors, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
package multierr
|
package multierr
|
||||||
|
|
||||||
import (
|
|
||||||
`sync`
|
|
||||||
)
|
|
||||||
|
|
||||||
// MultiError is a type of error.Error that can contain multiple errors.
|
// MultiError is a type of error.Error that can contain multiple errors.
|
||||||
type MultiError struct {
|
type MultiError struct {
|
||||||
// Errors is a slice of errors to combine/concatenate when .Error() is called.
|
// Errors is a slice of errors to combine/concatenate when .Error() is called.
|
||||||
Errors []error `json:"errors"`
|
Errors []error `json:"errors"`
|
||||||
// ErrorSep is a string to use to separate errors for .Error(). The default is "\n".
|
// ErrorSep is a string to use to separate errors for .Error(). The default is "\n".
|
||||||
ErrorSep string `json:"separator"`
|
ErrorSep string `json:"separator"`
|
||||||
lock sync.Mutex
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user