1
0
Fork 0
forked from boyska/circolog
circolog/formatter/format.go
2019-01-02 13:57:48 +01:00

108 lines
2.2 KiB
Go

package formatter
import (
"encoding/json"
"fmt"
"io"
"text/template"
"time"
"gopkg.in/mcuadros/go-syslog.v2/format"
"gopkg.in/mgo.v2/bson"
)
// Formatter is an interface, so that multiple implementations can exist
type Formatter func(format.LogParts) string
var tmplFuncs template.FuncMap
var syslogTmpl *template.Template
func init() {
tmplFuncs := template.FuncMap{
"dateFormat": func(dt time.Time, fmt string) string {
return dt.Format(fmt)
},
"rfc822": func(dt time.Time) string {
return dt.Format(time.RFC822)
},
"sevName": func(s int) string {
names := []string{"emerg", "alert", "crit", "err", "warn", "notice", "info", "dbg"}
if s >= len(names) {
return "???"
}
return names[s]
},
}
syslogTmpl = template.Must(template.New("syslog").Funcs(tmplFuncs).Parse(
"{{rfc822 (index . \"timestamp\")}} {{index . \"hostname\"}} " +
"{{index . \"app_name\"}}" +
"{{ if (ne (index . \"proc_id\") \"-\")}}[{{index . \"proc_id\"}}]{{end}}: " +
"<{{ sevName (index . \"severity\") }}> " +
"{{index . \"message\"}}",
))
}
type Format int
func (rf *Format) Set(v string) error {
newvalue, err := parseFormat(v)
if err != nil {
return err
}
*rf = newvalue
return nil
}
func (rf Format) String() string {
switch rf {
case FormatJSON:
return "json"
case FormatSyslog:
return "syslog"
case FormatBSON:
return "bson"
}
return ""
}
func (rf Format) WriteFormatted(w io.Writer, msg format.LogParts) error {
return WriteFormatted(w, rf, msg)
}
func parseFormat(s string) (Format, error) {
switch s {
case "json":
return FormatJSON, nil
case "syslog":
return FormatSyslog, nil
case "bson":
return FormatBSON, nil
default:
return 0, fmt.Errorf("Undefined format `%s`", s)
}
}
const (
FormatSyslog = iota // 0
FormatJSON = iota
FormatBSON = iota
)
func WriteFormatted(w io.Writer, f Format, msg format.LogParts) error {
switch f {
case FormatSyslog:
return syslogTmpl.Execute(w, msg)
case FormatJSON:
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
return enc.Encode(msg)
case FormatBSON:
enc, err := bson.Marshal(msg)
if err != nil {
return err
}
_, err = w.Write(enc)
return err
}
return nil
}