From 35a7644ee68710ae3a2f4415b59db6149e872a50 Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Tue, 27 Apr 2021 21:24:00 +0200 Subject: [PATCH] add colors to terminal output --- go.mod | 1 + go.sum | 6 ++ internal/logger/logger.go | 134 +++++++++++++++++++++++++------------- 3 files changed, 94 insertions(+), 47 deletions(-) diff --git a/go.mod b/go.mod index aa7894d2..8e26f09e 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/asticode/go-astits v0.0.0-00010101000000-000000000000 github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.4.9 + github.com/gookit/color v1.4.2 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/notedit/rtmp v0.0.2 github.com/pion/rtp v1.6.2 diff --git a/go.sum b/go.sum index b9b7137e..2482e68d 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gookit/color v1.4.2 h1:tXy44JFSFkKnELV6WaMo/lLfu/meqITX3iAV52do7lk= +github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/icza/bitio v1.0.0 h1:squ/m1SHyFeCA6+6Gyol1AxV9nmPPlJFT8c2vKdj3U8= github.com/icza/bitio v1.0.0/go.mod h1:0jGnlLAx8MKMr9VGnn/4YrvZiprkvBelsVIbA9Jjr9A= github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k= @@ -40,6 +42,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -49,6 +53,8 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 57b74ed6..5a94b904 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -1,11 +1,14 @@ package logger import ( + "bytes" "fmt" "io" "os" "sync" "time" + + "github.com/gookit/color" ) // Level is a log level. @@ -36,11 +39,13 @@ const ( type Logger struct { level Level destinations map[Destination]struct{} - mutex sync.Mutex - buffer []byte - file *os.File - syslog io.WriteCloser + mutex sync.Mutex + file *os.File + syslog io.WriteCloser + stdoutBuffer bytes.Buffer + fileBuffer bytes.Buffer + syslogBuffer bytes.Buffer } // New allocates a log handler. @@ -83,7 +88,7 @@ func (lh *Logger) Close() { } // https://golang.org/src/log/log.go#L78 -func itoa(buf *[]byte, i int, wid int) { +func itoa(i int, wid int) []byte { // Assemble decimal in reverse order. var b [20]byte bp := len(b) - 1 @@ -96,7 +101,66 @@ func itoa(buf *[]byte, i int, wid int) { } // i < 10 b[bp] = byte('0' + i) - *buf = append(*buf, b[bp:]...) + return b[bp:] +} + +func writeTime(buf *bytes.Buffer, doColor bool) { + var intbuf bytes.Buffer + + // date + now := time.Now() + year, month, day := now.Date() + intbuf.Write(itoa(year, 4)) + intbuf.WriteByte('/') + intbuf.Write(itoa(int(month), 2)) + intbuf.WriteByte('/') + intbuf.Write(itoa(day, 2)) + intbuf.WriteByte(' ') + + // time + hour, min, sec := now.Clock() + intbuf.Write(itoa(hour, 2)) + intbuf.WriteByte(':') + intbuf.Write(itoa(min, 2)) + intbuf.WriteByte(':') + intbuf.Write(itoa(sec, 2)) + intbuf.WriteByte(' ') + + if doColor { + buf.WriteString(color.RenderString(color.Gray.Code(), intbuf.String())) + } else { + buf.WriteString(intbuf.String()) + } +} + +func writeLevel(buf *bytes.Buffer, level Level, doColor bool) { + switch level { + case Debug: + if doColor { + buf.WriteString(color.RenderString(color.Debug.Code(), "D ")) + } else { + buf.WriteString("D ") + } + + case Info: + if doColor { + buf.WriteString(color.RenderString(color.Green.Code(), "I ")) + } else { + buf.WriteString("I ") + } + + case Warn: + if doColor { + buf.WriteString(color.RenderString(color.Warn.Code(), "W ")) + } else { + buf.WriteString("W ") + } + } +} + +func writeContent(buf *bytes.Buffer, format string, args []interface{}) { + buf.Write([]byte(fmt.Sprintf(format, args...))) + buf.WriteByte('\n') } // Log writes a log entry. @@ -108,51 +172,27 @@ func (lh *Logger) Log(level Level, format string, args ...interface{}) { lh.mutex.Lock() defer lh.mutex.Unlock() - lh.buffer = lh.buffer[:0] - - // date - now := time.Now() - year, month, day := now.Date() - itoa(&lh.buffer, year, 4) - lh.buffer = append(lh.buffer, '/') - itoa(&lh.buffer, int(month), 2) - lh.buffer = append(lh.buffer, '/') - itoa(&lh.buffer, day, 2) - lh.buffer = append(lh.buffer, ' ') - - // time - hour, min, sec := now.Clock() - itoa(&lh.buffer, hour, 2) - lh.buffer = append(lh.buffer, ':') - itoa(&lh.buffer, min, 2) - lh.buffer = append(lh.buffer, ':') - itoa(&lh.buffer, sec, 2) - lh.buffer = append(lh.buffer, ' ') - - // level - switch level { - case Debug: - lh.buffer = append(lh.buffer, "[D] "...) - - case Info: - lh.buffer = append(lh.buffer, "[I] "...) - - case Warn: - lh.buffer = append(lh.buffer, "[W] "...) - } - - // content - lh.buffer = append(lh.buffer, fmt.Sprintf(format, args...)...) - lh.buffer = append(lh.buffer, '\n') - - // output if _, ok := lh.destinations[DestinationStdout]; ok { - print(string(lh.buffer)) + lh.stdoutBuffer.Reset() + writeTime(&lh.stdoutBuffer, true) + writeLevel(&lh.stdoutBuffer, level, true) + writeContent(&lh.stdoutBuffer, format, args) + print(lh.stdoutBuffer.String()) } + if _, ok := lh.destinations[DestinationFile]; ok { - lh.file.Write(lh.buffer) + lh.fileBuffer.Reset() + writeTime(&lh.fileBuffer, false) + writeLevel(&lh.fileBuffer, level, false) + writeContent(&lh.fileBuffer, format, args) + lh.file.Write(lh.fileBuffer.Bytes()) } + if _, ok := lh.destinations[DestinationSyslog]; ok { - lh.syslog.Write(lh.buffer) + lh.syslogBuffer.Reset() + writeTime(&lh.syslogBuffer, false) + writeLevel(&lh.syslogBuffer, level, false) + writeContent(&lh.syslogBuffer, format, args) + lh.syslog.Write(lh.syslogBuffer.Bytes()) } }