format.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package formatter
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "text/template"
  7. "time"
  8. "gopkg.in/mcuadros/go-syslog.v2/format"
  9. "gopkg.in/mgo.v2/bson"
  10. )
  11. // Formatter is an interface, so that multiple implementations can exist
  12. type Formatter func(format.LogParts) string
  13. var tmplFuncs template.FuncMap
  14. var syslogTmpl *template.Template
  15. func init() {
  16. tmplFuncs := template.FuncMap{
  17. "dateFormat": func(dt time.Time, fmt string) string {
  18. return dt.Format(fmt)
  19. },
  20. "rfc822": func(dt time.Time) string {
  21. return dt.Format(time.RFC822)
  22. },
  23. }
  24. syslogTmpl = template.Must(template.New("syslog").Funcs(tmplFuncs).Parse(
  25. "{{rfc822 (index . \"timestamp\")}} {{index . \"hostname\"}} " +
  26. "{{index . \"app_name\"}}" +
  27. "{{ if (ne (index . \"proc_id\") \"-\")}}[{{index . \"proc_id\"}}]{{end}}: " +
  28. "{{index . \"message\"}}",
  29. ))
  30. }
  31. type Format int
  32. func (rf *Format) Set(v string) error {
  33. newvalue, err := parseFormat(v)
  34. if err != nil {
  35. return err
  36. }
  37. *rf = newvalue
  38. return nil
  39. }
  40. func (rf Format) String() string {
  41. switch rf {
  42. case FormatJSON:
  43. return "json"
  44. case FormatSyslog:
  45. return "syslog"
  46. case FormatBSON:
  47. return "bson"
  48. }
  49. return ""
  50. }
  51. func (rf Format) WriteFormatted(w io.Writer, msg format.LogParts) error {
  52. return WriteFormatted(w, rf, msg)
  53. }
  54. func parseFormat(s string) (Format, error) {
  55. switch s {
  56. case "json":
  57. return FormatJSON, nil
  58. case "syslog":
  59. return FormatSyslog, nil
  60. case "bson":
  61. return FormatBSON, nil
  62. default:
  63. return 0, fmt.Errorf("Undefined format `%s`", s)
  64. }
  65. }
  66. const (
  67. FormatSyslog = iota // 0
  68. FormatJSON = iota
  69. FormatBSON = iota
  70. )
  71. func WriteFormatted(w io.Writer, f Format, msg format.LogParts) error {
  72. switch f {
  73. case FormatSyslog:
  74. return syslogTmpl.Execute(w, msg)
  75. case FormatJSON:
  76. enc := json.NewEncoder(w)
  77. enc.SetIndent("", " ")
  78. return enc.Encode(msg)
  79. case FormatBSON:
  80. enc, err := bson.Marshal(msg)
  81. if err != nil {
  82. return err
  83. }
  84. _, err = w.Write(enc)
  85. return err
  86. }
  87. return nil
  88. }