This repository has been archived by the owner on Mar 31, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathplain.go
147 lines (138 loc) · 3.57 KB
/
plain.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package log
import (
"encoding"
"fmt"
"sort"
"strconv"
"strings"
"time"
"unicode/utf8"
)
// PlainFormat implements Formatter to generate plain log messages.
//
// A plain log message looks like:
// DATETIME SEVERITY UTSNAME TOPIC MESSAGE [OPTIONAL FIELDS...]
type PlainFormat struct {
// Utsname can normally be left blank.
// If not empty, the string is used instead of the hostname.
// Utsname must match this regexp: ^[a-z][a-z0-9-]*$
Utsname string
}
// String returns "plain".
func (f PlainFormat) String() string {
return "plain"
}
// Format implements Formatter.Format.
func (f PlainFormat) Format(buf []byte, l *Logger, t time.Time, severity int,
msg string, fields map[string]interface{}) ([]byte, error) {
var err error
buf = t.UTC().AppendFormat(buf, RFC3339Micro)
buf = append(buf, ' ')
if len(f.Utsname) > 0 {
buf = append(buf, f.Utsname...)
} else {
buf = append(buf, utsname...)
}
buf = append(buf, ' ')
buf = append(buf, l.Topic()...)
buf = append(buf, ' ')
if ss, ok := severityMap[severity]; ok {
buf = append(buf, ss...)
} else {
buf = strconv.AppendInt(buf, int64(severity), 10)
}
buf = append(buf, ": "...)
buf, err = appendPlain(buf, msg)
if err != nil {
return nil, err
}
if len(fields) > 0 {
keys := make([]string, 0, len(fields))
for k := range fields {
if !IsValidKey(k) {
return nil, ErrInvalidKey
}
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
buf = append(buf, ' ')
buf = append(buf, k...)
buf = append(buf, '=')
buf, err = appendPlain(buf, fields[k])
if err != nil {
return nil, err
}
}
}
for k, v := range l.Defaults() {
if _, ok := fields[k]; ok {
continue
}
buf = append(buf, ' ')
buf = append(buf, k...)
buf = append(buf, '=')
buf, err = appendPlain(buf, v)
if err != nil {
return nil, err
}
}
return append(buf, '\n'), nil
}
func appendPlain(buf []byte, v interface{}) ([]byte, error) {
switch t := v.(type) {
case nil:
return append(buf, "null"...), nil
case bool:
return strconv.AppendBool(buf, t), nil
case time.Time:
return t.UTC().AppendFormat(buf, RFC3339Micro), nil
case int:
return strconv.AppendInt(buf, int64(t), 10), nil
case int8:
return strconv.AppendInt(buf, int64(t), 10), nil
case int16:
return strconv.AppendInt(buf, int64(t), 10), nil
case int32:
return strconv.AppendInt(buf, int64(t), 10), nil
case int64:
return strconv.AppendInt(buf, t, 10), nil
case uint:
return strconv.AppendUint(buf, uint64(t), 10), nil
case uint8:
return strconv.AppendUint(buf, uint64(t), 10), nil
case uint16:
return strconv.AppendUint(buf, uint64(t), 10), nil
case uint32:
return strconv.AppendUint(buf, uint64(t), 10), nil
case uint64:
return strconv.AppendUint(buf, t, 10), nil
case float32:
return strconv.AppendFloat(buf, float64(t), 'f', -1, 32), nil
case float64:
return strconv.AppendFloat(buf, t, 'f', -1, 64), nil
case string:
if !utf8.ValidString(t) {
// the next line replaces invalid characters.
t = strings.ToValidUTF8(t, string(utf8.RuneError))
}
return strconv.AppendQuote(buf, t), nil
case encoding.TextMarshaler:
// TextMarshaler encodes into UTF-8 string.
s, err := t.MarshalText()
if err != nil {
return nil, err
}
return strconv.AppendQuote(buf, string(s)), nil
case error:
s := t.Error()
if !utf8.ValidString(s) {
// the next line replaces invalid characters.
s = strings.ToValidUTF8(s, string(utf8.RuneError))
}
return strconv.AppendQuote(buf, s), nil
default:
// other types are just formatted as string with "%v".
return appendPlain(buf, fmt.Sprintf("%v", t))
}
}