89 lines
1.8 KiB
Go
89 lines
1.8 KiB
Go
|
package ffiselect
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"bytes"
|
||
|
"io"
|
||
|
"regexp"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
logging "github.com/ipfs/go-log/v2"
|
||
|
"go.uber.org/zap"
|
||
|
)
|
||
|
|
||
|
var log = logging.Logger("ffiselect")
|
||
|
|
||
|
type LogWriter struct {
|
||
|
ctx []any
|
||
|
errOut io.Writer
|
||
|
re *regexp.Regexp
|
||
|
}
|
||
|
|
||
|
func NewLogWriter(logctx []any, errOut io.Writer) *LogWriter {
|
||
|
re := regexp.MustCompile(`^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3})\s+(\w+)\s+(.*)$`)
|
||
|
return &LogWriter{
|
||
|
ctx: logctx,
|
||
|
errOut: errOut,
|
||
|
re: re,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (lw *LogWriter) Write(p []byte) (n int, err error) {
|
||
|
reader := bufio.NewReader(bytes.NewReader(p))
|
||
|
for {
|
||
|
line, err := reader.ReadBytes('\n')
|
||
|
if err == io.EOF {
|
||
|
break
|
||
|
}
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
|
||
|
lineStr := string(line)
|
||
|
// trim trailing \n
|
||
|
lineStr = strings.TrimSpace(lineStr)
|
||
|
|
||
|
matches := lw.re.FindStringSubmatch(lineStr)
|
||
|
if matches == nil {
|
||
|
// Line didn't match the expected format, write it to stderr as-is
|
||
|
_, err := lw.errOut.Write(line)
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
timestamp, logLevel, message := matches[1], matches[2], matches[3]
|
||
|
logTime, err := time.Parse("2006-01-02T15:04:05.000", timestamp)
|
||
|
if err != nil {
|
||
|
_, err := lw.errOut.Write(line)
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
var zapLevel zap.AtomicLevel
|
||
|
switch logLevel {
|
||
|
case "DEBUG":
|
||
|
zapLevel = zap.NewAtomicLevelAt(zap.DebugLevel)
|
||
|
case "INFO":
|
||
|
zapLevel = zap.NewAtomicLevelAt(zap.InfoLevel)
|
||
|
case "WARN":
|
||
|
zapLevel = zap.NewAtomicLevelAt(zap.WarnLevel)
|
||
|
case "ERROR":
|
||
|
zapLevel = zap.NewAtomicLevelAt(zap.ErrorLevel)
|
||
|
default:
|
||
|
_, err := lw.errOut.Write(line)
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
log.With(zap.Time("timestamp", logTime)).Logw(zapLevel.Level(), message, lw.ctx...)
|
||
|
}
|
||
|
return len(p), nil
|
||
|
}
|