1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/vendor/github.com/Graylog2/go-gelf/gelf/message.go
Sebastiaan van Stijn 1fab7c6457
bump Graylog2/go-gelf to 1550ee647df0510058c9d67a45c56f18911d80b8
4143646226...1550ee647d

includes

- Graylog2/go-gelf#20 Prevent panic when unmarshalling JSON
- Graylog2/go-gelf#23 Feat: Use more precise time stamps
- Graylog2/go-gelf#31 bugfix. Not goroutine safe for TCP writer

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-10-17 18:41:03 +02:00

154 lines
3.4 KiB
Go

package gelf
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
// Message represents the contents of the GELF message. It is gzipped
// before sending.
type Message struct {
Version string `json:"version"`
Host string `json:"host"`
Short string `json:"short_message"`
Full string `json:"full_message,omitempty"`
TimeUnix float64 `json:"timestamp"`
Level int32 `json:"level,omitempty"`
Facility string `json:"facility,omitempty"`
Extra map[string]interface{} `json:"-"`
RawExtra json.RawMessage `json:"-"`
}
// Syslog severity levels
const (
LOG_EMERG = 0
LOG_ALERT = 1
LOG_CRIT = 2
LOG_ERR = 3
LOG_WARNING = 4
LOG_NOTICE = 5
LOG_INFO = 6
LOG_DEBUG = 7
)
func (m *Message) MarshalJSONBuf(buf *bytes.Buffer) error {
b, err := json.Marshal(m)
if err != nil {
return err
}
// write up until the final }
if _, err = buf.Write(b[:len(b)-1]); err != nil {
return err
}
if len(m.Extra) > 0 {
eb, err := json.Marshal(m.Extra)
if err != nil {
return err
}
// merge serialized message + serialized extra map
if err = buf.WriteByte(','); err != nil {
return err
}
// write serialized extra bytes, without enclosing quotes
if _, err = buf.Write(eb[1 : len(eb)-1]); err != nil {
return err
}
}
if len(m.RawExtra) > 0 {
if err := buf.WriteByte(','); err != nil {
return err
}
// write serialized extra bytes, without enclosing quotes
if _, err = buf.Write(m.RawExtra[1 : len(m.RawExtra)-1]); err != nil {
return err
}
}
// write final closing quotes
return buf.WriteByte('}')
}
func (m *Message) UnmarshalJSON(data []byte) error {
i := make(map[string]interface{}, 16)
if err := json.Unmarshal(data, &i); err != nil {
return err
}
for k, v := range i {
if k[0] == '_' {
if m.Extra == nil {
m.Extra = make(map[string]interface{}, 1)
}
m.Extra[k] = v
continue
}
ok := true
switch k {
case "version":
m.Version, ok = v.(string)
case "host":
m.Host, ok = v.(string)
case "short_message":
m.Short, ok = v.(string)
case "full_message":
m.Full, ok = v.(string)
case "timestamp":
m.TimeUnix, ok = v.(float64)
case "level":
var level float64
level, ok = v.(float64)
m.Level = int32(level)
case "facility":
m.Facility, ok = v.(string)
}
if !ok {
return fmt.Errorf("invalid type for field %s", k)
}
}
return nil
}
func (m *Message) toBytes(buf *bytes.Buffer) (messageBytes []byte, err error) {
if err = m.MarshalJSONBuf(buf); err != nil {
return nil, err
}
messageBytes = buf.Bytes()
return messageBytes, nil
}
func constructMessage(p []byte, hostname string, facility string, file string, line int) (m *Message) {
// remove trailing and leading whitespace
p = bytes.TrimSpace(p)
// If there are newlines in the message, use the first line
// for the short message and set the full message to the
// original input. If the input has no newlines, stick the
// whole thing in Short.
short := p
full := []byte("")
if i := bytes.IndexRune(p, '\n'); i > 0 {
short = p[:i]
full = p
}
m = &Message{
Version: "1.1",
Host: hostname,
Short: string(short),
Full: string(full),
TimeUnix: float64(time.Now().UnixNano()) / float64(time.Second),
Level: 6, // info
Facility: facility,
Extra: map[string]interface{}{
"_file": file,
"_line": line,
},
}
return m
}