observability: new page based on dataplane observability API#2205
observability: new page based on dataplane observability API#2205nicolaferraro merged 14 commits intomasterfrom
Conversation
| "react-markdown": "^10.1.0", | ||
| "react-simple-code-editor": "^0.14.1", | ||
| "react-syntax-highlighter": "^15.6.6", | ||
| "recharts": "2.15.4", |
There was a problem hiding this comment.
Let's use recharts v3 shadcn-ui/ui#7669 which will require components to be upgraded.
We can do that in a followup PR
|
|
||
| import ObservabilityPage from '../../components/pages/observability/observability-page'; | ||
|
|
||
| export const Route = createFileRoute('/observability/')({ |
There was a problem hiding this comment.
will this be required for standalone mode
|
@claude could you review, focus on simplicity and ensure it follows some well known frontend best practices |
There was a problem hiding this comment.
this component will require updating to support shadcn chart + recharts v3 major release.
| export type TimeRange = '5m' | '15m' | '30m' | '1h' | '3h' | '6h'; | ||
|
|
||
| const TIME_RANGE_MS: Record<TimeRange, number> = { | ||
| '5m': 5 * 60 * 1000, | ||
| '15m': 15 * 60 * 1000, | ||
| '30m': 30 * 60 * 1000, | ||
| '1h': 60 * 60 * 1000, | ||
| '3h': 3 * 60 * 60 * 1000, | ||
| '6h': 6 * 60 * 60 * 1000, | ||
| }; |
There was a problem hiding this comment.
@weeco implemented this for transcripts/traces UI, can you please adapt a similar approach to follow the same practices?
There was a problem hiding this comment.
We can move some things to the utils directories.
| // biome-ignore lint/correctness/useExhaustiveDependencies: refreshKey triggers recalculation on refresh | ||
| const timeRange = useMemo(() => { | ||
| const now = new Date(); | ||
| const startTime = new Date(now.getTime() - TIME_RANGE_MS[selectedTimeRange]); | ||
|
|
||
| return { | ||
| start: startTime, | ||
| end: now, | ||
| }; | ||
| }, [selectedTimeRange, refreshKey]); |
There was a problem hiding this comment.
do we still need useExhaustiveDependencies?
| icon: ActivityIcon, | ||
| }, | ||
| beforeLoad: () => { | ||
| const isObservabilityEnabled = isServerless() |
There was a problem hiding this comment.
In addition to this we also need to make sure that this is actually configured in the backend I'd say - specifically thinking of self-hosted community users and customers here. Not sure if we want to disable/hide the sidebar or show a setup / onboarding page in this case.
| * by the Apache License, Version 2.0 | ||
| */ | ||
|
|
||
| import { Box, Flex, Text } from '@redpanda-data/ui'; |
There was a problem hiding this comment.
Please use Redpanda UI registry instead of @redpanda-data/ui for this new observability page.
| tickFormatter={(value) => { | ||
| // Format large numbers with K, M, B suffixes | ||
| if (value >= 1_000_000_000) { | ||
| return `${(value / 1_000_000_000).toFixed(1)}B`; | ||
| } | ||
| if (value >= 1_000_000) { | ||
| return `${(value / 1_000_000).toFixed(1)}M`; | ||
| } | ||
| if (value >= 1000) { | ||
| return `${(value / 1000).toFixed(1)}K`; | ||
| } | ||
| // Show decimals for small values | ||
| if (value < 10) { | ||
| return value.toFixed(2); | ||
| } | ||
| if (value < 100) { | ||
| return value.toFixed(1); | ||
| } | ||
| return value.toFixed(0); | ||
| }} | ||
| tickLine={false} |
There was a problem hiding this comment.
I think we should filter using storage utils
| */ | ||
|
|
||
| import { timestampFromMs } from '@bufbuild/protobuf/wkt'; | ||
| import { Alert, AlertIcon, Box, Heading, Skeleton, Text } from '@redpanda-data/ui'; |
There was a problem hiding this comment.
blocker: use redpanda UI registry
|
I did a first pass to remove the old components and fixing stuff. About the self-hosted mode, currently the sidebar is only shown for embedded mode only. Don't know if there's a clean way to make this work for self-hosted as well |
fdd8c39 to
ca4d5a3
Compare
|
@claude review |
|
Claude finished @malinskibeniamin's task in 2m 36s —— View job Code ReviewI've reviewed the observability page implementation focusing on simplicity and frontend best practices. Here's my comprehensive feedback: SummaryOverall, the implementation is well-structured with good test coverage and proper TypeScript typing. However, there are several important issues to address, particularly regarding code consistency with existing patterns and some potential bugs. Critical Issues (Must Fix)1. Biome Linting ViolationsThe github-actions bot has flagged multiple formatting issues that should be addressed. These are primarily spacing/formatting issues in:
2. Inconsistent Import Paths
import { prettyNumber } from 'utils/utils';Should be relative like other imports in the file: import { prettyNumber } from '../../../utils/utils';This is inconsistent with the other imports in the same file which use relative paths like 3.
|
c826332 to
67a1902
Compare
| tickFormatter={(value) => { | ||
| // Use prettyNumber for large values (handles K, M, B formatting) | ||
| if (value >= 1000) { | ||
| return prettyNumber(value).toUpperCase(); | ||
| } | ||
| // Show decimals for small values | ||
| if (value < 10) { | ||
| return value.toFixed(2); | ||
| } | ||
| if (value < 100) { | ||
| return value.toFixed(1); | ||
| } | ||
| return value.toFixed(0); | ||
| }} |
There was a problem hiding this comment.
let's use storage utils to get proper formatting for these units
| icon: ActivityIcon, | ||
| visibilityCheck: routeVisibility( | ||
| () => | ||
| isEmbedded() && |
There was a problem hiding this comment.
This should be gated by isAdpEnabled() too, right? Or will we have observability in self-hosted too 1 day, somehow?
There was a problem hiding this comment.
Technically it's possible to provide it in self-hosted, by configuring a local prom server. There's an internal discussion about it. For the moment, I think this condition only enables it in embedded mode with a specific feature flag.
There was a problem hiding this comment.
I don't see why this should be gated by isAdpEnabled(). This change is completely unrelated. Current condition looks fine to me, even though I'd personally rather do the backend check to see if the API is supported rather than relying on the feature flags that much.
| return useQuery(listQueries, listQueriesRequest, { | ||
| ...opts, | ||
| retry: fastFailRetry, | ||
| }); |
There was a problem hiding this comment.
Do we want to poll this?
There was a problem hiding this comment.
I did not wire auto-polling since the page where charts are used has an auto-refresh button, that also moves the clock forward.
Polling without applying a time shift does nothing (the API uses an absolute time range).
There was a problem hiding this comment.
can we rely on work from @weeco for transcripts? and use the same approach for the time ranges
a1ae30a to
3d3f765
Compare
|
Done another pass, I hope I got what you meant :) |
3d3f765 to
271f920
Compare
|
@claude Review this and check if the feedback from reviewers has been applied or if someone was missing (in case it was reasonable feedback). |
|
Claude finished @weeco's task in 2m 38s —— View job Code Review: Observability Page ImplementationI've reviewed the PR to check if previous reviewer feedback has been properly addressed. Here's my comprehensive analysis: SummaryThe author has done an excellent job addressing most of the previous review feedback. The implementation now follows best practices with proper use of the Redpanda UI registry, shared time-range utilities with transcripts, and well-structured unit formatting. However, there are a few remaining concerns that should be addressed. ✅ Feedback Successfully Addressed1. Use Redpanda UI Registry ✅Status: RESOLVED All components now correctly use the Redpanda UI registry pattern:
2. Follow Transcripts/Traces UI Approach ✅Status: RESOLVED The implementation now follows the same time-range pattern used in transcripts:
3. Unit Formatting ✅Status: RESOLVED Proper unit formatting is now implemented:
4. Code Organization ✅Status: RESOLVED Code has been properly organized into utilities:
5. UseExhaustiveDependencies Pattern ✅Status: ACCEPTABLE The
However, this is now acceptable because:
|
| Reviewer | Feedback | Status |
|---|---|---|
| @malinskibeniamin | Use recharts v3 | ✅ Acknowledged as follow-up |
| @malinskibeniamin | Required for standalone mode? | ✅ Addressed with feature flag check |
| @malinskibeniamin | Use Redpanda UI registry | ✅ RESOLVED |
| @malinskibeniamin | Filter using storage utils | ❓ Unclear - no filtering implemented yet |
| @malinskibeniamin | useExhaustiveDependencies | ✅ Acceptable pattern |
| @malinskibeniamin | Use similar approach to transcripts | ✅ RESOLVED - shared time-range utils |
| @malinskibeniamin | Use storage utils for unit formatting | ✅ RESOLVED - custom unit.ts created |
| @malinskibeniamin | Gate by isAdpEnabled() | |
| @malinskibeniamin | Polling? | ✅ Intentionally not implemented |
| @weeco | Backend configuration check | |
| @weeco | Similar approach to transcripts | ✅ RESOLVED |
| Previous Claude review | All linting issues | ✅ Assumed resolved |
| Previous Claude review | Import path consistency | ✅ RESOLVED |
| Previous Claude review | Code duplication | ✅ RESOLVED |
🎯 Recommendations
Must Fix Before Merge:
⚠️ AddisAdpEnabled()check to route visibility inroute-utils.tsx:200
Should Consider:
2. Add backend capability check or onboarding page for unsupported backends (can be follow-up)
Nice to Have (Follow-up PRs):
3. Upgrade to recharts v3
4. Add tests for refresh and time-range change functionality
5. Consider making timezone configurable (currently hardcoded to UTC)
✨ Conclusion
This PR shows significant improvement from the previous review. The author has successfully addressed the majority of reviewer feedback, particularly around:
- Using Redpanda UI registry consistently
- Sharing time-range utilities with transcripts
- Implementing proper unit formatting
- Code organization and structure
The implementation is well-structured, tested, and follows React best practices. The main outstanding issue is the missing isAdpEnabled() check for route visibility, which should be added for consistency with other ADP features.
Overall: Excellent work addressing previous feedback! Just needs the isAdpEnabled() check added, and this will be ready to merge.
When the feature flag is toggled, console starts showing this and cloud-ui stops showing the old one (different ff for Serverless and Serverful).
This is a first iteration, it allows to select the time range (but only from now back to 6 hours). I need to publish the max lookback time in the API to have a better control bar.