refactor syslog formatting

the goal is making circolog-tail apply formatting "locally", receiving
structured messages instead
This commit is contained in:
boyska 2018-11-11 20:42:26 +01:00
parent b2127fd349
commit 2bf83b6c33
2 changed files with 41 additions and 17 deletions

View file

@ -9,6 +9,7 @@ import (
"time" "time"
"git.lattuga.net/boyska/circolog" "git.lattuga.net/boyska/circolog"
"git.lattuga.net/boyska/circolog/formatter"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"gopkg.in/mcuadros/go-syslog.v2/format" "gopkg.in/mcuadros/go-syslog.v2/format"
) )
@ -56,7 +57,7 @@ func parseParameters(r *http.Request) (circolog.ClientOptions, error) {
} }
type renderOptions struct { // those are options relevant to the rendered (that is, the HTTP side of circologd) type renderOptions struct { // those are options relevant to the rendered (that is, the HTTP side of circologd)
Format renderFormat Format formatter.Format
} }
func parseRenderParameters(r *http.Request) (renderOptions, error) { func parseRenderParameters(r *http.Request) (renderOptions, error) {
@ -70,11 +71,10 @@ func parseRenderParameters(r *http.Request) (renderOptions, error) {
if len(val) != 1 { if len(val) != 1 {
return opts, errors.New("Format repeated multiple times") return opts, errors.New("Format repeated multiple times")
} }
format, err := parseRenderFormat(val[0]) err := opts.Format.Set(val[0])
if err != nil { if err != nil {
return opts, err return opts, err
} }
opts.Format = format
} }
return opts, nil return opts, nil
} }
@ -106,12 +106,13 @@ func getHTTPHandler(hub circolog.Hub) http.HandlerFunc {
hub.Register <- client hub.Register <- client
for x := range client.Messages { for x := range client.Messages {
writeFormatted(w, render_opts.Format, x) if err := render_opts.Format.WriteFormatted(w, x); err == nil {
if render_opts.Format != formatJSON { // bleah if render_opts.Format != formatter.FormatJSON { // bleah
w.Write([]byte("\n")) w.Write([]byte("\n"))
} }
} }
} }
}
} }
func getWSHandler(hub circolog.Hub) http.HandlerFunc { func getWSHandler(hub circolog.Hub) http.HandlerFunc {
@ -166,7 +167,7 @@ func getWSHandler(hub circolog.Hub) http.HandlerFunc {
if err != nil { if err != nil {
return return
} }
writeFormatted(w, render_opts.Format, message) render_opts.Format.WriteFormatted(w, message)
if err := w.Close(); err != nil { if err := w.Close(); err != nil {
return return

View file

@ -1,4 +1,4 @@
package main package formatter
import ( import (
"encoding/json" "encoding/json"
@ -33,29 +33,52 @@ func init() {
)) ))
} }
type renderFormat int type Format int
func parseRenderFormat(s string) (renderFormat, error) { 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"
}
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 { switch s {
case "json": case "json":
return formatJSON, nil return FormatJSON, nil
case "syslog": case "syslog":
return formatSyslog, nil return FormatSyslog, nil
default: default:
return 0, fmt.Errorf("Undefined format `%s`", s) return 0, fmt.Errorf("Undefined format `%s`", s)
} }
} }
const ( const (
formatSyslog = iota // 0 FormatSyslog = iota // 0
formatJSON = iota FormatJSON = iota
) )
func writeFormatted(w io.Writer, f renderFormat, msg format.LogParts) error { func WriteFormatted(w io.Writer, f Format, msg format.LogParts) error {
switch f { switch f {
case formatSyslog: case FormatSyslog:
return syslogTmpl.Execute(w, msg) return syslogTmpl.Execute(w, msg)
case formatJSON: case FormatJSON:
enc := json.NewEncoder(w) enc := json.NewEncoder(w)
enc.SetIndent("", " ") enc.SetIndent("", " ")
return enc.Encode(msg) return enc.Encode(msg)