diff --git a/go.mod b/go.mod index 1c8209a9..0d60d6ef 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/stretchr/testify v1.8.4 golang.org/x/crypto v0.11.0 golang.org/x/net v0.12.0 + golang.org/x/term v0.10.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 2fda2732..6f4ff740 100644 --- a/go.sum +++ b/go.sum @@ -255,6 +255,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/internal/logger/destination.go b/internal/logger/destination.go index 7d8ff999..b4874292 100644 --- a/internal/logger/destination.go +++ b/internal/logger/destination.go @@ -1,5 +1,9 @@ package logger +import ( + "time" +) + // Destination is a log destination. type Destination int @@ -15,6 +19,6 @@ const ( ) type destination interface { - log(Level, string, ...interface{}) + log(time.Time, Level, string, ...interface{}) close() } diff --git a/internal/logger/destination_file.go b/internal/logger/destination_file.go index d7ff145a..d40c91d8 100644 --- a/internal/logger/destination_file.go +++ b/internal/logger/destination_file.go @@ -3,6 +3,7 @@ package logger import ( "bytes" "os" + "time" ) type destinationFile struct { @@ -21,9 +22,9 @@ func newDestinationFile(filePath string) (destination, error) { }, nil } -func (d *destinationFile) log(level Level, format string, args ...interface{}) { +func (d *destinationFile) log(t time.Time, level Level, format string, args ...interface{}) { d.buf.Reset() - writeTime(&d.buf, false) + writeTime(&d.buf, t, false) writeLevel(&d.buf, level, false) writeContent(&d.buf, format, args) d.file.Write(d.buf.Bytes()) diff --git a/internal/logger/destination_stdout.go b/internal/logger/destination_stdout.go index 98a0a43d..95f76c48 100644 --- a/internal/logger/destination_stdout.go +++ b/internal/logger/destination_stdout.go @@ -3,20 +3,27 @@ package logger import ( "bytes" "os" + "time" + + "golang.org/x/term" ) type destinationStdout struct { + useColor bool + buf bytes.Buffer } func newDestionationStdout() destination { - return &destinationStdout{} + return &destinationStdout{ + useColor: term.IsTerminal(int(os.Stdout.Fd())), + } } -func (d *destinationStdout) log(level Level, format string, args ...interface{}) { +func (d *destinationStdout) log(t time.Time, level Level, format string, args ...interface{}) { d.buf.Reset() - writeTime(&d.buf, true) - writeLevel(&d.buf, level, true) + writeTime(&d.buf, t, d.useColor) + writeLevel(&d.buf, level, d.useColor) writeContent(&d.buf, format, args) os.Stdout.Write(d.buf.Bytes()) } diff --git a/internal/logger/destination_syslog.go b/internal/logger/destination_syslog.go index c6e8faed..1798b1a9 100644 --- a/internal/logger/destination_syslog.go +++ b/internal/logger/destination_syslog.go @@ -3,6 +3,7 @@ package logger import ( "bytes" "io" + "time" ) type destinationSysLog struct { @@ -21,9 +22,9 @@ func newDestinationSyslog() (destination, error) { }, nil } -func (d *destinationSysLog) log(level Level, format string, args ...interface{}) { +func (d *destinationSysLog) log(t time.Time, level Level, format string, args ...interface{}) { d.buf.Reset() - writeTime(&d.buf, false) + writeTime(&d.buf, t, false) writeLevel(&d.buf, level, false) writeContent(&d.buf, format, args) d.syslog.Write(d.buf.Bytes()) diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 80952193..92afe356 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -74,12 +74,11 @@ func itoa(i int, wid int) []byte { return b[bp:] } -func writeTime(buf *bytes.Buffer, doColor bool) { +func writeTime(buf *bytes.Buffer, t time.Time, useColor bool) { var intbuf bytes.Buffer // date - now := time.Now() - year, month, day := now.Date() + year, month, day := t.Date() intbuf.Write(itoa(year, 4)) intbuf.WriteByte('/') intbuf.Write(itoa(int(month), 2)) @@ -88,7 +87,7 @@ func writeTime(buf *bytes.Buffer, doColor bool) { intbuf.WriteByte(' ') // time - hour, min, sec := now.Clock() + hour, min, sec := t.Clock() intbuf.Write(itoa(hour, 2)) intbuf.WriteByte(':') intbuf.Write(itoa(min, 2)) @@ -96,38 +95,38 @@ func writeTime(buf *bytes.Buffer, doColor bool) { intbuf.Write(itoa(sec, 2)) intbuf.WriteByte(' ') - if doColor { + if useColor { buf.WriteString(color.RenderString(color.Gray.Code(), intbuf.String())) } else { buf.WriteString(intbuf.String()) } } -func writeLevel(buf *bytes.Buffer, level Level, doColor bool) { +func writeLevel(buf *bytes.Buffer, level Level, useColor bool) { switch level { case Debug: - if doColor { + if useColor { buf.WriteString(color.RenderString(color.Debug.Code(), "DEB")) } else { buf.WriteString("DEB") } case Info: - if doColor { + if useColor { buf.WriteString(color.RenderString(color.Green.Code(), "INF")) } else { buf.WriteString("INF") } case Warn: - if doColor { + if useColor { buf.WriteString(color.RenderString(color.Warn.Code(), "WAR")) } else { buf.WriteString("WAR") } case Error: - if doColor { + if useColor { buf.WriteString(color.RenderString(color.Error.Code(), "ERR")) } else { buf.WriteString("ERR") @@ -150,7 +149,9 @@ func (lh *Logger) Log(level Level, format string, args ...interface{}) { lh.mutex.Lock() defer lh.mutex.Unlock() + t := time.Now() + for _, dest := range lh.destinations { - dest.log(level, format, args...) + dest.log(t, level, format, args...) } }