Skip to content

Commit 72f03cf

Browse files
authored
Generate Logs/Traces/Metrics and ExportResponse (open-telemetry#13597)
This removes lots of hand written JSON encoding code, and will help when start using generated proto size/marshal/unmarshal. This also adds tests for all previously hand written funcs. Signed-off-by: Bogdan Drutu <[email protected]>
1 parent aef8b1c commit 72f03cf

File tree

76 files changed

+2508
-580
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+2508
-580
lines changed

.chloggen/generate-more.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: pdata
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Generate Logs/Traces/Metrics/Profiles and p[log|trace|metric|profile]ExportResponse with pdatagen.
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [13597]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: This change brings consistency on how these structs are written and remove JSON marshaling/unmarshaling hand written logic.
19+
20+
# Optional: The change log or logs in which this entry should be included.
21+
# e.g. '[user]' or '[user, api]'
22+
# Include 'user' if the change is relevant to end users.
23+
# Include 'api' if there is a change to a library API.
24+
# Default: '[user]'
25+
change_logs: [api, user]

internal/cmd/pdatagen/internal/base_slices.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package internal // import "go.opentelemetry.io/collector/internal/cmd/pdatagen/
66
type baseSlice interface {
77
getName() string
88
getOriginName() string
9+
getHasWrapper() bool
910
getElementProtoType() ProtoType
1011
getElementOriginName() string
1112
getPackageName() string
@@ -43,11 +44,12 @@ func (ss *sliceOfPtrs) generateInternalTests(packageInfo *PackageInfo) []byte {
4344
}
4445

4546
func (ss *sliceOfPtrs) templateFields(packageInfo *PackageInfo) map[string]any {
46-
orig := origAccessor(ss.packageName)
47-
state := stateAccessor(ss.packageName)
47+
hasWrapper := usedByOtherDataTypes(ss.packageName)
48+
orig := origAccessor(hasWrapper)
49+
state := stateAccessor(hasWrapper)
4850
return map[string]any{
4951
"type": "sliceOfPtrs",
50-
"isCommon": usedByOtherDataTypes(ss.packageName),
52+
"hasWrapper": usedByOtherDataTypes(ss.packageName),
5153
"structName": ss.structName,
5254
"elementName": ss.element.getName(),
5355
"elementOriginFullName": ss.element.originFullName,
@@ -56,8 +58,8 @@ func (ss *sliceOfPtrs) templateFields(packageInfo *PackageInfo) map[string]any {
5658
"originElementPtr": "",
5759
"emptyOriginElement": "&" + ss.element.originFullName + "{}",
5860
"newElement": "new" + ss.element.getName() + "((*es." + orig + ")[i], es." + state + ")",
59-
"origAccessor": orig,
60-
"stateAccessor": state,
61+
"origAccessor": origAccessor(hasWrapper),
62+
"stateAccessor": stateAccessor(hasWrapper),
6163
"packageName": packageInfo.name,
6264
"imports": packageInfo.imports,
6365
"testImports": packageInfo.testImports,
@@ -72,6 +74,10 @@ func (ss *sliceOfPtrs) getElementProtoType() ProtoType {
7274
return ProtoTypeMessage
7375
}
7476

77+
func (ss *sliceOfPtrs) getHasWrapper() bool {
78+
return usedByOtherDataTypes(ss.packageName)
79+
}
80+
7581
func (ss *sliceOfPtrs) getElementOriginName() string {
7682
return ss.element.getOriginName()
7783
}
@@ -110,11 +116,12 @@ func (ss *sliceOfValues) generateInternalTests(packageInfo *PackageInfo) []byte
110116
}
111117

112118
func (ss *sliceOfValues) templateFields(packageInfo *PackageInfo) map[string]any {
113-
orig := origAccessor(ss.packageName)
114-
state := stateAccessor(ss.packageName)
119+
hasWrapper := usedByOtherDataTypes(ss.packageName)
120+
orig := origAccessor(hasWrapper)
121+
state := stateAccessor(hasWrapper)
115122
return map[string]any{
116123
"type": "sliceOfValues",
117-
"isCommon": usedByOtherDataTypes(ss.packageName),
124+
"hasWrapper": usedByOtherDataTypes(ss.packageName),
118125
"structName": ss.getName(),
119126
"elementName": ss.element.getName(),
120127
"elementOriginFullName": ss.element.originFullName,
@@ -139,6 +146,10 @@ func (ss *sliceOfValues) getElementProtoType() ProtoType {
139146
return ProtoTypeMessage
140147
}
141148

149+
func (ss *sliceOfValues) getHasWrapper() bool {
150+
return usedByOtherDataTypes(ss.packageName)
151+
}
152+
142153
func (ss *sliceOfValues) getElementOriginName() string {
143154
return ss.element.getOriginName()
144155
}

internal/cmd/pdatagen/internal/base_struct.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
type baseStruct interface {
1010
getName() string
1111
getOriginName() string
12+
getHasWrapper() bool
1213
generate(packageInfo *PackageInfo) []byte
1314
generateTests(packageInfo *PackageInfo) []byte
1415
generateInternal(packageInfo *PackageInfo) []byte
@@ -23,6 +24,7 @@ type messageStruct struct {
2324
description string
2425
originFullName string
2526
fields []Field
27+
hasWrapper bool
2628
}
2729

2830
func (ms *messageStruct) getName() string {
@@ -46,22 +48,33 @@ func (ms *messageStruct) generateInternalTests(packageInfo *PackageInfo) []byte
4648
}
4749

4850
func (ms *messageStruct) templateFields(packageInfo *PackageInfo) map[string]any {
51+
hasWrapper := ms.hasWrapper
52+
if !hasWrapper {
53+
hasWrapper = usedByOtherDataTypes(ms.packageName)
54+
}
4955
return map[string]any{
5056
"messageStruct": ms,
5157
"fields": ms.fields,
5258
"structName": ms.getName(),
5359
"originFullName": ms.originFullName,
5460
"originName": ms.getOriginName(),
5561
"description": ms.description,
56-
"isCommon": usedByOtherDataTypes(ms.packageName),
57-
"origAccessor": origAccessor(ms.packageName),
58-
"stateAccessor": stateAccessor(ms.packageName),
62+
"hasWrapper": hasWrapper,
63+
"origAccessor": origAccessor(hasWrapper),
64+
"stateAccessor": stateAccessor(hasWrapper),
5965
"packageName": packageInfo.name,
6066
"imports": packageInfo.imports,
6167
"testImports": packageInfo.testImports,
6268
}
6369
}
6470

71+
func (ms *messageStruct) getHasWrapper() bool {
72+
if ms.hasWrapper {
73+
return true
74+
}
75+
return usedByOtherDataTypes(ms.packageName)
76+
}
77+
6578
func (ms *messageStruct) getOriginName() string {
6679
_, after, _ := strings.Cut(ms.originFullName, ".")
6780
return after

internal/cmd/pdatagen/internal/field.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ type Field interface {
2121
GenerateMarshalProto(ms *messageStruct) string
2222
}
2323

24-
func origAccessor(packageName string) string {
25-
if usedByOtherDataTypes(packageName) {
24+
func origAccessor(hasWrapper bool) string {
25+
if hasWrapper {
2626
return "getOrig()"
2727
}
2828
return "orig"
2929
}
3030

31-
func stateAccessor(packageName string) string {
32-
if usedByOtherDataTypes(packageName) {
31+
func stateAccessor(hasWrapper bool) string {
32+
if hasWrapper {
3333
return "getState()"
3434
}
3535
return "state"

internal/cmd/pdatagen/internal/message_field.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
const messageAccessorsTemplate = `// {{ .fieldName }} returns the {{ .lowerFieldName }} associated with this {{ .structName }}.
1212
func (ms {{ .structName }}) {{ .fieldName }}() {{ .packageName }}{{ .returnType }} {
13-
{{- if .isCommon }}
13+
{{- if .messageHasWrapper }}
1414
return {{ .packageName }}{{ .returnType }}(internal.New{{ .returnType }}(&ms.{{ .origAccessor }}.{{ .fieldOriginFullName }}, ms.{{ .stateAccessor }}))
1515
{{- else }}
1616
return new{{ .returnType }}(&ms.{{ .origAccessor }}.{{ .fieldOriginFullName }}, ms.{{ .stateAccessor }})
@@ -21,7 +21,7 @@ const messageAccessorsTestTemplate = `func Test{{ .structName }}_{{ .fieldName }
2121
ms := New{{ .structName }}()
2222
assert.Equal(t, {{ .packageName }}New{{ .returnType }}{{- if eq .returnType "Value" }}Empty{{- end }}(), ms.{{ .fieldName }}())
2323
internal.FillOrigTest{{ .fieldOriginName }}(&ms.{{ .origAccessor }}.{{ .fieldOriginFullName }})
24-
{{- if .isCommon }}
24+
{{- if .messageHasWrapper }}
2525
assert.Equal(t, {{ .packageName }}{{ .returnType }}(internal.GenerateTest{{ .returnType }}()), ms.{{ .fieldName }}())
2626
{{- else }}
2727
assert.Equal(t, generateTest{{ .returnType }}(), ms.{{ .fieldName }}())
@@ -41,9 +41,10 @@ const messageUnmarshalJSONTemplate = `case "{{ lowerFirst .fieldOriginFullName }
4141
UnmarshalJSONOrig{{ .fieldOriginName }}(&orig.{{ .fieldOriginFullName }}, iter)`
4242

4343
type MessageField struct {
44-
fieldName string
45-
protoID uint32
46-
returnMessage *messageStruct
44+
fieldName string
45+
fieldOriginFullName string
46+
protoID uint32
47+
returnMessage *messageStruct
4748
}
4849

4950
func (mf *MessageField) GenerateAccessors(ms *messageStruct) string {
@@ -92,17 +93,17 @@ func (mf *MessageField) toProtoField() *ProtoField {
9293
return &ProtoField{
9394
Type: pt,
9495
ID: mf.protoID,
95-
Name: mf.fieldName,
96+
Name: mf.getFieldOriginFullName(),
9697
MessageName: mf.returnMessage.getOriginName(),
9798
}
9899
}
99100

100101
func (mf *MessageField) templateFields(ms *messageStruct) map[string]any {
101102
return map[string]any{
102-
"isCommon": usedByOtherDataTypes(mf.returnMessage.packageName),
103+
"messageHasWrapper": usedByOtherDataTypes(mf.returnMessage.packageName),
103104
"structName": ms.getName(),
104105
"fieldName": mf.fieldName,
105-
"fieldOriginFullName": mf.fieldName,
106+
"fieldOriginFullName": mf.getFieldOriginFullName(),
106107
"fieldOriginName": mf.returnMessage.getOriginName(),
107108
"lowerFieldName": strings.ToLower(mf.fieldName),
108109
"returnType": mf.returnMessage.getName(),
@@ -112,9 +113,16 @@ func (mf *MessageField) templateFields(ms *messageStruct) map[string]any {
112113
}
113114
return ""
114115
}(),
115-
"origAccessor": origAccessor(ms.packageName),
116-
"stateAccessor": stateAccessor(ms.packageName),
116+
"origAccessor": origAccessor(ms.getHasWrapper()),
117+
"stateAccessor": stateAccessor(ms.getHasWrapper()),
117118
}
118119
}
119120

121+
func (mf *MessageField) getFieldOriginFullName() string {
122+
if mf.fieldOriginFullName != "" {
123+
return mf.fieldOriginFullName
124+
}
125+
return mf.fieldName
126+
}
127+
120128
var _ Field = (*MessageField)(nil)

internal/cmd/pdatagen/internal/one_of_field.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ func (of *OneOfField) templateFields(ms *messageStruct) map[string]any {
129129
"typeName": of.typeName,
130130
"originFieldName": of.originFieldName,
131131
"lowerOriginFieldName": strings.ToLower(of.originFieldName),
132-
"origAccessor": origAccessor(ms.packageName),
133-
"stateAccessor": stateAccessor(ms.packageName),
132+
"origAccessor": origAccessor(ms.getHasWrapper()),
133+
"stateAccessor": stateAccessor(ms.getHasWrapper()),
134134
"values": of.values,
135135
"originTypePrefix": ms.originFullName + "_",
136136
}

internal/cmd/pdatagen/internal/plog_package.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var plog = &Package{
1717
`"go.opentelemetry.io/collector/pdata/internal/data"`,
1818
`"go.opentelemetry.io/collector/pdata/internal/json"`,
1919
`"go.opentelemetry.io/collector/pdata/internal/proto"`,
20+
`otlpcollectorlog "go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/logs/v1"`,
2021
`otlplogs "go.opentelemetry.io/collector/pdata/internal/data/protogen/logs/v1"`,
2122
`"go.opentelemetry.io/collector/pdata/pcommon"`,
2223
},
@@ -30,11 +31,13 @@ var plog = &Package{
3031
`"go.opentelemetry.io/collector/pdata/internal"`,
3132
`"go.opentelemetry.io/collector/pdata/internal/data"`,
3233
`"go.opentelemetry.io/collector/pdata/internal/json"`,
34+
`otlpcollectorlog "go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/logs/v1"`,
3335
`otlplogs "go.opentelemetry.io/collector/pdata/internal/data/protogen/logs/v1"`,
3436
`"go.opentelemetry.io/collector/pdata/pcommon"`,
3537
},
3638
},
3739
structs: []baseStruct{
40+
logs,
3841
resourceLogsSlice,
3942
resourceLogs,
4043
scopeLogsSlice,
@@ -44,6 +47,21 @@ var plog = &Package{
4447
},
4548
}
4649

50+
var logs = &messageStruct{
51+
structName: "Logs",
52+
description: "// Logs is the top-level struct that is propagated through the logs pipeline.\n// Use NewLogs to create new instance, zero-initialized instance is not valid for use.",
53+
originFullName: "otlpcollectorlog.ExportLogsServiceRequest",
54+
fields: []Field{
55+
&SliceField{
56+
fieldName: "ResourceLogs",
57+
protoID: 1,
58+
protoType: ProtoTypeMessage,
59+
returnSlice: resourceLogsSlice,
60+
},
61+
},
62+
hasWrapper: true,
63+
}
64+
4765
var resourceLogsSlice = &sliceOfPtrs{
4866
structName: "ResourceLogsSlice",
4967
element: resourceLogs,

internal/cmd/pdatagen/internal/plogotlp_package.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,24 @@ var plogotlp = &Package{
2727
},
2828
},
2929
structs: []baseStruct{
30+
exportLogsResponse,
3031
exportLogsPartialSuccess,
3132
},
3233
}
3334

35+
var exportLogsResponse = &messageStruct{
36+
structName: "ExportResponse",
37+
description: "// ExportResponse represents the response for gRPC/HTTP client/server.",
38+
originFullName: "otlpcollectorlog.ExportLogsServiceResponse",
39+
fields: []Field{
40+
&MessageField{
41+
fieldName: "PartialSuccess",
42+
protoID: 1,
43+
returnMessage: exportLogsPartialSuccess,
44+
},
45+
},
46+
}
47+
3448
var exportLogsPartialSuccess = &messageStruct{
3549
structName: "ExportPartialSuccess",
3650
description: "// ExportPartialSuccess represents the details of a partially successful export request.",

internal/cmd/pdatagen/internal/pmetric_package.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var pmetric = &Package{
1717
`"go.opentelemetry.io/collector/pdata/internal/data"`,
1818
`"go.opentelemetry.io/collector/pdata/internal/json"`,
1919
`"go.opentelemetry.io/collector/pdata/internal/proto"`,
20+
`otlpcollectormetrics "go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/metrics/v1"`,
2021
`otlpmetrics "go.opentelemetry.io/collector/pdata/internal/data/protogen/metrics/v1"`,
2122
`"go.opentelemetry.io/collector/pdata/pcommon"`,
2223
},
@@ -30,11 +31,13 @@ var pmetric = &Package{
3031
`"go.opentelemetry.io/collector/pdata/internal"`,
3132
`"go.opentelemetry.io/collector/pdata/internal/data"`,
3233
`"go.opentelemetry.io/collector/pdata/internal/json"`,
34+
`otlpcollectormetrics "go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/metrics/v1"`,
3335
`otlpmetrics "go.opentelemetry.io/collector/pdata/internal/data/protogen/metrics/v1"`,
3436
`"go.opentelemetry.io/collector/pdata/pcommon"`,
3537
},
3638
},
3739
structs: []baseStruct{
40+
metrics,
3841
resourceMetricsSlice,
3942
resourceMetrics,
4043
scopeMetricsSlice,
@@ -62,6 +65,21 @@ var pmetric = &Package{
6265
},
6366
}
6467

68+
var metrics = &messageStruct{
69+
structName: "Metrics",
70+
description: "// Metrics is the top-level struct that is propagated through the metrics pipeline.\n// Use NewMetrics to create new instance, zero-initialized instance is not valid for use.",
71+
originFullName: "otlpcollectormetrics.ExportMetricsServiceRequest",
72+
fields: []Field{
73+
&SliceField{
74+
fieldName: "ResourceMetrics",
75+
protoID: 1,
76+
protoType: ProtoTypeMessage,
77+
returnSlice: resourceMetricsSlice,
78+
},
79+
},
80+
hasWrapper: true,
81+
}
82+
6583
var resourceMetricsSlice = &sliceOfPtrs{
6684
structName: "ResourceMetricsSlice",
6785
element: resourceMetrics,

internal/cmd/pdatagen/internal/pmetricotlp_package.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,24 @@ var pmetricotlp = &Package{
2828
},
2929
},
3030
structs: []baseStruct{
31+
exportMetricsResponse,
3132
exportMetricsPartialSuccess,
3233
},
3334
}
3435

36+
var exportMetricsResponse = &messageStruct{
37+
structName: "ExportResponse",
38+
description: "// ExportResponse represents the response for gRPC/HTTP client/server.",
39+
originFullName: "otlpcollectormetrics.ExportMetricsServiceResponse",
40+
fields: []Field{
41+
&MessageField{
42+
fieldName: "PartialSuccess",
43+
protoID: 1,
44+
returnMessage: exportMetricsPartialSuccess,
45+
},
46+
},
47+
}
48+
3549
var exportMetricsPartialSuccess = &messageStruct{
3650
structName: "ExportPartialSuccess",
3751
description: "// ExportPartialSuccess represents the details of a partially successful export request.",

0 commit comments

Comments
 (0)