package log import ( "bytes" "encoding/json" "fmt" "os" "path/filepath" "sync" "time" ) // JSONFormatter is a json formatter type JSONFormatter struct { AppName string TimeFormat string init sync.Once host string pid int } // Format implements log.Formatter func (f *JSONFormatter) Format(level Level, msg string, logger *Logger) []byte { // output fields: time level host app pid file line msg f.init.Do(func() { if f.AppName == "" { f.AppName = filepath.Base(os.Args[0]) } if f.TimeFormat == "" { f.TimeFormat = "2006-01-02T15:04:05.000-0700" } f.host, _ = os.Hostname() f.pid = os.Getpid() }) data := make(map[string]interface{}, 8) // file, line file, line := FilelineCaller(4) data["time"] = time.Now().Format(f.TimeFormat) data["level"] = level.String() data["host"] = f.host data["app"] = f.AppName data["pid"] = f.pid data["file"] = file data["line"] = line data["msg"] = msg serialized, err := marshal(data) if err != nil { fmt.Fprintf(os.Stderr, "Failed to marshal json, %v\n", err) } return serialized } func marshal(v interface{}) ([]byte, error) { var buf bytes.Buffer encoder := json.NewEncoder(&buf) encoder.SetEscapeHTML(false) err := encoder.Encode(v) if err != nil { return nil, err } return buf.Bytes(), nil }