-
Notifications
You must be signed in to change notification settings - Fork 167
/
codec-base.go
157 lines (146 loc) · 3.82 KB
/
codec-base.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
148
149
150
151
152
153
154
155
156
157
package log
import (
"fmt"
"github.com/pydio/cells/v4/common"
"github.com/pydio/cells/v4/common/proto/log"
servicecontext "github.com/pydio/cells/v4/common/service/context"
json "github.com/pydio/cells/v4/common/utils/jsonx"
"strings"
"time"
)
// IndexableLog extends default log.LogMessage struct to add index specific methods
type IndexableLog struct {
Nano int `bson:"nano"`
*log.LogMessage `bson:"inline"`
}
// BleveType is interpreted by bleve indexer as the mapping name
func (*IndexableLog) BleveType() string {
return "log"
}
type baseCodec struct{}
func (b *baseCodec) Marshal(input interface{}) (interface{}, error) {
var msg *IndexableLog
switch v := input.(type) {
case *IndexableLog:
msg = v
case *log.Log:
if ms, e := b.marshalLogMsg(v); e == nil {
msg = ms
} else {
return nil, e
}
case *log.LogMessage:
return &IndexableLog{LogMessage: v}, nil
default:
return nil, fmt.Errorf("unrecognized type")
}
return msg, nil
}
// marshalLogMsg creates an IndexableLog object and populates the inner LogMessage with known fields of the passed JSON line.
func (b *baseCodec) marshalLogMsg(line *log.Log) (*IndexableLog, error) {
msg := &IndexableLog{
LogMessage: &log.LogMessage{},
}
zaps := make(map[string]interface{})
var data map[string]interface{}
e := json.Unmarshal(line.Message, &data)
if e != nil {
return nil, e
}
for k, v := range data {
val, ok := v.(string)
if !ok && k != common.KeyTransferSize {
zaps[k] = v
continue
}
switch k {
case "ts":
t, err := time.Parse(time.RFC3339, val)
if err != nil {
return nil, err
}
msg.Ts = int32(t.UTC().Unix())
case "level":
msg.Level = val
case common.KeyMsgId:
msg.MsgId = val
case "logger": // name of the service that is currently logging.
msg.Logger = val
// N specific info
case common.KeyNodeUuid:
msg.NodeUuid = val
case common.KeyNodePath:
msg.NodePath = val
case common.KeyTransferSize:
if f, o := v.(float64); o {
msg.TransferSize = int64(f)
} else if i, o2 := v.(int64); o2 {
msg.TransferSize = i
}
case common.KeyWorkspaceUuid:
msg.WsUuid = val
case common.KeyWorkspaceScope:
msg.WsScope = val
// User specific info
case common.KeyUsername:
msg.UserName = val
case common.KeyUserUuid:
msg.UserUuid = val
case common.KeyGroupPath:
msg.GroupPath = val
case common.KeyRoles:
msg.RoleUuids = strings.Split(val, ",")
case common.KeyProfile:
msg.Profile = val
// Session and remote client info
case servicecontext.HttpMetaRemoteAddress:
msg.RemoteAddress = val
case servicecontext.HttpMetaUserAgent:
msg.UserAgent = val
case servicecontext.HttpMetaProtocol:
msg.HttpProtocol = val
// Span enable following a given request between the various services
case common.KeySpanUuid:
msg.SpanUuid = val
case common.KeySpanParentUuid:
msg.SpanParentUuid = val
case common.KeySpanRootUuid:
msg.SpanRootUuid = val
// Group messages for a given high level operation
case common.KeyOperationUuid:
msg.OperationUuid = val
case common.KeyOperationLabel:
msg.OperationLabel = val
case common.KeySchedulerJobId:
msg.SchedulerJobUuid = val
case common.KeySchedulerTaskId:
msg.SchedulerTaskUuid = val
case common.KeySchedulerActionPath:
msg.SchedulerTaskActionPath = val
case "msg", "error":
default:
zaps[k] = v
}
}
// Concatenate msg and error in the full text msg field.
text := ""
if m, ok := data["msg"]; ok {
if t, o := m.(string); o {
text = t
} else {
fmt.Println("Error while unmarshaling log data, data['msg'] not a string", m)
}
}
if m, ok := data["error"]; ok {
if stringErr, o := m.(string); o {
text += " - " + stringErr
}
}
msg.Msg = text
msg.Nano = int(line.Nano)
if len(zaps) > 0 {
data, _ := json.Marshal(zaps)
msg.JsonZaps = string(data)
}
return msg, nil
}