Skip to content

Commit e21aa94

Browse files
authored
[processor/transform] Fix context inferrer so it takes into consideration global conditions (#39463)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description Fix the context inferrer to also take into consideration the global OTTL `conditions` configuration. For that, it uses the new option `ottl.WithContextInferenceConditions` recently added to the `ParserCollection.ParseStataments` (#39465). <!-- Issue number (e.g. #1234) or full URL to issue, if applicable. --> #### Link to tracking issue Fixes #39455 <!--Describe what testing was performed and which tests were added.--> #### Testing Unit tests <!--Please delete paragraphs that you did not use before submitting.-->
1 parent eac240c commit e21aa94

File tree

8 files changed

+195
-5
lines changed

8 files changed

+195
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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: bug_fix
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: transformprocessor
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Fix the context inferrer to also take into consideration the global OTTL conditions configuration.
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [39455]
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:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [user, api]

processor/transformprocessor/config.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ type Config struct {
4949

5050
// Unmarshal is used internally by mapstructure to parse the transformprocessor configuration (Config),
5151
// adding support to structured and flat configuration styles.
52-
// When the flat configuration style is used, each statement becomes a new common.ContextStatements
52+
// When the flat configuration style is used, all statements are grouped into a common.ContextStatements
5353
// object, with empty [common.ContextStatements.Context] value.
5454
// On the other hand, structured configurations are parsed following the mapstructure Config format.
55-
// Mixed configuration styles are also supported.
5655
//
5756
// Example of flat configuration:
5857
//

processor/transformprocessor/internal/common/logs.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,5 @@ func (lpc *LogParserCollection) ParseContextStatements(contextStatements Context
116116
if contextStatements.Context != "" {
117117
return pc.ParseStatementsWithContext(string(contextStatements.Context), contextStatements, true)
118118
}
119-
return pc.ParseStatements(contextStatements)
119+
return pc.ParseStatements(contextStatements, ottl.WithContextInferenceConditions(contextStatements.Conditions))
120120
}

processor/transformprocessor/internal/common/metrics.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -257,5 +257,5 @@ func (mpc *MetricParserCollection) ParseContextStatements(contextStatements Cont
257257
if contextStatements.Context != "" {
258258
return pc.ParseStatementsWithContext(string(contextStatements.Context), contextStatements, true)
259259
}
260-
return pc.ParseStatements(contextStatements)
260+
return pc.ParseStatements(contextStatements, ottl.WithContextInferenceConditions(contextStatements.Conditions))
261261
}

processor/transformprocessor/internal/common/traces.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,5 +185,5 @@ func (tpc *TraceParserCollection) ParseContextStatements(contextStatements Conte
185185
if contextStatements.Context != "" {
186186
return pc.ParseStatementsWithContext(string(contextStatements.Context), contextStatements, true)
187187
}
188-
return pc.ParseStatements(contextStatements)
188+
return pc.ParseStatements(contextStatements, ottl.WithContextInferenceConditions(contextStatements.Conditions))
189189
}

processor/transformprocessor/internal/logs/processor_test.go

+50
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,56 @@ func Test_ProcessLogs_CacheAccess(t *testing.T) {
11511151
}
11521152
}
11531153

1154+
func Test_ProcessLogs_InferredContextFromConditions(t *testing.T) {
1155+
tests := []struct {
1156+
name string
1157+
contextStatements []common.ContextStatements
1158+
want func(td plog.Logs)
1159+
}{
1160+
{
1161+
name: "inferring from statements",
1162+
contextStatements: []common.ContextStatements{
1163+
{
1164+
Conditions: []string{`resource.attributes["test"] == nil`},
1165+
Statements: []string{`set(log.attributes["test"], "pass")`},
1166+
},
1167+
},
1168+
want: func(td plog.Logs) {
1169+
td.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0).Attributes().PutStr("test", "pass")
1170+
td.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(1).Attributes().PutStr("test", "pass")
1171+
},
1172+
},
1173+
{
1174+
name: "inferring from conditions",
1175+
contextStatements: []common.ContextStatements{
1176+
{
1177+
Conditions: []string{`log.attributes["test"] == nil`},
1178+
Statements: []string{`set(resource.attributes["test"], "pass")`},
1179+
},
1180+
},
1181+
want: func(td plog.Logs) {
1182+
td.ResourceLogs().At(0).Resource().Attributes().PutStr("test", "pass")
1183+
},
1184+
},
1185+
}
1186+
1187+
for _, tt := range tests {
1188+
t.Run(tt.name, func(t *testing.T) {
1189+
td := constructLogs()
1190+
processor, err := NewProcessor(tt.contextStatements, ottl.IgnoreError, false, componenttest.NewNopTelemetrySettings())
1191+
assert.NoError(t, err)
1192+
1193+
_, err = processor.ProcessLogs(context.Background(), td)
1194+
assert.NoError(t, err)
1195+
1196+
exTd := constructLogs()
1197+
tt.want(exTd)
1198+
1199+
assert.Equal(t, exTd, td)
1200+
})
1201+
}
1202+
}
1203+
11541204
func Test_NewProcessor_ConditionsParse(t *testing.T) {
11551205
type testCase struct {
11561206
name string

processor/transformprocessor/internal/metrics/processor_test.go

+57
Original file line numberDiff line numberDiff line change
@@ -1880,6 +1880,63 @@ func Test_ProcessMetrics_CacheAccess(t *testing.T) {
18801880
}
18811881
}
18821882

1883+
func Test_ProcessMetrics_InferredContextFromConditions(t *testing.T) {
1884+
tests := []struct {
1885+
name string
1886+
contextStatements []common.ContextStatements
1887+
want func(td pmetric.Metrics)
1888+
}{
1889+
{
1890+
name: "inferring from statements",
1891+
contextStatements: []common.ContextStatements{
1892+
{
1893+
Conditions: []string{`resource.attributes["test"] == nil`},
1894+
Statements: []string{`set(metric.name, Concat([metric.name, "pass"], "-"))`},
1895+
},
1896+
},
1897+
want: func(td pmetric.Metrics) {
1898+
for _, v := range td.ResourceMetrics().All() {
1899+
for _, m := range v.ScopeMetrics().All() {
1900+
for _, mm := range m.Metrics().All() {
1901+
mm.SetName(mm.Name() + "-pass")
1902+
}
1903+
}
1904+
}
1905+
},
1906+
},
1907+
{
1908+
name: "inferring from conditions",
1909+
contextStatements: []common.ContextStatements{
1910+
{
1911+
Conditions: []string{`metric.name != nil`},
1912+
Statements: []string{`set(resource.attributes["test"], "pass")`},
1913+
},
1914+
},
1915+
want: func(td pmetric.Metrics) {
1916+
for _, v := range td.ResourceMetrics().All() {
1917+
v.Resource().Attributes().PutStr("test", "pass")
1918+
}
1919+
},
1920+
},
1921+
}
1922+
1923+
for _, tt := range tests {
1924+
t.Run(tt.name, func(t *testing.T) {
1925+
td := constructMetrics()
1926+
processor, err := NewProcessor(tt.contextStatements, ottl.IgnoreError, componenttest.NewNopTelemetrySettings())
1927+
assert.NoError(t, err)
1928+
1929+
_, err = processor.ProcessMetrics(context.Background(), td)
1930+
assert.NoError(t, err)
1931+
1932+
exTd := constructMetrics()
1933+
tt.want(exTd)
1934+
1935+
assert.Equal(t, exTd, td)
1936+
})
1937+
}
1938+
}
1939+
18831940
func Test_NewProcessor_ConditionsParse(t *testing.T) {
18841941
type testCase struct {
18851942
name string

processor/transformprocessor/internal/traces/processor_test.go

+57
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,63 @@ func Test_ProcessTraces_CacheAccess(t *testing.T) {
12671267
}
12681268
}
12691269

1270+
func Test_ProcessTraces_InferredContextFromConditions(t *testing.T) {
1271+
tests := []struct {
1272+
name string
1273+
contextStatements []common.ContextStatements
1274+
want func(td ptrace.Traces)
1275+
}{
1276+
{
1277+
name: "inferring from statements",
1278+
contextStatements: []common.ContextStatements{
1279+
{
1280+
Conditions: []string{`resource.attributes["test"] == nil`},
1281+
Statements: []string{`set(span.name, Concat([span.name, "pass"], "-"))`},
1282+
},
1283+
},
1284+
want: func(td ptrace.Traces) {
1285+
for _, v := range td.ResourceSpans().All() {
1286+
for _, m := range v.ScopeSpans().All() {
1287+
for _, mm := range m.Spans().All() {
1288+
mm.SetName(mm.Name() + "-pass")
1289+
}
1290+
}
1291+
}
1292+
},
1293+
},
1294+
{
1295+
name: "inferring from conditions",
1296+
contextStatements: []common.ContextStatements{
1297+
{
1298+
Conditions: []string{`span.name != nil`},
1299+
Statements: []string{`set(resource.attributes["test"], "pass")`},
1300+
},
1301+
},
1302+
want: func(td ptrace.Traces) {
1303+
for _, v := range td.ResourceSpans().All() {
1304+
v.Resource().Attributes().PutStr("test", "pass")
1305+
}
1306+
},
1307+
},
1308+
}
1309+
1310+
for _, tt := range tests {
1311+
t.Run(tt.name, func(t *testing.T) {
1312+
td := constructTraces()
1313+
processor, err := NewProcessor(tt.contextStatements, ottl.IgnoreError, componenttest.NewNopTelemetrySettings())
1314+
assert.NoError(t, err)
1315+
1316+
_, err = processor.ProcessTraces(context.Background(), td)
1317+
assert.NoError(t, err)
1318+
1319+
exTd := constructTraces()
1320+
tt.want(exTd)
1321+
1322+
assert.Equal(t, exTd, td)
1323+
})
1324+
}
1325+
}
1326+
12701327
func Test_NewProcessor_ConditionsParse(t *testing.T) {
12711328
type testCase struct {
12721329
name string

0 commit comments

Comments
 (0)