forked from humanlogio/humanlog
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzap_development_handler.go
72 lines (64 loc) · 2.48 KB
/
zap_development_handler.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
package humanlog
import (
"regexp"
"strings"
"time"
"github.com/humanlogio/humanlog/internal/pkg/model"
)
// Zap Development logs are made up of the following separated by whitespace
// 1. timestamp in ISO-8601 (??)
// 2. Log Level (one of DEBUG ERROR INFO WARN FATAL)
// 3. Caller Location in the source
// 4. The main logged message
// 5. a JSON object containing the structured k/v pairs
// 6. optional context lines - but since they are on a separate line the main
// scanner loop will never capture them
var zapDevLogsPrefixRe = regexp.MustCompile("^(?P<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}-\\d{4})\\s+(?P<level>\\w{4,5})\\s+(?P<location>\\S+)\\s+(?P<message>[^{]+?)\\s+(?P<jsonbody>{.+})$")
// Zap Development Logs when run in Docker-Compose are nearly identical to before
// Fields are tab separated instead of whitespace
// Timestamp is now in ...
// Everything else remains the same
var zapDevDCLogsPrefixRe = regexp.MustCompile("^(?P<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)\t(?P<level>\\w{4,5})\t(?P<location>\\S+)\t(?P<message>[^{]+?)\t(?P<jsonbody>{.+})$")
// This is not obviously an RFC-compliant format and is not a constant in the
// time package which is worrisome but this pattern does work.
const someRFC = "2006-01-02T15:04:05.000-0700"
func tryZapDevPrefix(d []byte, ev *model.Structured, handler *JSONHandler) bool {
if matches := zapDevLogsPrefixRe.FindSubmatch(d); matches != nil {
if handler.TryHandle(matches[5], ev) {
t, err := time.Parse(someRFC, string(matches[1]))
if err != nil {
return false
}
ev.Time = t
ev.Level = strings.ToLower(string(matches[2]))
ev.Msg = string(matches[4])
ev.KVs = append(ev.KVs, model.KV{
Key: "caller", Value: string(matches[3]),
})
return true
}
}
return false
}
// This is not obviously an RFC-compliant format and is not a constant in the
// time package which is worrisome but this pattern does work.
const someOtherRFC = "2006-01-02T15:04:05.000Z"
func tryZapDevDCPrefix(d []byte, ev *model.Structured, handler *JSONHandler) bool {
if matches := zapDevDCLogsPrefixRe.FindSubmatch(d); matches != nil {
if handler.TryHandle(matches[5], ev) {
t, err := time.Parse(someOtherRFC, string(matches[1]))
if err != nil {
return false
}
ev.Time = t
ev.Level = strings.ToLower(string(matches[2]))
ev.Msg = string(matches[4])
ev.KVs = append(
ev.KVs,
model.KV{Key: "caller", Value: string(matches[3])},
)
return true
}
}
return false
}