Skip to content

Commit bd9d794

Browse files
authored
feat: add string renderer (#277)
1 parent c38607d commit bd9d794

File tree

3 files changed

+84
-2
lines changed

3 files changed

+84
-2
lines changed

producer/proto/messages.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package protoproducer
22

33
import (
44
"bytes"
5-
"encoding/hex"
65
"fmt"
76
"hash"
87
"hash/fnv"
@@ -121,7 +120,8 @@ func (m *ProtoProducerMessage) mapUnknown() map[string]interface{} {
121120
value = v
122121
} else if dataType == protowire.BytesType {
123122
v, _ := protowire.ConsumeString(data)
124-
value = hex.EncodeToString([]byte(v))
123+
//value = hex.EncodeToString([]byte(v)) // removed, this conversion is left to the renderer
124+
value = []byte(v)
125125
} else {
126126
continue
127127
}

producer/proto/messages_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package protoproducer
2+
3+
import (
4+
"testing"
5+
6+
"google.golang.org/protobuf/encoding/protowire"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestMarshalJSON(t *testing.T) {
12+
var m ProtoProducerMessage
13+
14+
m.formatter = &FormatterConfigMapper{
15+
fields: []string{"Etype", "test1", "test2", "test3"},
16+
rename: map[string]string{
17+
"Etype": "etype",
18+
},
19+
numToPb: map[int32]ProtobufFormatterConfig{
20+
100: ProtobufFormatterConfig{
21+
Name: "test1",
22+
Index: 100,
23+
Type: "varint",
24+
Array: false,
25+
},
26+
101: ProtobufFormatterConfig{
27+
Name: "test2",
28+
Index: 101,
29+
Type: "string",
30+
Array: false,
31+
},
32+
102: ProtobufFormatterConfig{
33+
Name: "test3",
34+
Index: 102,
35+
Type: "bytes",
36+
Array: false,
37+
},
38+
},
39+
render: map[string]RenderFunc{
40+
"Etype": EtypeRenderer,
41+
"test1": EtypeRenderer,
42+
"test2": NilRenderer,
43+
"test3": StringRenderer,
44+
},
45+
}
46+
47+
m.FlowMessage.Etype = 0x86dd
48+
49+
fmr := m.FlowMessage.ProtoReflect()
50+
unk := fmr.GetUnknown()
51+
52+
unk = protowire.AppendTag(unk, protowire.Number(100), protowire.VarintType)
53+
unk = protowire.AppendVarint(unk, 0x86dd)
54+
55+
unk = protowire.AppendTag(unk, protowire.Number(101), protowire.BytesType)
56+
unk = protowire.AppendString(unk, string("testing"))
57+
58+
unk = protowire.AppendTag(unk, protowire.Number(102), protowire.BytesType)
59+
unk = protowire.AppendString(unk, string([]byte{0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67}))
60+
61+
fmr.SetUnknown(unk)
62+
63+
out, err := m.MarshalJSON()
64+
assert.Nil(t, err)
65+
t.Log(string(out))
66+
assert.Equal(t, "{\"etype\":\"IPv6\",\"test1\":\"IPv6\",\"test2\":\"74657374696e67\",\"test3\":\"testing\"}", string(out))
67+
}

producer/proto/render.go

+15
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const (
2222
RendererNetwork RendererID = "network"
2323
RendererDateTime RendererID = "datetime"
2424
RendererDateTimeNano RendererID = "datetimenano"
25+
RendererString RendererID = "string"
2526
)
2627

2728
var (
@@ -33,6 +34,7 @@ var (
3334
RendererProto: ProtoRenderer,
3435
RendererDateTime: DateTimeRenderer,
3536
RendererDateTimeNano: DateTimeNanoRenderer,
37+
RendererString: StringRenderer,
3638
}
3739

3840
defaultRenderers = map[string]RenderFunc{
@@ -95,6 +97,15 @@ func NilRenderer(msg *ProtoProducerMessage, fieldName string, data interface{})
9597
return data
9698
}
9799

100+
func StringRenderer(msg *ProtoProducerMessage, fieldName string, data interface{}) interface{} {
101+
if dataC, ok := data.([]byte); ok {
102+
return string(dataC)
103+
} else if dataC, ok := data.(string); ok {
104+
return string(dataC)
105+
} // maybe should support uint64?
106+
return NilRenderer(msg, fieldName, data)
107+
}
108+
98109
func DateTimeRenderer(msg *ProtoProducerMessage, fieldName string, data interface{}) interface{} {
99110
if dataC, ok := data.(uint64); ok {
100111
ts := time.Unix(int64(dataC), 0).UTC()
@@ -151,13 +162,17 @@ func IPRenderer(msg *ProtoProducerMessage, fieldName string, data interface{}) i
151162
func EtypeRenderer(msg *ProtoProducerMessage, fieldName string, data interface{}) interface{} {
152163
if dataC, ok := data.(uint32); ok {
153164
return etypeName[dataC]
165+
} else if dataC, ok := data.(uint64); ok { // supports protobuf mapped fields
166+
return etypeName[uint32(dataC)]
154167
}
155168
return "unknown"
156169
}
157170

158171
func ProtoRenderer(msg *ProtoProducerMessage, fieldName string, data interface{}) interface{} {
159172
if dataC, ok := data.(uint32); ok {
160173
return protoName[dataC]
174+
} else if dataC, ok := data.(uint64); ok {
175+
return protoName[uint32(dataC)]
161176
}
162177
return "unknown"
163178
}

0 commit comments

Comments
 (0)