[tail] format locally
JSON is actually unfit to send structured log messages, because date/time is not well supported. So we are using BSON, which supports those. BSON is, among the dozen serializers available, really a random choice and might be changed in the future.
This commit is contained in:
parent
2bf83b6c33
commit
b11c2edfc0
2 changed files with 27 additions and 2 deletions
|
@ -11,7 +11,10 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.lattuga.net/boyska/circolog/formatter"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
|
"gopkg.in/mcuadros/go-syslog.v2/format"
|
||||||
|
"gopkg.in/mgo.v2/bson"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -28,6 +31,7 @@ func main() {
|
||||||
Path: "/ws",
|
Path: "/ws",
|
||||||
}
|
}
|
||||||
q := u.Query()
|
q := u.Query()
|
||||||
|
q.Set("fmt", "bson")
|
||||||
if *backlogLimit >= 0 {
|
if *backlogLimit >= 0 {
|
||||||
q.Set("l", strconv.Itoa(*backlogLimit))
|
q.Set("l", strconv.Itoa(*backlogLimit))
|
||||||
}
|
}
|
||||||
|
@ -58,12 +62,20 @@ func main() {
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
for {
|
for {
|
||||||
_, message, err := c.ReadMessage()
|
_, serialized, err := c.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("close:", err)
|
log.Println("close:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println(string(message))
|
var parsed format.LogParts
|
||||||
|
if err := bson.Unmarshal(serialized, &parsed); err != nil {
|
||||||
|
log.Println("invalid YAML", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := formatter.WriteFormatted(os.Stdout, formatter.FormatSyslog, parsed); err != nil {
|
||||||
|
log.Println("error printing", err)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gopkg.in/mcuadros/go-syslog.v2/format"
|
"gopkg.in/mcuadros/go-syslog.v2/format"
|
||||||
|
"gopkg.in/mgo.v2/bson"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Formatter is an interface, so that multiple implementations can exist
|
// Formatter is an interface, so that multiple implementations can exist
|
||||||
|
@ -50,6 +51,8 @@ func (rf Format) String() string {
|
||||||
return "json"
|
return "json"
|
||||||
case FormatSyslog:
|
case FormatSyslog:
|
||||||
return "syslog"
|
return "syslog"
|
||||||
|
case FormatBSON:
|
||||||
|
return "bson"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -64,6 +67,8 @@ func parseFormat(s string) (Format, error) {
|
||||||
return FormatJSON, nil
|
return FormatJSON, nil
|
||||||
case "syslog":
|
case "syslog":
|
||||||
return FormatSyslog, nil
|
return FormatSyslog, nil
|
||||||
|
case "bson":
|
||||||
|
return FormatBSON, nil
|
||||||
default:
|
default:
|
||||||
return 0, fmt.Errorf("Undefined format `%s`", s)
|
return 0, fmt.Errorf("Undefined format `%s`", s)
|
||||||
}
|
}
|
||||||
|
@ -72,6 +77,7 @@ func parseFormat(s string) (Format, error) {
|
||||||
const (
|
const (
|
||||||
FormatSyslog = iota // 0
|
FormatSyslog = iota // 0
|
||||||
FormatJSON = iota
|
FormatJSON = iota
|
||||||
|
FormatBSON = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
func WriteFormatted(w io.Writer, f Format, msg format.LogParts) error {
|
func WriteFormatted(w io.Writer, f Format, msg format.LogParts) error {
|
||||||
|
@ -82,6 +88,13 @@ func WriteFormatted(w io.Writer, f Format, msg format.LogParts) error {
|
||||||
enc := json.NewEncoder(w)
|
enc := json.NewEncoder(w)
|
||||||
enc.SetIndent("", " ")
|
enc.SetIndent("", " ")
|
||||||
return enc.Encode(msg)
|
return enc.Encode(msg)
|
||||||
|
case FormatBSON:
|
||||||
|
enc, err := bson.Marshal(msg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = w.Write(enc)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue