-
Notifications
You must be signed in to change notification settings - Fork 584
feat: Add tags dropdown to SPM page for filtering metrics #3065
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: Add tags dropdown to SPM page for filtering metrics #3065
Conversation
How to use the Graphite Merge QueueAdd the label merge-queue to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. |
047cbc8
to
556d48b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to stress test how it looks when all tag drop downs don't fit in one line
@@ -0,0 +1,31 @@ | |||
/* | |||
Copyright (c) 2025 The Jaeger Authors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use spdx id instead of full header
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use spdx id
@@ -105,6 +105,12 @@ const defaultConfig: Config = { | |||
}, | |||
}, | |||
docsLink: 'https://www.jaegertracing.io/docs/latest/spm/', | |||
tagFilters: [], | |||
tagAttributes: [ | |||
{ name: 'environment', label: 'Environment' }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non standard, cannot be default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I commited some of the testing values. Will remove
tagAttributes: [ | ||
{ name: 'environment', label: 'Environment' }, | ||
{ name: 'http.status_code', label: 'HTTP Status' }, | ||
{ name: 'http.method', label: 'HTTP Method' }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default can only be something that will work out if the box. Including http route by default is nice, but how will it work with Prometheus if the label is not exposed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default, i can see these; the traces are generated using microsim. http.Method isnt there by default in prometheus, it'll require spanmetrics to be configured.
harshil.gupta@harshil jaeger % curl "http://localhost:9090/api/v1/labels" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 148 100 148 0 0 18642 0 --:--:-- --:--:-- --:--:-- 21142
{
"status": "success",
"data": [
"__name__",
"exported_job",
"instance",
"job",
"le",
"otel_scope_name",
"service_name",
"span_kind",
"span_name",
"status_code"
]
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see there is a operation
in prometheus by default. Maybe we can include that as default.
labels": [
{
"name": "operation",
"value": "/GetDriver"
},
{
"name": "service_name",
"value": "redis"
}
],
@@ -71,6 +71,18 @@ export type MonitorConfig = { | |||
menuEnabled?: boolean; | |||
emptyState?: MonitorEmptyStateConfig; | |||
docsLink?: string; | |||
tagFilters?: readonly TagFilter[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add documentation to new fields and types
@@ -31,6 +31,7 @@ export type MetricsAPIQueryParams = { | |||
step: number; | |||
ratePer: number; | |||
spanKind: spanKinds; | |||
tag?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add documentation
}, [valueAsObject]); | ||
|
||
// Handle value selection for a specific attribute | ||
const handleValueChange = useCallback((attributeName, selectedValue) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why useCallback here? the only place it is used is passing it to an unmemoized component in a prop that creates a new function every render anyway.
multiple things would need to change for there to be any perf impact
.map(([key, val]) => `${key}=${val}`) | ||
.join(' '); | ||
|
||
onChange(tagString); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
}, [service, tagAttributes]); | ||
|
||
// Update selected values when value prop changes | ||
useEffect(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but this will clobber any local state changes you make every time the prop changes. you need to either lift all of this state up to the parent or keep state only for changes made at this level and merge local state with valueAsObject
in render e..g.,
// somewhere in render
const [localObjChanges, setLocalObjChanges] = useState() // don't attempt to sync state this with parent prop
// takes parent prop and patches local state changes on top in pure way
const selectedValues = mergeFn(valueAsObject, localObjChanges)
Hey @yurishkuro @mdwyer6 , I truly appreciate you reviewing. |
@yurishkuro Here's what the stress test looks like |
This commit adds functionality to filter metrics by tags in the Service Performance Monitoring (SPM) page. Signed-off-by: Harshil Gupta <harshilgupta1808@gmail.com>
Signed-off-by: Harshil Gupta <harshilgupta1808@gmail.com>
Signed-off-by: Harshil Gupta <harshilgupta1808@gmail.com>
Signed-off-by: Harshil Gupta <harshilgupta1808@gmail.com>
Signed-off-by: Harshil Gupta <harshilgupta1808@gmail.com>
92deeca
to
4d21f20
Compare
This commit adds functionality to filter metrics by tags in the Service Performance Monitoring (SPM) page.
Which problem is this PR solving?
Description of the changes
How was this change tested?
Checklist
jaeger
:make lint test
jaeger-ui
:npm run lint
andnpm run test