111 lines
2.3 KiB
Go
111 lines
2.3 KiB
Go
|
// Based on https://github.com/gogap/logrus_mate under License Apache License 2.0
|
||
|
package file
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/juju/errors"
|
||
|
"github.com/sirupsen/logrus"
|
||
|
)
|
||
|
|
||
|
func NewHook(c *ConfigStruct) (logrus.Hook, error) {
|
||
|
|
||
|
c.ApplyDefault()
|
||
|
|
||
|
err := c.IsValid()
|
||
|
if err != nil {
|
||
|
return nil, errors.Trace(err)
|
||
|
}
|
||
|
|
||
|
dir := filepath.Dir(c.Filename)
|
||
|
|
||
|
err = os.MkdirAll(dir, 0755)
|
||
|
if err != nil {
|
||
|
return nil, nil
|
||
|
}
|
||
|
|
||
|
w, err := InitFileLogWriter(c)
|
||
|
if err != nil {
|
||
|
return nil, errors.Trace(err)
|
||
|
}
|
||
|
|
||
|
return &FileHook{W: w}, nil
|
||
|
}
|
||
|
|
||
|
type FileHook struct {
|
||
|
W *fileLogWriter
|
||
|
}
|
||
|
|
||
|
func (p *FileHook) Fire(entry *logrus.Entry) (err error) {
|
||
|
message, err := getMessage(entry)
|
||
|
|
||
|
if err != nil {
|
||
|
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
now := time.Now()
|
||
|
|
||
|
switch entry.Level {
|
||
|
case logrus.PanicLevel:
|
||
|
fallthrough
|
||
|
case logrus.FatalLevel:
|
||
|
fallthrough
|
||
|
case logrus.ErrorLevel:
|
||
|
return p.W.WriteMsg(now, fmt.Sprintf("[ERROR] %s", message), LevelError)
|
||
|
case logrus.WarnLevel:
|
||
|
return p.W.WriteMsg(now, fmt.Sprintf("[WARN] %s", message), LevelWarn)
|
||
|
case logrus.InfoLevel:
|
||
|
return p.W.WriteMsg(now, fmt.Sprintf("[INFO] %s", message), LevelInfo)
|
||
|
case logrus.DebugLevel:
|
||
|
return p.W.WriteMsg(now, fmt.Sprintf("[DEBUG] %s", message), LevelDebug)
|
||
|
default:
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (p *FileHook) Levels() []logrus.Level {
|
||
|
return []logrus.Level{
|
||
|
logrus.PanicLevel,
|
||
|
logrus.FatalLevel,
|
||
|
logrus.ErrorLevel,
|
||
|
logrus.WarnLevel,
|
||
|
logrus.InfoLevel,
|
||
|
logrus.DebugLevel,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func getMessage(entry *logrus.Entry) (message string, err error) {
|
||
|
message = message + fmt.Sprintf("%s", entry.Message)
|
||
|
for k, v := range entry.Data {
|
||
|
if !strings.HasPrefix(k, "err_") {
|
||
|
message = message + fmt.Sprintf("\n%v:%v", k, v)
|
||
|
}
|
||
|
}
|
||
|
if errCode, exist := entry.Data["err_code"]; exist {
|
||
|
|
||
|
ns, _ := entry.Data["err_ns"]
|
||
|
ctx, _ := entry.Data["err_ctx"]
|
||
|
id, _ := entry.Data["err_id"]
|
||
|
tSt, _ := entry.Data["err_stack"]
|
||
|
st, _ := tSt.(string)
|
||
|
st = strings.Replace(st, "\n", "\n\t\t", -1)
|
||
|
|
||
|
buf := bytes.NewBuffer(nil)
|
||
|
buf.WriteString(fmt.Sprintf("\tid:\n\t\t%s#%d:%s\n", ns, errCode, id))
|
||
|
buf.WriteString(fmt.Sprintf("\tcontext:\n\t\t%s\n", ctx))
|
||
|
buf.WriteString(fmt.Sprintf("\tstacktrace:\n\t\t%s", st))
|
||
|
|
||
|
message = message + fmt.Sprintf("%v", buf.String())
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|