Skip to content

Commit 0dc8c85

Browse files
committed
Align log attribute group drilldown
1 parent d61e8f1 commit 0dc8c85

2 files changed

Lines changed: 49 additions & 1 deletion

File tree

web-next/lib/signal-dashboards.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,48 @@ describe('signal dashboards API client', () => {
25422542
}));
25432543
});
25442544

2545+
it('maps log attribute groups to log attribute-filter drilldowns with entity context', async () => {
2546+
const [logPlan] = buildSignalDashboardExecutionPlans({
2547+
dashboardKey: 'log-attribute-breakouts',
2548+
title: 'Log attribute breakouts',
2549+
description: 'Grouped log panels',
2550+
tags: 'logs',
2551+
layout: '[]',
2552+
widgets: JSON.stringify([
2553+
{
2554+
id: 'log-route-breakout',
2555+
signal: 'logs',
2556+
title: 'Logs by route',
2557+
visualization: 'list',
2558+
route: '/log/manage?view=list&serviceName=checkout&serviceNamespace=payments&entityId=4200&entityType=service&entityName=Checkout+API&source=otlp&collector=collector-a&template=spring-boot&groupBy=attribute:http.route&groupLimit=8'
2559+
}
2560+
])
2561+
});
2562+
2563+
const logResult = await executeSignalDashboardPanelPlan(logPlan, async url => {
2564+
expect(url).toBe('/logs/stats/group-by?entityId=4200&entityType=service&serviceName=checkout&serviceNamespace=payments&groupBy=attribute%3Ahttp.route&limit=8');
2565+
return {
2566+
groupBy: 'attribute:http.route',
2567+
groups: [{
2568+
value: 'POST /checkout',
2569+
count: 9,
2570+
errorCount: 3
2571+
}]
2572+
};
2573+
});
2574+
const logRenderer = buildSignalDashboardPanelRuntimeRenderDescriptor(logPlan, logResult);
2575+
2576+
expect(logRenderer.rows[0]).toEqual(expect.objectContaining({
2577+
key: 'log-route-breakout:group:0',
2578+
title: 'POST /checkout',
2579+
copy: '9 logs · 3 errors',
2580+
meta: 'attribute:http.route',
2581+
relatedSignal: 'logs',
2582+
relatedHandoffHref: '/log/manage?serviceName=checkout&serviceNamespace=payments&entityId=4200&entityType=service&entityName=Checkout+API&source=otlp&collector=collector-a&template=spring-boot&view=list&attributeFilter=http.route%3APOST+%2Fcheckout'
2583+
}));
2584+
expect(logRenderer.rows[0]?.relatedHandoffHref).not.toContain('attributeFilter=http.route%3D');
2585+
});
2586+
25452587
it('unwraps backend message envelopes for group-by dashboard panels before rendering', async () => {
25462588
const [logPlan, tracePlan] = buildSignalDashboardExecutionPlans({
25472589
dashboardKey: 'wrapped-breakouts',

web-next/lib/signal-dashboards.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2718,7 +2718,13 @@ function buildLogGroupRelatedHandoff(plan: SignalDashboardPanelExecutionPlan, gr
27182718
]);
27192719
target.searchParams.set('view', 'list');
27202720
if (normalizedGroupBy.startsWith('attribute:')) {
2721-
target.searchParams.set('attributeFilter', mergeTraceResourceFilterExpression(target.searchParams.get('attributeFilter'), `${normalizedGroupBy.slice('attribute:'.length)}=${normalizedValue}`));
2721+
target.searchParams.set(
2722+
'attributeFilter',
2723+
mergeTraceResourceFilterExpression(
2724+
target.searchParams.get('attributeFilter'),
2725+
`${normalizedGroupBy.slice('attribute:'.length)}:${normalizedValue}`
2726+
)
2727+
);
27222728
} else {
27232729
const key = normalizedGroupBy.startsWith('resource:') ? normalizedGroupBy.slice('resource:'.length) : normalizedGroupBy;
27242730
target.searchParams.set('resourceFilter', mergeTraceResourceFilterExpression(target.searchParams.get('resourceFilter'), `${key}=${normalizedValue}`));

0 commit comments

Comments
 (0)