|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"regexp"
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/hrfee/jfa-go/linecache"
|
|
|
|
)
|
|
|
|
|
|
|
|
var logPath string = filepath.Join(temp, "jfa-go.log")
|
|
|
|
var lineCache = linecache.NewLineCache(100)
|
|
|
|
|
|
|
|
func logOutput() (closeFunc func()) {
|
|
|
|
old := os.Stdout
|
|
|
|
writers := []io.Writer{old, colorStripper{lineCache}}
|
|
|
|
wExit := make(chan bool)
|
|
|
|
r, w, _ := os.Pipe()
|
|
|
|
if TRAY {
|
|
|
|
log.Printf("Logging to \"%s\"", logPath)
|
|
|
|
f, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
|
|
|
if err != nil {
|
|
|
|
closeFunc = func() {}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
writers = append(writers, colorStripper{f})
|
|
|
|
closeFunc = func() {
|
|
|
|
w.Close()
|
|
|
|
<-wExit
|
|
|
|
f.Close()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
closeFunc = func() {
|
|
|
|
w.Close()
|
|
|
|
<-wExit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
writer := io.MultiWriter(writers...)
|
|
|
|
// FIXME: Potential cause if last log line doesn't get printed sometimes.
|
|
|
|
os.Stdout, os.Stderr = w, w
|
|
|
|
log.SetOutput(writer)
|
|
|
|
gin.DefaultWriter, gin.DefaultErrorWriter = writer, writer
|
|
|
|
go func() {
|
|
|
|
io.Copy(writer, r)
|
|
|
|
wExit <- true
|
|
|
|
}()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Regex that removes ANSI color escape sequences. Used for outputting to log file and log cache.
|
|
|
|
var stripColors = func() *regexp.Regexp {
|
|
|
|
r, err := regexp.Compile("\\x1b\\[[0-9;]*m")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Failed to compile color escape regexp: %v", err)
|
|
|
|
}
|
|
|
|
return r
|
|
|
|
}()
|
|
|
|
|
|
|
|
type colorStripper struct {
|
|
|
|
file io.Writer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c colorStripper) Write(p []byte) (n int, err error) {
|
|
|
|
_, err = c.file.Write(stripColors.ReplaceAll(p, []byte("")))
|
|
|
|
n = len(p)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func sanitizeLog(l string) string {
|
|
|
|
quoteCensor, err := regexp.Compile("\"([^\"]*)\"")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("Failed to compile sanitizing regexp: %v", err)
|
|
|
|
}
|
|
|
|
return string(quoteCensor.ReplaceAll([]byte(l), []byte("\"CENSORED\"")))
|
|
|
|
}
|