Skip to content

Commit 5b5ef4d

Browse files
committed
fix(logs pipelines): preview logs with the body the collector sees
The collector gets a normalize pipeline prepended ahead of user pipelines when use_json_body is on, delivered over opamp, so a pipeline authored against body.<field> behaved differently in preview than in production. Preview evaluates the flag for the caller's org and prepends the same pipeline.
1 parent 1684996 commit 5b5ef4d

3 files changed

Lines changed: 110 additions & 34 deletions

File tree

pkg/query-service/app/http_handler.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3201,7 +3201,19 @@ func (aH *APIHandler) PreviewLogsPipelinesHandler(w http.ResponseWriter, r *http
32013201
return
32023202
}
32033203

3204-
resultLogs, err := aH.LogsParsingPipelineController.PreviewLogsPipelines(r.Context(), &req)
3204+
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
3205+
if errv2 != nil {
3206+
render.Error(w, errv2)
3207+
return
3208+
}
3209+
3210+
orgID, errv2 := valuer.NewUUID(claims.OrgID)
3211+
if errv2 != nil {
3212+
render.Error(w, errv2)
3213+
return
3214+
}
3215+
3216+
resultLogs, err := aH.LogsParsingPipelineController.PreviewLogsPipelines(r.Context(), orgID, &req)
32053217
if err != nil {
32063218
render.Error(w, err)
32073219
return

pkg/query-service/app/logparsingpipeline/controller.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,13 +342,19 @@ type PipelinesPreviewResponse struct {
342342

343343
func (ic *LogParsingPipelineController) PreviewLogsPipelines(
344344
ctx context.Context,
345+
orgID valuer.UUID,
345346
request *PipelinesPreviewRequest,
346347
) (*PipelinesPreviewResponse, error) {
347348
pipelines, err := ic.enrichPipelinesFilters(ctx, request.Pipelines)
348349
if err != nil {
349350
return nil, err
350351
}
351352

353+
// The collector gets the same pipeline prepended over opamp; see RecommendAgentConfig.
354+
if ic.fl.BooleanOrEmpty(ctx, flagger.FeatureUseJSONBody, featuretypes.NewFlaggerEvaluationContext(orgID)) {
355+
pipelines = append([]pipelinetypes.GettablePipeline{ic.getNormalizePipeline()}, pipelines...)
356+
}
357+
352358
result, collectorLogs, err := SimulatePipelinesProcessing(ctx, pipelines, request.Logs)
353359
if err != nil {
354360
return nil, err

pkg/query-service/app/logparsingpipeline/preview_test.go

Lines changed: 91 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,22 @@ import (
66
"testing"
77
"time"
88

9+
"github.com/SigNoz/signoz/pkg/flagger/flaggertest"
910
"github.com/SigNoz/signoz/pkg/query-service/model"
1011
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
1112
"github.com/SigNoz/signoz/pkg/types/pipelinetypes"
13+
"github.com/SigNoz/signoz/pkg/valuer"
1214
"github.com/google/uuid"
1315
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/entry"
16+
"github.com/stretchr/testify/assert"
1417
"github.com/stretchr/testify/require"
1518
)
1619

1720
func TestPipelinePreview(t *testing.T) {
1821
require := require.New(t)
1922

2023
testPipelines := []pipelinetypes.GettablePipeline{
21-
{
22-
StoreablePipeline: pipelinetypes.StoreablePipeline{
23-
OrderID: 1,
24-
Name: "pipeline1",
25-
Alias: "pipeline1",
26-
Enabled: true,
27-
},
28-
Filter: &v3.FilterSet{
29-
Operator: "AND",
30-
Items: []v3.FilterItem{
31-
{
32-
Key: v3.AttributeKey{
33-
Key: "method",
34-
DataType: v3.AttributeKeyDataTypeString,
35-
Type: v3.AttributeKeyTypeTag,
36-
},
37-
Operator: "=",
38-
Value: "GET",
39-
},
40-
},
41-
},
42-
Config: []pipelinetypes.PipelineOperator{
43-
{
44-
OrderId: 1,
45-
ID: "add",
46-
Type: "add",
47-
Field: "attributes.test",
48-
Value: "val",
49-
Enabled: true,
50-
Name: "test add",
51-
},
52-
},
53-
},
24+
makeTestAddAttributePipeline(),
5425
{
5526
StoreablePipeline: pipelinetypes.StoreablePipeline{
5627
OrderID: 2,
@@ -148,6 +119,93 @@ func TestPipelinePreview(t *testing.T) {
148119

149120
}
150121

122+
func TestPipelinePreviewNormalizesBodyWithJSONBodyEnabled(t *testing.T) {
123+
controller := &LogParsingPipelineController{fl: flaggertest.WithUseJSONBody(t, true)}
124+
125+
result, err := controller.PreviewLogsPipelines(
126+
context.Background(),
127+
valuer.GenerateUUID(),
128+
&PipelinesPreviewRequest{
129+
Pipelines: []pipelinetypes.GettablePipeline{makeTestAddAttributePipeline()},
130+
Logs: []model.SignozLog{
131+
makeTestSignozLog("test log body", map[string]interface{}{"method": "GET"}),
132+
makeTestSignozLog(
133+
`{"level":"error","msg":"json log body"}`,
134+
map[string]interface{}{"method": "GET"},
135+
),
136+
},
137+
},
138+
)
139+
140+
require.NoError(t, err)
141+
require.Len(t, result.OutputLogs, 2)
142+
143+
assert.Equal(t, `{"message":"test log body"}`, result.OutputLogs[0].Body)
144+
assert.Equal(
145+
t,
146+
`{"level":"error","message":"json log body"}`,
147+
result.OutputLogs[1].Body,
148+
)
149+
assert.Equal(t, "val", result.OutputLogs[0].Attributes_string["test"])
150+
}
151+
152+
func TestPipelinePreviewKeepsBodyAsIsWithJSONBodyDisabled(t *testing.T) {
153+
controller := &LogParsingPipelineController{fl: flaggertest.WithUseJSONBody(t, false)}
154+
155+
result, err := controller.PreviewLogsPipelines(
156+
context.Background(),
157+
valuer.GenerateUUID(),
158+
&PipelinesPreviewRequest{
159+
Pipelines: []pipelinetypes.GettablePipeline{makeTestAddAttributePipeline()},
160+
Logs: []model.SignozLog{
161+
makeTestSignozLog("test log body", map[string]interface{}{"method": "GET"}),
162+
},
163+
},
164+
)
165+
166+
require.NoError(t, err)
167+
require.Len(t, result.OutputLogs, 1)
168+
169+
assert.Equal(t, "test log body", result.OutputLogs[0].Body)
170+
assert.Equal(t, "val", result.OutputLogs[0].Attributes_string["test"])
171+
}
172+
173+
func makeTestAddAttributePipeline() pipelinetypes.GettablePipeline {
174+
return pipelinetypes.GettablePipeline{
175+
StoreablePipeline: pipelinetypes.StoreablePipeline{
176+
OrderID: 1,
177+
Name: "pipeline1",
178+
Alias: "pipeline1",
179+
Enabled: true,
180+
},
181+
Filter: &v3.FilterSet{
182+
Operator: "AND",
183+
Items: []v3.FilterItem{
184+
{
185+
Key: v3.AttributeKey{
186+
Key: "method",
187+
DataType: v3.AttributeKeyDataTypeString,
188+
Type: v3.AttributeKeyTypeTag,
189+
},
190+
Operator: "=",
191+
Value: "GET",
192+
},
193+
},
194+
},
195+
Config: []pipelinetypes.PipelineOperator{
196+
{
197+
OrderId: 1,
198+
ID: "add",
199+
Type: "add",
200+
Field: "attributes.test",
201+
Value: "val",
202+
Enabled: true,
203+
Name: "test add",
204+
},
205+
},
206+
}
207+
}
208+
151209
func TestGrokParsingProcessor(t *testing.T) {
152210
require := require.New(t)
153211

0 commit comments

Comments
 (0)