enhanced the logger to use color on a tty
This commit is contained in:
@ -1543,11 +1543,11 @@ func (cts *ClientConn) RptyLoop(crp *ClientRpty, wg *sync.WaitGroup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (poll_fds[0].Revents & (unix.POLLERR | unix.POLLHUP | unix.POLLNVAL)) != 0 {
|
if (poll_fds[0].Revents & (unix.POLLERR | unix.POLLHUP | unix.POLLNVAL)) != 0 {
|
||||||
cts.C.log.Write(cts.Sid, LOG_ERROR, "EOF detected on rpty(%d) stdout", crp.id)
|
cts.C.log.Write(cts.Sid, LOG_DEBUG, "EOF detected on rpty(%d) stdout", crp.id)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if (poll_fds[1].Revents & (unix.POLLERR | unix.POLLHUP | unix.POLLNVAL)) != 0 {
|
if (poll_fds[1].Revents & (unix.POLLERR | unix.POLLHUP | unix.POLLNVAL)) != 0 {
|
||||||
cts.C.log.Write(cts.Sid, LOG_ERROR, "EOF detected on rpty(%d) event pipe", crp.id)
|
cts.C.log.Write(cts.Sid, LOG_DEBUG, "EOF detected on rpty(%d) event pipe", crp.id)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import "runtime"
|
|||||||
import "strings"
|
import "strings"
|
||||||
import "sync"
|
import "sync"
|
||||||
import "sync/atomic"
|
import "sync/atomic"
|
||||||
|
import "syscall"
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type app_logger_msg_t struct {
|
type app_logger_msg_t struct {
|
||||||
@ -28,9 +29,28 @@ type AppLogger struct {
|
|||||||
msg_chan chan app_logger_msg_t
|
msg_chan chan app_logger_msg_t
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
|
||||||
|
use_color bool
|
||||||
closed atomic.Bool
|
closed atomic.Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _is_ansi_tty(fd uintptr) bool {
|
||||||
|
var st syscall.Stat_t
|
||||||
|
var err error
|
||||||
|
|
||||||
|
err = syscall.Fstat(int(fd), &st)
|
||||||
|
if err != nil { return false }
|
||||||
|
if (st.Mode & syscall.S_IFMT) == syscall.S_IFCHR {
|
||||||
|
var term string
|
||||||
|
// i assume this fd is bound to the current terminal if it's a character device
|
||||||
|
// if the assumption is wrong, you simply get extraneous ansi code in the output.
|
||||||
|
term = os.Getenv("TERM")
|
||||||
|
if term != "" && term != "dumb" { return true }
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func NewAppLogger (id string, w io.Writer, mask hodu.LogMask) *AppLogger {
|
func NewAppLogger (id string, w io.Writer, mask hodu.LogMask) *AppLogger {
|
||||||
var l *AppLogger
|
var l *AppLogger
|
||||||
l = &AppLogger{
|
l = &AppLogger{
|
||||||
@ -38,6 +58,7 @@ func NewAppLogger (id string, w io.Writer, mask hodu.LogMask) *AppLogger {
|
|||||||
out: w,
|
out: w,
|
||||||
mask: mask,
|
mask: mask,
|
||||||
msg_chan: make(chan app_logger_msg_t, 256),
|
msg_chan: make(chan app_logger_msg_t, 256),
|
||||||
|
use_color: false,
|
||||||
}
|
}
|
||||||
l.closed.Store(false)
|
l.closed.Store(false)
|
||||||
l.wg.Add(1)
|
l.wg.Add(1)
|
||||||
@ -73,6 +94,7 @@ func NewAppLoggerToFile (id string, file_name string, max_size int64, rotate int
|
|||||||
file_max_size: max_size,
|
file_max_size: max_size,
|
||||||
file_rotate: rotate,
|
file_rotate: rotate,
|
||||||
msg_chan: make(chan app_logger_msg_t, 256),
|
msg_chan: make(chan app_logger_msg_t, 256),
|
||||||
|
use_color: _is_ansi_tty(f.Fd()),
|
||||||
}
|
}
|
||||||
l.closed.Store(false)
|
l.closed.Store(false)
|
||||||
l.wg.Add(1)
|
l.wg.Add(1)
|
||||||
@ -169,7 +191,15 @@ func (l *AppLogger) write(id string, level hodu.LogLevel, call_depth int, fmtstr
|
|||||||
}
|
}
|
||||||
sb.WriteString(": ")
|
sb.WriteString(": ")
|
||||||
msg = fmt.Sprintf(fmtstr, args...)
|
msg = fmt.Sprintf(fmtstr, args...)
|
||||||
sb.WriteString(msg)
|
if (l.use_color) {
|
||||||
|
var code string
|
||||||
|
code = l.log_level_to_ansi_code(level)
|
||||||
|
sb.WriteString(code)
|
||||||
|
sb.WriteString(msg)
|
||||||
|
if code != "" { sb.WriteString("\x1B[0m") }
|
||||||
|
} else {
|
||||||
|
sb.WriteString(msg)
|
||||||
|
}
|
||||||
if msg[len(msg) - 1] != '\n' { sb.WriteRune('\n') }
|
if msg[len(msg) - 1] != '\n' { sb.WriteRune('\n') }
|
||||||
|
|
||||||
// use queue to avoid blocking operation as much as possible
|
// use queue to avoid blocking operation as much as possible
|
||||||
@ -211,3 +241,24 @@ func (l *AppLogger) rotate() {
|
|||||||
l.out = l.file
|
l.out = l.file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l* AppLogger) log_level_to_ansi_code(level hodu.LogLevel) string {
|
||||||
|
switch level {
|
||||||
|
case hodu.LOG_ERROR:
|
||||||
|
return "\x1B[31m" // red
|
||||||
|
|
||||||
|
case hodu.LOG_WARN:
|
||||||
|
return "\x1B[33m" // yellow
|
||||||
|
|
||||||
|
case hodu.LOG_INFO:
|
||||||
|
if (l.mask & hodu.LogMask(hodu.LOG_DEBUG)) != 0 {
|
||||||
|
// if debug is enabled, change the color of info.
|
||||||
|
// otherwisse no color
|
||||||
|
return "\x1B[32m" // green
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user