c1f99c58c5
* started * so far so good * builds and looks good * changing level of abstration. some work remains * it builds * betterment * import order * 2 * stupid linter - you can cast a nil * build commit and date * nicer * tmp and nide makefile * comments handled * oops * added debug and reg * ffiselect: change err encode to strings, fix some bugs * ffiselect: Wrap rust logs into go-log * ffiselect: Make the linter happy * verification tests * ffiselect: Fix startup --------- Co-authored-by: Łukasz Magiera <magik6k@gmail.com>
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
|
|
}
|