improve interop with other libs/stdlib
This commit is contained in:
parent
dc2ed32352
commit
4785d5f5d5
@ -4,19 +4,20 @@
|
|||||||
-- no native Go support (yet)?
|
-- no native Go support (yet)?
|
||||||
--- https://developer.apple.com/forums/thread/773369
|
--- https://developer.apple.com/forums/thread/773369
|
||||||
|
|
||||||
|
- add a `log/slog` logging.Logger?
|
||||||
|
|
||||||
- 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
|
||||||
-- log.LlongFile and log.Lshortfile flags don't currently work properly for StdLogger/FileLogger; they refer to the file in logging package rather than the caller.
|
-- log.LlongFile and log.Lshortfile flags don't currently work properly for StdLogger/FileLogger; they refer to the file in logging package rather than the caller.
|
||||||
|
-- ZeroLog seems to be able to do it, take a peek there.
|
||||||
|
|
||||||
- StdLogger2; where stdout and stderr are both logged to depending on severity level.
|
- StdLogger2; where stdout and stderr are both logged to depending on severity level.
|
||||||
- make configurable via OR bitmask
|
- make configurable via OR bitmask
|
||||||
|
|
||||||
- Suport remote loggers? (eventlog, syslog, systemd)
|
- Suport remote loggers? (eventlog, syslog, journald)
|
||||||
|
|
||||||
- JSON logger? YAML logger? XML logger?
|
- JSON logger? YAML logger? XML logger?
|
||||||
|
|
||||||
- DOCS.
|
- DOCS.
|
||||||
-- Done, but flesh out.
|
-- Done, but flesh out.
|
||||||
|
|
||||||
- Implement io.Writer interfaces
|
|
||||||
|
@ -11,9 +11,12 @@ These particular loggers (logging.Logger) available are:
|
|||||||
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.
|
||||||
As you may have guessed, NullLogger doesn't actually log anything but is fully "functional" as a logging.Logger.
|
(This is similar to stdlib's io.MultiWriter()'s return value, but with priority awareness and fmt string support).
|
||||||
|
|
||||||
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.
|
As you may have guessed, NullLogger doesn't actually log anything but is fully "functional" as a logging.Logger (similar to io.discard/io.Discard()'s return).
|
||||||
|
|
||||||
|
Note that for some Loggers, the prefix may be modified after the Logger has already initialized.
|
||||||
|
"Literal" loggers (StdLogger and FileLogger) will append a space to the end of the prefix by default.
|
||||||
If this is undesired (unlikely), you will need to modify (Logger).Prefix and run (Logger).Logger.SetPrefix(yourPrefixHere) for the respective logger.
|
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".
|
Every logging.Logger type has the following methods that correspond to certain "levels".
|
||||||
@ -45,5 +48,17 @@ logging.Logger types also have the following methods:
|
|||||||
|
|
||||||
In some cases, Logger.Setup and Logger.Shutdown are no-ops. In other cases, they perform necessary initialization/cleanup and closing of the logger.
|
In some cases, Logger.Setup and Logger.Shutdown are no-ops. In other cases, they perform necessary initialization/cleanup and closing of the logger.
|
||||||
It is recommended to *always* run Setup and Shutdown before and after using, respectively, regardless of the actual logging.Logger type.
|
It is recommended to *always* run Setup and Shutdown before and after using, respectively, regardless of the actual logging.Logger type.
|
||||||
|
|
||||||
|
Lastly, all logging.Loggers have a ToLogger() method. This returns a *log.Logger (from stdlib log), which also conforms to io.Writer inherently.
|
||||||
|
In addition. all have a ToRaw() method, which extends a Logger even further and returns an unexported type (*logging.logWriter) compatible with:
|
||||||
|
|
||||||
|
- io.ByteWriter
|
||||||
|
- io.Writer
|
||||||
|
- io.WriteCloser (Shutdown() on the Logger backend is called during Close(), rendering the underlying Logger unsafe to use afterwards)
|
||||||
|
- io.StringWriter
|
||||||
|
|
||||||
|
and, if stdlib io ever defines an e.g. RuneWriter (WriteRune(r rune) (n int, err error)), it will conform to that too.
|
||||||
|
Obviously this and io.ByteWriter are fairly silly, as they're intended to be high-speed throughput-optimized methods, but if you wanted to e.g.
|
||||||
|
log every single byte on a wire as a separate log message, go ahead; I'm not your dad.
|
||||||
*/
|
*/
|
||||||
package logging
|
package logging
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
`errors`
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -12,6 +12,8 @@ var (
|
|||||||
exists with too restrictive perms to write/append to, and/or could not be created.
|
exists with too restrictive perms to write/append to, and/or could not be created.
|
||||||
*/
|
*/
|
||||||
ErrInvalidFile error = errors.New("a FileLogger was requested but the file does not exist and cannot be created")
|
ErrInvalidFile error = errors.New("a FileLogger was requested but the file does not exist and cannot be created")
|
||||||
|
// ErrInvalidRune is returned if a rune was expected but it is not a valid UTF-8 codepoint.
|
||||||
|
ErrInvalidRune error = errors.New("specified rune is not valid UTF-8 codepoint")
|
||||||
// ErrNoEntry indicates that the user attempted to MultiLogger.RemoveLogger a Logger but one by that identifier does not exist.
|
// ErrNoEntry indicates that the user attempted to MultiLogger.RemoveLogger a Logger but one by that identifier does not exist.
|
||||||
ErrNoEntry error = errors.New("the Logger specified to be removed does not exist")
|
ErrNoEntry error = errors.New("the Logger specified to be removed does not exist")
|
||||||
)
|
)
|
||||||
|
@ -1,9 +1,33 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
ToLog returns a stdlib *log.Logger from a logging.Logger. It simply wraps the (logging.Logger).ToLogger() methods.
|
||||||
|
|
||||||
|
prio is an OR'd logPrio of the Priority* constants.
|
||||||
|
*/
|
||||||
|
func ToLog(l Logger, prio logPrio) (stdLibLog *log.Logger) {
|
||||||
|
|
||||||
|
stdLibLog = l.ToLogger(prio)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRaw returns a *logWriter from a logging.Logger. It is an alternative to the (logging.Logger).ToRaw() methods.
|
||||||
|
func ToRaw(l Logger, prio logPrio) (raw *logWriter) {
|
||||||
|
|
||||||
|
raw = &logWriter{
|
||||||
|
backend: l,
|
||||||
|
prio: prio,
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// testOpen attempts to open a file for writing to test for suitability as a LogFile path.
|
// testOpen attempts to open a file for writing to test for suitability as a LogFile path.
|
||||||
func testOpen(path string) (success bool, err error) {
|
func testOpen(path string) (success bool, err error) {
|
||||||
|
|
||||||
|
@ -223,7 +223,15 @@ func (l *FileLogger) Warning(s string, v ...interface{}) (err error) {
|
|||||||
// ToLogger returns a stdlib log.Logger.
|
// ToLogger returns a stdlib log.Logger.
|
||||||
func (l *FileLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
func (l *FileLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
||||||
|
|
||||||
stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)
|
stdLibLog = log.New(l.ToRaw(prio), "", 0)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRaw returns a *logWriter.
|
||||||
|
func (l *FileLogger) ToRaw(prio logPrio) (raw *logWriter) {
|
||||||
|
|
||||||
|
raw = &logWriter{backend: l, prio: prio}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,34 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
`r00t2.io/goutils/multierr`
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"r00t2.io/goutils/multierr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Write writes bytes b to the underlying Logger's priority level if the logWriter's priority level(s) match.
|
/*
|
||||||
|
Close calls Logger.Shutdown() on the underlying Logger.
|
||||||
|
The Logger *must not be used* after this; it will need to be re-initialized with Logger.Setup()
|
||||||
|
or a new Logger (and thuse new logWriter) must be created to replace it.
|
||||||
|
|
||||||
|
It (along with logWriter.Write()) conforms to WriteCloser().
|
||||||
|
*/
|
||||||
|
func (l *logWriter) Close() (err error) {
|
||||||
|
|
||||||
|
if err = l.backend.Shutdown(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write writes bytes b to the underlying Logger's priority level if the logWriter's priority level(s) match.
|
||||||
|
It conforms to io.Writer. n will *always* == len(b) on success, because otherwise n would technically be >= len(b)
|
||||||
|
(if multiple priorities are enabled), which is undefined behavior per io.Writer.
|
||||||
|
|
||||||
|
b is converted to a string to normalize to the underlying Logger.
|
||||||
|
*/
|
||||||
func (l *logWriter) Write(b []byte) (n int, err error) {
|
func (l *logWriter) Write(b []byte) (n int, err error) {
|
||||||
|
|
||||||
var s string
|
var s string
|
||||||
@ -70,5 +94,116 @@ func (l *logWriter) Write(b []byte) (n int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n = len(b)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
WriteByte conforms a logWriter to an io.ByteWriter. (It just wraps logWriter.Write().)
|
||||||
|
You should probably never use this; the logging overhead/prefix is going to be more data than the single byte itself.
|
||||||
|
|
||||||
|
c is converted to a string to normalize to the underlying Logger.
|
||||||
|
*/
|
||||||
|
func (l *logWriter) WriteByte(c byte) (err error) {
|
||||||
|
|
||||||
|
if _, err = l.Write([]byte{c}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
WriteRune follows the same signature of (bytes.Buffer).WriteRune() and (bufio.Writer).WriteRune(); thus if `io` ever defines an io.RuneWriter interface, here ya go.
|
||||||
|
|
||||||
|
n will *always* be equal to (unicode/utf8).RuneLen(r), unless r is an "invalid rune" -- in which case n will be 0 and err will be ErrInvalidRune..
|
||||||
|
*/
|
||||||
|
func (l *logWriter) WriteRune(r rune) (n int, err error) {
|
||||||
|
|
||||||
|
var b []byte
|
||||||
|
|
||||||
|
n = utf8.RuneLen(r)
|
||||||
|
if n < 0 {
|
||||||
|
err = ErrInvalidRune
|
||||||
|
n = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
b = make([]byte, n)
|
||||||
|
utf8.EncodeRune(b, r)
|
||||||
|
|
||||||
|
if n, err = l.Write(b); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
WriteString writes string s to the underlying Logger's priority level if the logWriter's priority level(s) match.
|
||||||
|
It conforms to io.StringWriter. n will *always* == len(s) on success, because otherwise n would technically be >= len(s)
|
||||||
|
(if multiple priorities are enabled), which is undefined behavior per io.StringWriter.
|
||||||
|
*/
|
||||||
|
func (l *logWriter) WriteString(s string) (n int, err error) {
|
||||||
|
|
||||||
|
var mErr *multierr.MultiError = multierr.NewMultiError(nil)
|
||||||
|
|
||||||
|
if l.prio.HasFlag(PriorityEmergency) {
|
||||||
|
if err = l.backend.Emerg(s); err != nil {
|
||||||
|
mErr.AddError(err)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.prio.HasFlag(PriorityAlert) {
|
||||||
|
if err = l.backend.Alert(s); err != nil {
|
||||||
|
mErr.AddError(err)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.prio.HasFlag(PriorityCritical) {
|
||||||
|
if err = l.backend.Crit(s); err != nil {
|
||||||
|
mErr.AddError(err)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.prio.HasFlag(PriorityError) {
|
||||||
|
if err = l.backend.Err(s); err != nil {
|
||||||
|
mErr.AddError(err)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.prio.HasFlag(PriorityWarning) {
|
||||||
|
if err = l.backend.Warning(s); err != nil {
|
||||||
|
mErr.AddError(err)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.prio.HasFlag(PriorityNotice) {
|
||||||
|
if err = l.backend.Notice(s); err != nil {
|
||||||
|
mErr.AddError(err)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.prio.HasFlag(PriorityInformational) {
|
||||||
|
if err = l.backend.Info(s); err != nil {
|
||||||
|
mErr.AddError(err)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l.prio.HasFlag(PriorityDebug) {
|
||||||
|
if err = l.backend.Debug(s); err != nil {
|
||||||
|
mErr.AddError(err)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !mErr.IsEmpty() {
|
||||||
|
err = mErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
n = len(s)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package logging
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
`log`
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"r00t2.io/goutils/multierr"
|
"r00t2.io/goutils/multierr"
|
||||||
@ -375,7 +375,15 @@ func (m *MultiLogger) Warning(s string, v ...interface{}) (err error) {
|
|||||||
// ToLogger returns a stdlib log.Logger.
|
// ToLogger returns a stdlib log.Logger.
|
||||||
func (m *MultiLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
func (m *MultiLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
||||||
|
|
||||||
stdLibLog = log.New(&logWriter{backend: m, prio: prio}, "", 0)
|
stdLibLog = log.New(m.ToRaw(prio), "", 0)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRaw returns a *logWriter.
|
||||||
|
func (m *MultiLogger) ToRaw(prio logPrio) (raw *logWriter) {
|
||||||
|
|
||||||
|
raw = &logWriter{backend: m, prio: prio}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
`log`
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setup does nothing at all; it's here for interface compat. 🙃
|
// Setup does nothing at all; it's here for interface compat. 🙃
|
||||||
@ -84,3 +84,11 @@ func (l *NullLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToRaw returns a *logWriter. (This is a little less efficient than using ToLogger's log.Logger as an io.Writer if that's all you need.)
|
||||||
|
func (l *NullLogger) ToRaw(prio logPrio) (raw *logWriter) {
|
||||||
|
|
||||||
|
raw = &logWriter{backend: l, prio: prio}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
// nulLWriter writes... nothing. To avoid errors, however, in downstream code it pretends it does (n will *always* == len(b)).
|
import (
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Close conforms a nullWriter to an io.WriteCloser. It obviously does nothing, and will always return with err == nil.
|
||||||
|
func (nw *nullWriter) Close() (err error) {
|
||||||
|
|
||||||
|
// NO-OP
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write conforms a nullWriter to an io.Writer, but it writes... nothing. To avoid errors, however, in downstream code it pretends it does (n will *always* == len(b)).
|
||||||
func (nw *nullWriter) Write(b []byte) (n int, err error) {
|
func (nw *nullWriter) Write(b []byte) (n int, err error) {
|
||||||
|
|
||||||
if b == nil {
|
if b == nil {
|
||||||
@ -10,3 +22,37 @@ func (nw *nullWriter) Write(b []byte) (n int, err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteByte conforms to an io.ByteWriter but again... nothing is actually written anywhere.
|
||||||
|
func (nw *nullWriter) WriteByte(c byte) (err error) {
|
||||||
|
|
||||||
|
// NO-OP
|
||||||
|
|
||||||
|
_ = c
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
WriteRune conforms to the other Loggers. It WILL return the proper value for n (matching (bytes.Buffer).WriteRune() and (bufio.Writer).WriteRune() signatures,
|
||||||
|
and it WILL return an ErrInvalidRune if r is not a valid rune, but otherwise it will no-op.
|
||||||
|
*/
|
||||||
|
func (nw *nullWriter) WriteRune(r rune) (n int, err error) {
|
||||||
|
|
||||||
|
n = utf8.RuneLen(r)
|
||||||
|
if n < 0 {
|
||||||
|
err = ErrInvalidRune
|
||||||
|
n = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteString conforms to an io.StringWriter but nothing is actually written. (n will *always* == len(s))
|
||||||
|
func (nw *nullWriter) WriteString(s string) (n int, err error) {
|
||||||
|
|
||||||
|
n = len(s)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -235,6 +235,22 @@ func (l *StdLogger) Warning(s string, v ...interface{}) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToLogger returns a stdlib log.Logger.
|
||||||
|
func (l *StdLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
||||||
|
|
||||||
|
stdLibLog = log.New(l.ToRaw(prio), "", 0)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRaw returns a *logWriter.
|
||||||
|
func (l *StdLogger) ToRaw(prio logPrio) (raw *logWriter) {
|
||||||
|
|
||||||
|
raw = &logWriter{backend: l, prio: prio}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// renderWrite prepares/formats a log message to be written to this StdLogger.
|
// renderWrite prepares/formats a log message to be written to this StdLogger.
|
||||||
func (l *StdLogger) renderWrite(msg, prio string) {
|
func (l *StdLogger) renderWrite(msg, prio string) {
|
||||||
|
|
||||||
@ -244,11 +260,3 @@ func (l *StdLogger) renderWrite(msg, prio string) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToLogger returns a stdlib log.Logger.
|
|
||||||
func (l *StdLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
|
||||||
|
|
||||||
stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
@ -227,7 +227,15 @@ func (l *SystemDLogger) renderWrite(msg string, prio journal.Priority) {
|
|||||||
// ToLogger returns a stdlib log.Logger.
|
// ToLogger returns a stdlib log.Logger.
|
||||||
func (l *SystemDLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
func (l *SystemDLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
||||||
|
|
||||||
stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)
|
stdLibLog = log.New(l.ToRaw(prio), "", 0)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRaw returns a *logWriter.
|
||||||
|
func (l *SystemDLogger) ToRaw(prio logPrio) (raw *logWriter) {
|
||||||
|
|
||||||
|
raw = &logWriter{backend: l, prio: prio}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,15 @@ func (l *SyslogLogger) Warning(s string, v ...interface{}) (err error) {
|
|||||||
// ToLogger returns a stdlib log.Logger.
|
// ToLogger returns a stdlib log.Logger.
|
||||||
func (l *SyslogLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
func (l *SyslogLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
||||||
|
|
||||||
stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)
|
stdLibLog = log.New(l.ToRaw(prio), "", 0)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRaw returns a *logWriter.
|
||||||
|
func (l *SyslogLogger) ToRaw(prio logPrio) (raw *logWriter) {
|
||||||
|
|
||||||
|
raw = &logWriter{backend: l, prio: prio}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package logging
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
`log`
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -347,7 +347,15 @@ func (l *WinLogger) Warning(s string, v ...interface{}) (err error) {
|
|||||||
// ToLogger returns a stdlib log.Logger.
|
// ToLogger returns a stdlib log.Logger.
|
||||||
func (l *WinLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
func (l *WinLogger) ToLogger(prio logPrio) (stdLibLog *log.Logger) {
|
||||||
|
|
||||||
stdLibLog = log.New(&logWriter{backend: l, prio: prio}, "", 0)
|
stdLibLog = log.New(l.ToRaw(prio), "", 0)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRaw returns a *logWriter.
|
||||||
|
func (l *WinLogger) ToRaw(prio logPrio) (raw *logWriter) {
|
||||||
|
|
||||||
|
raw = &logWriter{backend: l, prio: prio}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
`r00t2.io/goutils/bitmask`
|
"r00t2.io/goutils/bitmask"
|
||||||
)
|
)
|
||||||
|
|
||||||
type logPrio bitmask.MaskBit
|
type logPrio bitmask.MaskBit
|
||||||
@ -28,6 +28,7 @@ type Logger interface {
|
|||||||
Setup() (err error)
|
Setup() (err error)
|
||||||
Shutdown() (err error)
|
Shutdown() (err error)
|
||||||
ToLogger(prio logPrio) (stdLibLog *log.Logger)
|
ToLogger(prio logPrio) (stdLibLog *log.Logger)
|
||||||
|
ToRaw(prio logPrio) (raw *logWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user