This is an automated email from the ASF dual-hosted git repository.

zqr10159 pushed a commit to branch 2.0.0
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/2.0.0 by this push:
     new 0dc8c850a6 Align log attribute group drilldown
0dc8c850a6 is described below

commit 0dc8c850a617b739dc34841ee9b143d91cbd7ae6
Author: Logic <[email protected]>
AuthorDate: Tue Jun 9 18:22:41 2026 +0800

    Align log attribute group drilldown
---
 web-next/lib/signal-dashboards.test.ts | 42 ++++++++++++++++++++++++++++++++++
 web-next/lib/signal-dashboards.ts      |  8 ++++++-
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/web-next/lib/signal-dashboards.test.ts 
b/web-next/lib/signal-dashboards.test.ts
index 6838ac86cd..3faeff5d7a 100644
--- a/web-next/lib/signal-dashboards.test.ts
+++ b/web-next/lib/signal-dashboards.test.ts
@@ -2542,6 +2542,48 @@ describe('signal dashboards API client', () => {
     }));
   });
 
+  it('maps log attribute groups to log attribute-filter drilldowns with entity 
context', async () => {
+    const [logPlan] = buildSignalDashboardExecutionPlans({
+      dashboardKey: 'log-attribute-breakouts',
+      title: 'Log attribute breakouts',
+      description: 'Grouped log panels',
+      tags: 'logs',
+      layout: '[]',
+      widgets: JSON.stringify([
+        {
+          id: 'log-route-breakout',
+          signal: 'logs',
+          title: 'Logs by route',
+          visualization: 'list',
+          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'
+        }
+      ])
+    });
+
+    const logResult = await executeSignalDashboardPanelPlan(logPlan, async url 
=> {
+      
expect(url).toBe('/logs/stats/group-by?entityId=4200&entityType=service&serviceName=checkout&serviceNamespace=payments&groupBy=attribute%3Ahttp.route&limit=8');
+      return {
+        groupBy: 'attribute:http.route',
+        groups: [{
+          value: 'POST /checkout',
+          count: 9,
+          errorCount: 3
+        }]
+      };
+    });
+    const logRenderer = 
buildSignalDashboardPanelRuntimeRenderDescriptor(logPlan, logResult);
+
+    expect(logRenderer.rows[0]).toEqual(expect.objectContaining({
+      key: 'log-route-breakout:group:0',
+      title: 'POST /checkout',
+      copy: '9 logs ยท 3 errors',
+      meta: 'attribute:http.route',
+      relatedSignal: 'logs',
+      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'
+    }));
+    
expect(logRenderer.rows[0]?.relatedHandoffHref).not.toContain('attributeFilter=http.route%3D');
+  });
+
   it('unwraps backend message envelopes for group-by dashboard panels before 
rendering', async () => {
     const [logPlan, tracePlan] = buildSignalDashboardExecutionPlans({
       dashboardKey: 'wrapped-breakouts',
diff --git a/web-next/lib/signal-dashboards.ts 
b/web-next/lib/signal-dashboards.ts
index cac98d9b62..1dd6c6f853 100644
--- a/web-next/lib/signal-dashboards.ts
+++ b/web-next/lib/signal-dashboards.ts
@@ -2718,7 +2718,13 @@ function buildLogGroupRelatedHandoff(plan: 
SignalDashboardPanelExecutionPlan, gr
   ]);
   target.searchParams.set('view', 'list');
   if (normalizedGroupBy.startsWith('attribute:')) {
-    target.searchParams.set('attributeFilter', 
mergeTraceResourceFilterExpression(target.searchParams.get('attributeFilter'), 
`${normalizedGroupBy.slice('attribute:'.length)}=${normalizedValue}`));
+    target.searchParams.set(
+      'attributeFilter',
+      mergeTraceResourceFilterExpression(
+        target.searchParams.get('attributeFilter'),
+        `${normalizedGroupBy.slice('attribute:'.length)}:${normalizedValue}`
+      )
+    );
   } else {
     const key = normalizedGroupBy.startsWith('resource:') ? 
normalizedGroupBy.slice('resource:'.length) : normalizedGroupBy;
     target.searchParams.set('resourceFilter', 
mergeTraceResourceFilterExpression(target.searchParams.get('resourceFilter'), 
`${key}=${normalizedValue}`));


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to