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) }, } 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}}: " + "{{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 }