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 06f2966639 Expose trace span attribute filters
06f2966639 is described below
commit 06f296663998fac9bd56a347db99d4ba12fe9819
Author: Logic <[email protected]>
AuthorDate: Tue Jun 9 21:58:40 2026 +0800
Expose trace span attribute filters
---
web-next/app/trace/manage/page.test.tsx | 25 ++++++++++++++++---------
web-next/app/trace/manage/route-state.test.ts | 3 ++-
web-next/app/trace/manage/trace-manage-page.tsx | 15 +++++++++++++++
web-next/lib/i18n-runtime-messages.ts | 4 ++++
web-next/lib/trace-manage/query-state.test.ts | 12 ++++++++----
web-next/lib/trace-manage/query-state.ts | 13 ++++++++++---
web-next/lib/trace-manage/view-model.ts | 1 +
7 files changed, 56 insertions(+), 17 deletions(-)
diff --git a/web-next/app/trace/manage/page.test.tsx
b/web-next/app/trace/manage/page.test.tsx
index 11d5a92b11..55894d5aa1 100644
--- a/web-next/app/trace/manage/page.test.tsx
+++ b/web-next/app/trace/manage/page.test.tsx
@@ -220,6 +220,7 @@ vi.mock('@/lib/trace-manage/query-state', () => {
if (query.spanId) params.set('spanId', query.spanId);
if (query.serviceName) params.set('serviceName', query.serviceName);
if (query.resourceFilter) params.set('resourceFilter',
query.resourceFilter);
+ if (query.attributeFilter) params.set('attributeFilter',
query.attributeFilter);
if (query.operationName) params.set('operationName', query.operationName);
if (query.minDurationMs) params.set('minDurationMs', query.minDurationMs);
if (query.maxDurationMs) params.set('maxDurationMs', query.maxDurationMs);
@@ -254,6 +255,10 @@ vi.mock('@/lib/trace-manage/query-state', () => {
listParams.set('resourceFilter', query.resourceFilter);
overviewParams.set('resourceFilter', query.resourceFilter);
}
+ if (query.attributeFilter) {
+ listParams.set('attributeFilter', query.attributeFilter);
+ overviewParams.set('attributeFilter', query.attributeFilter);
+ }
if (query.operationName) {
listParams.set('operationName', query.operationName);
overviewParams.set('operationName', query.operationName);
@@ -294,6 +299,7 @@ vi.mock('@/lib/trace-manage/query-state', () => {
spanId: searchParams.get('spanId') || '',
serviceName: searchParams.get('serviceName') || '',
resourceFilter: searchParams.get('resourceFilter') || '',
+ attributeFilter: searchParams.get('attributeFilter') || '',
operationName: searchParams.get('operationName') || '',
minDurationMs: searchParams.get('minDurationMs') || '',
maxDurationMs: searchParams.get('maxDurationMs') || '',
@@ -417,6 +423,7 @@ function buildTraceManageRouteState():
TraceManageRouteState {
spanId: mockState.searchParams.get('spanId') || '',
serviceName: mockState.searchParams.get('serviceName') || '',
resourceFilter: mockState.searchParams.get('resourceFilter') || '',
+ attributeFilter: mockState.searchParams.get('attributeFilter') || '',
operationName: mockState.searchParams.get('operationName') || '',
minDurationMs: mockState.searchParams.get('minDurationMs') || '',
maxDurationMs: mockState.searchParams.get('maxDurationMs') || '',
@@ -520,7 +527,7 @@ afterEach(() => {
describe('trace manage page', () => {
it('renders the OTLP cold trace workbench and keeps the filtered trace
endpoints', async () => {
- mockState.searchParams = new
URLSearchParams('traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=POST%20%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true');
+ mockState.searchParams = new
URLSearchParams('traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route%20CONTAINS%20checkout&operationName=POST%20%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true');
apiMessageGet
.mockResolvedValueOnce({ totalTraceCount: 8, errorTraceCount: 2,
latestObservedAt: 1713200000000, hasActiveTrace: true })
.mockResolvedValueOnce({ content: [] });
@@ -531,7 +538,7 @@ describe('trace manage page', () => {
expect(html).toContain('data-trace-manage-route="otlp-hertzbeat-ui-trace-workbench"');
expect(html).toContain('data-loading-copy="Loading trace workbench"');
expect(html).toContain(
-
'data-cache-key="trace-manage:list:/traces/list?pageIndex=0&pageSize=8&traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=POST+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root|/traces/stats/overview?traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=POST+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=tr
[...]
+
'data-cache-key="trace-manage:list:/traces/list?pageIndex=0&pageSize=8&traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&operationName=POST+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root|/traces/stats/overview?traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checko
[...]
);
expect(html).toContain('data-cache-settled-ttl="10000"');
expect(html).toContain('data-trace-manage-style-baseline="hertzbeat-ui-matte"');
@@ -722,13 +729,13 @@ describe('trace manage page', () => {
expect(html).not.toContain('Create an Alert');
expect(html).not.toContain('Add to Dashboard');
expect(apiMessageGet.mock.calls).toEqual([
-
['/traces/stats/overview?traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=POST+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root',
{ signal: expect.any(AbortSignal) }],
-
['/traces/list?pageIndex=0&pageSize=8&traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=POST+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root',
{ signal: expect.any(AbortSignal) }]
+
['/traces/stats/overview?traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&operationName=POST+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root',
{ signal: expect.any(AbortSignal) }],
+
['/traces/list?pageIndex=0&pageSize=8&traceId=trace-123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&operationName=POST+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root',
{ signal: expect.any(AbortSignal) }]
]);
}, 60000);
it('loads and renders trace group-by results when the route has an active
groupBy', async () => {
- mockState.searchParams = new
URLSearchParams('serviceName=checkout&resourceFilter=service.version%3D1.2.3&groupBy=resource%3Aservice.version&groupLimit=7&groupOrder=latency-p95-desc&groupMinCount=5');
+ mockState.searchParams = new
URLSearchParams('serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route%20CONTAINS%20checkout&groupBy=resource%3Aservice.version&groupLimit=7&groupOrder=latency-p95-desc&groupMinCount=5');
apiMessageGet
.mockResolvedValueOnce({ totalTraceCount: 8, errorTraceCount: 2,
latestObservedAt: 1713200000000, hasActiveTrace: true })
.mockResolvedValueOnce({ content: [] })
@@ -749,7 +756,7 @@ describe('trace manage page', () => {
await mockState.lastLoad?.();
expect(html).toContain('data-cache-key="trace-manage:list:');
-
expect(html).toContain('/traces/stats/group-by?serviceName=checkout&resourceFilter=service.version%3D1.2.3&spanScope=root&groupBy=resource%3Aservice.version&limit=7&orderBy=latency-p95-desc&minCount=5');
+
expect(html).toContain('/traces/stats/group-by?serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&spanScope=root&groupBy=resource%3Aservice.version&limit=7&orderBy=latency-p95-desc&minCount=5');
expect(html).toContain('data-trace-manage-group-panel="hertzbeat-ui-trace-group-results"');
expect(html).toContain('data-trace-manage-group-panel-owner="hertzbeat-ui-panel-surface"');
expect(html).toContain('data-trace-manage-group-by="resource:service.version"');
@@ -769,9 +776,9 @@ describe('trace manage page', () => {
expect(html).toContain('84.5ms');
expect(html).toContain('210ms');
expect(apiMessageGet.mock.calls).toEqual([
-
['/traces/stats/overview?serviceName=checkout&resourceFilter=service.version%3D1.2.3&spanScope=root',
{ signal: expect.any(AbortSignal) }],
-
['/traces/list?pageIndex=0&pageSize=8&serviceName=checkout&resourceFilter=service.version%3D1.2.3&spanScope=root',
{ signal: expect.any(AbortSignal) }],
-
['/traces/stats/group-by?serviceName=checkout&resourceFilter=service.version%3D1.2.3&spanScope=root&groupBy=resource%3Aservice.version&limit=7&orderBy=latency-p95-desc&minCount=5',
{ signal: expect.any(AbortSignal) }]
+
['/traces/stats/overview?serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&spanScope=root',
{ signal: expect.any(AbortSignal) }],
+
['/traces/list?pageIndex=0&pageSize=8&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&spanScope=root',
{ signal: expect.any(AbortSignal) }],
+
['/traces/stats/group-by?serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&spanScope=root&groupBy=resource%3Aservice.version&limit=7&orderBy=latency-p95-desc&minCount=5',
{ signal: expect.any(AbortSignal) }]
]);
}, 15000);
diff --git a/web-next/app/trace/manage/route-state.test.ts
b/web-next/app/trace/manage/route-state.test.ts
index b75a8dbfbe..3773a17c09 100644
--- a/web-next/app/trace/manage/route-state.test.ts
+++ b/web-next/app/trace/manage/route-state.test.ts
@@ -19,6 +19,7 @@ describe('trace manage route state', () => {
spanId: 'span-456',
serviceName: 'checkout',
resourceFilter: 'service.version=1.2.3',
+ attributeFilter: 'http.route CONTAINS checkout',
operationName: 'GET /checkout',
minDurationMs: '100',
maxDurationMs: '500',
@@ -28,7 +29,7 @@ describe('trace manage route state', () => {
);
expect(route).toBe(
-
'/trace/manage?traceId=trace-123&spanId=span-456&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=GET+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&start=1713200000000&end=1713203600000&timeRange=last-1h&refresh=30&live=false&tz=Asia%2FShanghai&entityId=42&entityName=checkout&returnTo=%2Foverview&serviceNamespace=payments&environment=prod&codeRepo=https%3A%2F%2Fexample.test%2Frepo&codeProvider=github&codePath=src%2Ftrace.ts&codeSearch=Trace
[...]
+
'/trace/manage?traceId=trace-123&spanId=span-456&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&operationName=GET+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&start=1713200000000&end=1713203600000&timeRange=last-1h&refresh=30&live=false&tz=Asia%2FShanghai&entityId=42&entityName=checkout&returnTo=%2Foverview&serviceNamespace=payments&environment=prod&codeRepo=https%3A%2F%2Fexample.test%2Frepo&codeProvider=gi
[...]
);
expect(route).not.toContain('returnLabel=');
});
diff --git a/web-next/app/trace/manage/trace-manage-page.tsx
b/web-next/app/trace/manage/trace-manage-page.tsx
index ad5abb5d30..bc8ace5d71 100644
--- a/web-next/app/trace/manage/trace-manage-page.tsx
+++ b/web-next/app/trace/manage/trace-manage-page.tsx
@@ -148,6 +148,7 @@ const emptyTraceQuery: TraceQueryState = {
spanId: '',
serviceName: '',
resourceFilter: '',
+ attributeFilter: '',
operationName: '',
minDurationMs: '',
maxDurationMs: '',
@@ -389,6 +390,7 @@ function buildTraceSavedViewDescription(query:
TraceQueryState, routeContext: Si
query.serviceName.trim() ? `${t('trace.manage.saved-view.field.service')}:
${compactTraceSavedViewValue(query.serviceName)}` : '',
query.operationName?.trim() ?
`${t('trace.manage.saved-view.field.operation')}:
${compactTraceSavedViewValue(query.operationName)}` : '',
query.resourceFilter?.trim() ?
`${t('trace.manage.saved-view.field.resource-filter')}:
${compactTraceSavedViewValue(query.resourceFilter)}` : '',
+ query.attributeFilter?.trim() ?
`${t('trace.manage.saved-view.field.attribute-filter')}:
${compactTraceSavedViewValue(query.attributeFilter)}` : '',
query.minDurationMs?.trim() ?
`${t('trace.manage.saved-view.field.min-duration')}:
${compactTraceSavedViewValue(query.minDurationMs)}ms` : '',
query.maxDurationMs?.trim() ?
`${t('trace.manage.saved-view.field.max-duration')}:
${compactTraceSavedViewValue(query.maxDurationMs)}ms` : '',
query.errorOnly ? t('trace.manage.saved-view.field.errors-only') : '',
@@ -2258,6 +2260,19 @@ function TraceExplorer({
'data-trace-manage-resource-filter-input-owner':
'hertzbeat-ui-query-token-field'
}}
/>
+ <HzQueryTokenField
+ width="trace-id"
+ aria-label={t('trace.manage.route.query.attribute-filter')}
+ value={draft.attributeFilter || ''}
+ onChange={event => setDraft(updateDraftField('attributeFilter',
event.target.value))}
+ placeholder={t('trace.manage.route.query.attribute-filter')}
+ data-trace-manage-attribute-filter-input="true"
+ fieldProps={{
+ 'data-trace-manage-query-token-field': 'attribute-filter',
+ 'data-trace-manage-query-token-field-owner':
'hertzbeat-ui-query-token-field',
+ 'data-trace-manage-attribute-filter-input-owner':
'hertzbeat-ui-query-token-field'
+ }}
+ />
<HzQueryTokenField
width="root-span"
aria-label={t('trace.manage.route.query.operation')}
diff --git a/web-next/lib/i18n-runtime-messages.ts
b/web-next/lib/i18n-runtime-messages.ts
index 8274ab2d1e..d96900c35c 100644
--- a/web-next/lib/i18n-runtime-messages.ts
+++ b/web-next/lib/i18n-runtime-messages.ts
@@ -2577,6 +2577,7 @@ export const SUPPLEMENTAL_MESSAGES:
Partial<Record<LocaleCode, Messages>> = {
'trace.manage.route.action.catalog': 'Entity catalog',
'trace.manage.route.query.service': 'Service name',
'trace.manage.route.query.resource-filter': 'Resource filter',
+ 'trace.manage.route.query.attribute-filter': 'Span attribute filter',
'trace.manage.route.query.operation': 'Operation',
'trace.manage.route.query.min-duration': 'Minimum duration',
'trace.manage.route.query.min-duration.placeholder': 'Min ms',
@@ -2626,6 +2627,7 @@ export const SUPPLEMENTAL_MESSAGES:
Partial<Record<LocaleCode, Messages>> = {
'trace.manage.saved-view.field.service': 'service',
'trace.manage.saved-view.field.operation': 'operation',
'trace.manage.saved-view.field.resource-filter': 'resource',
+ 'trace.manage.saved-view.field.attribute-filter': 'attribute',
'trace.manage.saved-view.field.min-duration': 'min',
'trace.manage.saved-view.field.max-duration': 'max',
'trace.manage.saved-view.field.errors-only': 'errors only',
@@ -7033,6 +7035,7 @@ export const SUPPLEMENTAL_MESSAGES:
Partial<Record<LocaleCode, Messages>> = {
'trace.manage.route.action.catalog': '对象目录',
'trace.manage.route.query.service': '服务名称',
'trace.manage.route.query.resource-filter': '资源过滤',
+ 'trace.manage.route.query.attribute-filter': 'Span 属性过滤',
'trace.manage.route.query.operation': '操作',
'trace.manage.route.query.min-duration': '最短耗时',
'trace.manage.route.query.min-duration.placeholder': '最小 ms',
@@ -7082,6 +7085,7 @@ export const SUPPLEMENTAL_MESSAGES:
Partial<Record<LocaleCode, Messages>> = {
'trace.manage.saved-view.field.service': '服务',
'trace.manage.saved-view.field.operation': '操作',
'trace.manage.saved-view.field.resource-filter': '资源',
+ 'trace.manage.saved-view.field.attribute-filter': '属性',
'trace.manage.saved-view.field.min-duration': '最小',
'trace.manage.saved-view.field.max-duration': '最大',
'trace.manage.saved-view.field.errors-only': '仅错误',
diff --git a/web-next/lib/trace-manage/query-state.test.ts
b/web-next/lib/trace-manage/query-state.test.ts
index 6baa476399..44781f7de7 100644
--- a/web-next/lib/trace-manage/query-state.test.ts
+++ b/web-next/lib/trace-manage/query-state.test.ts
@@ -3,12 +3,13 @@ import { DEFAULT_TRACE_TABLE_COLUMNS, buildTraceRouteUrl,
buildTraceUrls, queryS
describe('trace query state codec', () => {
it('reads query state from search params', () => {
- const params = new
URLSearchParams('traceId=abc123&spanId=span456&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=GET%20%2Fcheckout&minDurationMs=100&maxDurationMs=500&groupBy=resource%3Aservice.version&groupLimit=7&groupOrder=latency-p95-desc&groupMinCount=5&errorOnly=true');
+ const params = new
URLSearchParams('traceId=abc123&spanId=span456&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route%20CONTAINS%20checkout&operationName=GET%20%2Fcheckout&minDurationMs=100&maxDurationMs=500&groupBy=resource%3Aservice.version&groupLimit=7&groupOrder=latency-p95-desc&groupMinCount=5&errorOnly=true');
expect(queryStateFromParams(params)).toEqual({
traceId: 'abc123',
spanId: 'span456',
serviceName: 'checkout',
resourceFilter: 'service.version=1.2.3',
+ attributeFilter: 'http.route CONTAINS checkout',
operationName: 'GET /checkout',
minDurationMs: '100',
maxDurationMs: '500',
@@ -30,6 +31,7 @@ describe('trace query state codec', () => {
spanId: [' span-456 ', 'span-ignored'],
serviceName: [' checkout ', 'payments'],
resourceFilter: [' service.version=1.2.3 ', 'service.version=ignored'],
+ attributeFilter: [' http.route CONTAINS checkout ', 'http.route CONTAINS
ignored'],
groupBy: [' resource:service.version ', 'resource:host.name'],
groupLimit: [' 7 ', '12'],
groupOrder: [' error-count-desc ', 'latency-p95-desc'],
@@ -51,6 +53,7 @@ describe('trace query state codec', () => {
spanId: 'span-456',
serviceName: 'checkout',
resourceFilter: 'service.version=1.2.3',
+ attributeFilter: 'http.route CONTAINS checkout',
operationName: '',
minDurationMs: '',
maxDurationMs: '',
@@ -143,6 +146,7 @@ describe('trace query state codec', () => {
spanId: 'span456',
serviceName: 'checkout',
resourceFilter: 'service.version=1.2.3',
+ attributeFilter: 'http.route CONTAINS checkout',
operationName: 'GET /checkout',
minDurationMs: '100',
maxDurationMs: '500',
@@ -156,9 +160,9 @@ describe('trace query state codec', () => {
listPageIndex: '2'
})
).toEqual({
- listUrl:
'/traces/list?pageIndex=2&pageSize=50&traceId=abc123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=GET+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root',
- overviewUrl:
'/traces/stats/overview?traceId=abc123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=GET+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root',
- groupByUrl:
'/traces/stats/group-by?traceId=abc123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&operationName=GET+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root&groupBy=resource%3Aservice.version&limit=7&orderBy=latency-p95-desc&minCount=5'
+ listUrl:
'/traces/list?pageIndex=2&pageSize=50&traceId=abc123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&operationName=GET+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root',
+ overviewUrl:
'/traces/stats/overview?traceId=abc123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&operationName=GET+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root',
+ groupByUrl:
'/traces/stats/group-by?traceId=abc123&serviceName=checkout&resourceFilter=service.version%3D1.2.3&attributeFilter=http.route+CONTAINS+checkout&operationName=GET+%2Fcheckout&minDurationMs=100&maxDurationMs=500&errorOnly=true&spanScope=root&groupBy=resource%3Aservice.version&limit=7&orderBy=latency-p95-desc&minCount=5'
});
expect(buildTraceRouteUrl({ traceId: 'abc123', spanId: 'span456',
serviceName: 'checkout', errorOnly: false, spanScope: 'root', listPageSize:
'50', listPageIndex: '2' })).toBe(
'/trace/manage?traceId=abc123&spanId=span456&serviceName=checkout&listPageSize=50&listPageIndex=2'
diff --git a/web-next/lib/trace-manage/query-state.ts
b/web-next/lib/trace-manage/query-state.ts
index 42f693317c..4d3ee17e09 100644
--- a/web-next/lib/trace-manage/query-state.ts
+++ b/web-next/lib/trace-manage/query-state.ts
@@ -13,6 +13,7 @@ export type TraceQueryState = {
spanId: string;
serviceName: string;
resourceFilter?: string;
+ attributeFilter?: string;
operationName?: string;
minDurationMs?: string;
maxDurationMs?: string;
@@ -97,6 +98,7 @@ export function queryStateFromParams(searchParams:
SearchParamReader): TraceQuer
spanId: readSearchParam(searchParams, 'spanId'),
serviceName: readSearchParam(searchParams, 'serviceName'),
resourceFilter: readSearchParam(searchParams, 'resourceFilter'),
+ attributeFilter: readSearchParam(searchParams, 'attributeFilter'),
operationName: readSearchParam(searchParams, 'operationName'),
minDurationMs: readNonNegativeIntegerSearchParam(searchParams,
'minDurationMs'),
maxDurationMs: readNonNegativeIntegerSearchParam(searchParams,
'maxDurationMs'),
@@ -224,6 +226,7 @@ export function buildTraceRouteUrl(query: TraceQueryState,
options?: { view?: Tr
if (query.spanId.trim()) params.set('spanId', query.spanId.trim());
if (query.serviceName.trim()) params.set('serviceName',
query.serviceName.trim());
if (query.resourceFilter?.trim()) params.set('resourceFilter',
query.resourceFilter.trim());
+ if (query.attributeFilter?.trim()) params.set('attributeFilter',
query.attributeFilter.trim());
if (query.operationName?.trim()) params.set('operationName',
query.operationName.trim());
const minDurationMs = readNonNegativeDurationValue(query.minDurationMs);
const maxDurationMs = readNonNegativeDurationValue(query.maxDurationMs);
@@ -278,7 +281,7 @@ export function buildTraceUrls(
const listParams = new URLSearchParams({ pageIndex: listPageIndex, pageSize:
listPageSize });
if (query.traceId.trim()) listParams.set('traceId', query.traceId.trim());
if (query.serviceName.trim()) listParams.set('serviceName',
query.serviceName.trim());
- appendTraceResourceFilterParam(listParams, query);
+ appendTraceFilterParams(listParams, query);
if (query.operationName?.trim()) listParams.set('operationName',
query.operationName.trim());
appendTraceDurationParams(listParams, query);
if (query.errorOnly) listParams.set('errorOnly', 'true');
@@ -288,7 +291,7 @@ export function buildTraceUrls(
const overviewParams = new URLSearchParams();
if (query.traceId.trim()) overviewParams.set('traceId',
query.traceId.trim());
if (query.serviceName.trim()) overviewParams.set('serviceName',
query.serviceName.trim());
- appendTraceResourceFilterParam(overviewParams, query);
+ appendTraceFilterParams(overviewParams, query);
if (query.operationName?.trim()) overviewParams.set('operationName',
query.operationName.trim());
appendTraceDurationParams(overviewParams, query);
if (query.errorOnly) overviewParams.set('errorOnly', 'true');
@@ -327,9 +330,13 @@ function appendTraceDurationParams(params:
URLSearchParams, query: TraceQuerySta
if (maxDurationMs) params.set('maxDurationMs', maxDurationMs);
}
-function appendTraceResourceFilterParam(params: URLSearchParams, query:
TraceQueryState) {
+function appendTraceFilterParams(params: URLSearchParams, query:
TraceQueryState) {
const resourceFilter = query.resourceFilter?.trim() || '';
if (resourceFilter) {
params.set('resourceFilter', resourceFilter);
}
+ const attributeFilter = query.attributeFilter?.trim() || '';
+ if (attributeFilter) {
+ params.set('attributeFilter', attributeFilter);
+ }
}
diff --git a/web-next/lib/trace-manage/view-model.ts
b/web-next/lib/trace-manage/view-model.ts
index d78980e959..67e7988944 100644
--- a/web-next/lib/trace-manage/view-model.ts
+++ b/web-next/lib/trace-manage/view-model.ts
@@ -772,6 +772,7 @@ export function buildTraceAlertRuleDraft(query:
TraceQueryState, routeContext: S
['spanId', query.spanId || routeContext.spanId],
['serviceName', query.serviceName || routeContext.serviceName],
['resourceFilter', query.resourceFilter],
+ ['attributeFilter', query.attributeFilter],
['operationName', query.operationName],
['minDurationMs', query.minDurationMs],
['maxDurationMs', query.maxDurationMs],
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]