mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
b24c8e07f1
Signed-off-by: Ghislain Bourgeois <ghislain.bourgeois@gmail.com>
147 lines
3.3 KiB
Go
147 lines
3.3 KiB
Go
package gelf
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"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
|
|
}
|
|
switch k {
|
|
case "version":
|
|
m.Version = v.(string)
|
|
case "host":
|
|
m.Host = v.(string)
|
|
case "short_message":
|
|
m.Short = v.(string)
|
|
case "full_message":
|
|
m.Full = v.(string)
|
|
case "timestamp":
|
|
m.TimeUnix = v.(float64)
|
|
case "level":
|
|
m.Level = int32(v.(float64))
|
|
case "facility":
|
|
m.Facility = v.(string)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *Message) toBytes() (messageBytes []byte, err error) {
|
|
buf := newBuffer()
|
|
defer bufPool.Put(buf)
|
|
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().Unix()),
|
|
Level: 6, // info
|
|
Facility: facility,
|
|
Extra: map[string]interface{}{
|
|
"_file": file,
|
|
"_line": line,
|
|
},
|
|
}
|
|
|
|
return m
|
|
}
|