-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[feat] support fe/be metrics system table #54221
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: master
Are you sure you want to change the base?
[feat] support fe/be metrics system table #54221
Conversation
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
run buildall |
Cloud UT Coverage ReportIncrement line coverage Increment coverage report
|
|
run buildall |
Cloud UT Coverage ReportIncrement line coverage Increment coverage report
|
|
run buildall |
Cloud UT Coverage ReportIncrement line coverage Increment coverage report
|
TPC-H: Total hot run time: 33714 ms |
TPC-DS: Total hot run time: 160081 ms |
ClickBench: Total hot run time: 34.91 s |
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
|
run buildall |
Cloud UT Coverage ReportIncrement line coverage Increment coverage report
|
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
875d6d5 to
1cfbc7d
Compare
|
run buildall |
Cloud UT Coverage ReportIncrement line coverage Increment coverage report
|
FE UT Coverage ReportIncrement line coverage |
TPC-H: Total hot run time: 33853 ms |
TPC-DS: Total hot run time: 171123 ms |
ClickBench: Total hot run time: 34.89 s |
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
1b4f560 to
2b2e7a1
Compare
|
run buildall |
Cloud UT Coverage ReportIncrement line coverage Increment coverage report
|
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
|
run buildall |
Cloud UT Coverage ReportIncrement line coverage Increment coverage report
|
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
2b2e7a1 to
45774dd
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.
Pull request overview
This PR adds frontend (FE) and backend (BE) metrics system tables to the information_schema database, enabling SQL-based querying of metrics data from both FE and BE nodes.
Key changes:
- Added new Thrift RPC interface
fetchFrontendMetricsfor retrieving FE metrics - Implemented
ListMetricVisitorto convert metrics into list format for system table consumption - Created schema scanners for both
backend_metricsandfrontend_metricstables
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
| gensrc/thrift/FrontendService.thrift | Adds Thrift request/response structures and RPC method for fetching FE metrics |
| gensrc/thrift/Descriptors.thrift | Adds enum values for BE and FE metrics schema table types |
| fe/fe-core/src/main/java/org/apache/doris/metric/ListMetricVisitor.java | New visitor implementation that converts metrics to list format with JSON-like tags |
| fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java | Implements RPC endpoint to fetch FE metrics using ListMetricVisitor |
| fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java | Defines schema for backend_metrics and frontend_metrics tables |
| fe/fe-core/src/main/java/org/apache/doris/analysis/SchemaTableType.java | Adds enum entries for the new metrics schema tables |
| fe/fe-core/src/main/java/org/apache/doris/planner/BackendPartitionedSchemaScanNode.java | Registers backend_metrics as a backend-partitioned table |
| fe/fe-core/src/test/java/org/apache/doris/metric/MetricsTest.java | Adds test for ListMetricVisitor and updates existing tests to use update() instead of increase() |
| be/src/util/metrics.h | Declares new method to populate metrics into a Block for system table |
| be/src/util/metrics.cpp | Implements metrics extraction and conversion to Block format with JSON tags |
| be/src/exec/schema_scanner/schema_helper.h | Declares helper method for fetching FE metrics via Thrift RPC |
| be/src/exec/schema_scanner/schema_helper.cpp | Implements Thrift RPC call to fetch FE metrics |
| be/src/exec/schema_scanner/schema_frontend_metrics_scanner.h | Header for FE metrics schema scanner |
| be/src/exec/schema_scanner/schema_frontend_metrics_scanner.cpp | Implements scanner that fetches and returns FE metrics from all FE nodes |
| be/src/exec/schema_scanner/schema_backend_metrics_scanner.h | Header for BE metrics schema scanner |
| be/src/exec/schema_scanner/schema_backend_metrics_scanner.cpp | Implements scanner that returns local BE metrics |
| be/src/exec/schema_scanner.cpp | Registers the new BE and FE metrics scanners in the factory |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fe/fe-core/src/main/java/org/apache/doris/metric/ListMetricVisitor.java
Outdated
Show resolved
Hide resolved
| threads.getCount(), "\"type\"=\"count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getPeakCount(), "\"type\"=\"peak_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsNewCount(), "\"type\"=\"new_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsRunnableCount(), "\"type\"=\"runnable_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsBlockedCount(), "\"type\"=\"blocked_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsWaitingCount(), "\"type\"=\"waiting_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsTimedWaitingCount(), "\"type\"=\"timed_waiting_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsTerminatedCount(), "\"type\"=\"terminated_count\"}")); |
Copilot
AI
Dec 29, 2025
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.
Missing opening brace in the tag string. The tag should be "{"type"="count"}" but it's currently ""type"="count"}", which is missing the opening brace. This inconsistency with other tag strings in this file will cause malformed JSON-like tags.
| threads.getCount(), "\"type\"=\"count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getPeakCount(), "\"type\"=\"peak_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsNewCount(), "\"type\"=\"new_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsRunnableCount(), "\"type\"=\"runnable_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsBlockedCount(), "\"type\"=\"blocked_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsWaitingCount(), "\"type\"=\"waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTimedWaitingCount(), "\"type\"=\"timed_waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTerminatedCount(), "\"type\"=\"terminated_count\"}")); | |
| threads.getCount(), "{\"type\"=\"count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getPeakCount(), "{\"type\"=\"peak_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsNewCount(), "{\"type\"=\"new_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsRunnableCount(), "{\"type\"=\"runnable_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsBlockedCount(), "{\"type\"=\"blocked_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsWaitingCount(), "{\"type\"=\"waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTimedWaitingCount(), "{\"type\"=\"timed_waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTerminatedCount(), "{\"type\"=\"terminated_count\"}")); |
| threads.getCount(), "\"type\"=\"count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getPeakCount(), "\"type\"=\"peak_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsNewCount(), "\"type\"=\"new_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsRunnableCount(), "\"type\"=\"runnable_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsBlockedCount(), "\"type\"=\"blocked_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsWaitingCount(), "\"type\"=\"waiting_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsTimedWaitingCount(), "\"type\"=\"timed_waiting_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsTerminatedCount(), "\"type\"=\"terminated_count\"}")); |
Copilot
AI
Dec 29, 2025
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.
Missing opening brace in the tag string. The tag should be "{"type"="peak_count"}" but it's currently ""type"="peak_count"}", which is missing the opening brace. This inconsistency with other tag strings in this file will cause malformed JSON-like tags.
| threads.getCount(), "\"type\"=\"count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getPeakCount(), "\"type\"=\"peak_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsNewCount(), "\"type\"=\"new_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsRunnableCount(), "\"type\"=\"runnable_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsBlockedCount(), "\"type\"=\"blocked_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsWaitingCount(), "\"type\"=\"waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTimedWaitingCount(), "\"type\"=\"timed_waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTerminatedCount(), "\"type\"=\"terminated_count\"}")); | |
| threads.getCount(), "{\"type\"=\"count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getPeakCount(), "{\"type\"=\"peak_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsNewCount(), "{\"type\"=\"new_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsRunnableCount(), "{\"type\"=\"runnable_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsBlockedCount(), "{\"type\"=\"blocked_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsWaitingCount(), "{\"type\"=\"waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTimedWaitingCount(), "{\"type\"=\"timed_waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTerminatedCount(), "{\"type\"=\"terminated_count\"}")); |
| threads.getCount(), "\"type\"=\"count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getPeakCount(), "\"type\"=\"peak_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsNewCount(), "\"type\"=\"new_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsRunnableCount(), "\"type\"=\"runnable_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsBlockedCount(), "\"type\"=\"blocked_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsWaitingCount(), "\"type\"=\"waiting_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsTimedWaitingCount(), "\"type\"=\"timed_waiting_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsTerminatedCount(), "\"type\"=\"terminated_count\"}")); |
Copilot
AI
Dec 29, 2025
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.
Missing opening brace in the tag string. The tag should be "{"type"="new_count"}" but it's currently ""type"="new_count"}", which is missing the opening brace. This inconsistency with other tag strings in this file will cause malformed JSON-like tags.
| threads.getCount(), "\"type\"=\"count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getPeakCount(), "\"type\"=\"peak_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsNewCount(), "\"type\"=\"new_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsRunnableCount(), "\"type\"=\"runnable_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsBlockedCount(), "\"type\"=\"blocked_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsWaitingCount(), "\"type\"=\"waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTimedWaitingCount(), "\"type\"=\"timed_waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTerminatedCount(), "\"type\"=\"terminated_count\"}")); | |
| threads.getCount(), "{\"type\"=\"count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getPeakCount(), "{\"type\"=\"peak_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsNewCount(), "{\"type\"=\"new_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsRunnableCount(), "{\"type\"=\"runnable_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsBlockedCount(), "{\"type\"=\"blocked_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsWaitingCount(), "{\"type\"=\"waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTimedWaitingCount(), "{\"type\"=\"timed_waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTerminatedCount(), "{\"type\"=\"terminated_count\"}")); |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsNewCount(), "\"type\"=\"new_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsRunnableCount(), "\"type\"=\"runnable_count\"}")); |
Copilot
AI
Dec 29, 2025
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.
Missing opening brace in the tag string. The tag should be "{"type"="runnable_count"}" but it's currently ""type"="runnable_count"}", which is missing the opening brace. This inconsistency with other tag strings in this file will cause malformed JSON-like tags.
| threads.getCount(), "\"type\"=\"count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getPeakCount(), "\"type\"=\"peak_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsNewCount(), "\"type\"=\"new_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsRunnableCount(), "\"type\"=\"runnable_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsBlockedCount(), "\"type\"=\"blocked_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsWaitingCount(), "\"type\"=\"waiting_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsTimedWaitingCount(), "\"type\"=\"timed_waiting_count\"}")); | ||
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | ||
| threads.getThreadsTerminatedCount(), "\"type\"=\"terminated_count\"}")); |
Copilot
AI
Dec 29, 2025
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.
Missing opening brace in the tag string. The tag should be "{"type"="blocked_count"}" but it's currently ""type"="blocked_count"}", which is missing the opening brace. This inconsistency with other tag strings in this file will cause malformed JSON-like tags.
| threads.getCount(), "\"type\"=\"count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getPeakCount(), "\"type\"=\"peak_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsNewCount(), "\"type\"=\"new_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsRunnableCount(), "\"type\"=\"runnable_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsBlockedCount(), "\"type\"=\"blocked_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsWaitingCount(), "\"type\"=\"waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTimedWaitingCount(), "\"type\"=\"timed_waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTerminatedCount(), "\"type\"=\"terminated_count\"}")); | |
| threads.getCount(), "{\"type\"=\"count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getPeakCount(), "{\"type\"=\"peak_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsNewCount(), "{\"type\"=\"new_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsRunnableCount(), "{\"type\"=\"runnable_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsBlockedCount(), "{\"type\"=\"blocked_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsWaitingCount(), "{\"type\"=\"waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTimedWaitingCount(), "{\"type\"=\"timed_waiting_count\"}")); | |
| this.metricsList.add(newGaugeSubList(JVM_THREAD, | |
| threads.getThreadsTerminatedCount(), "{\"type\"=\"terminated_count\"}")); |
| this.metricsList.add(newHistogramSubList(fullName + "_count", | ||
| histogram.getCount(), "{\"quantile\"=\"0.75\"" + delimiter + fullTag + "}")); |
Copilot
AI
Dec 29, 2025
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.
The tag used for the "_count" metric should not include the "quantile" label, as count is not associated with a quantile. Additionally, using "{"quantile"="0.75"" is misleading since this represents the total count, not the 75th percentile. Consider removing the quantile label entirely or using an empty tag set for the count metric.
…itor.java Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
6cb6e30 to
8a957dd
Compare
|
run buildall |
What problem does this PR solve?
Issue Number: close #xxx
Related PR: #xxx
Problem Summary:
add fe/be metrics system table in db
information_schemaRelease note
None
Check List (For Author)
Test
Behavior changed:
Does this need documentation?
Check List (For Reviewer who merge this PR)