已合并
merge_client_metrics #417
merge_client_metrics #417
已合并
wangyibing创建于 7月29日
7 个文件变更+191-166
@@ -82,7 +82,7 @@
82 },82 },
83 "targets": [83 "targets": [
84 {84 {
85- "expr": "memcache_client_bandwidth_latency_seconds{rank=~\"$rank\", operation=\"get\", quantile=~\"$quantile\"}",85+ "expr": "memcache_bandwidth_latency_seconds{rank=~\"$rank\", operation=\"get\", quantile=~\"$quantile\"}",
86 "legendFormat": "{{rank}} @ {{quantile}}",86 "legendFormat": "{{rank}} @ {{quantile}}",
87 "refId": "A"87 "refId": "A"
88 }88 }
@@ -119,7 +119,7 @@
119 },119 },
120 "targets": [120 "targets": [
121 {121 {
122- "expr": "memcache_client_bandwidth_latency_seconds{rank=~\"$rank\", operation=\"put\", quantile=~\"$quantile\"}",122+ "expr": "memcache_bandwidth_latency_seconds{rank=~\"$rank\", operation=\"put\", quantile=~\"$quantile\"}",
123 "legendFormat": "{{rank}} @ {{quantile}}",123 "legendFormat": "{{rank}} @ {{quantile}}",
124 "refId": "A"124 "refId": "A"
125 }125 }
@@ -156,7 +156,7 @@
156 },156 },
157 "targets": [157 "targets": [
158 {158 {
159- "expr": "memcache_client_bandwidth_bytes{rank=~\"$rank\", operation=\"get\"}",159+ "expr": "memcache_bandwidth_bytes{rank=~\"$rank\", operation=\"get\"}",
160 "legendFormat": "{{rank}}",160 "legendFormat": "{{rank}}",
161 "refId": "A"161 "refId": "A"
162 }162 }
@@ -193,7 +193,7 @@
193 },193 },
194 "targets": [194 "targets": [
195 {195 {
196- "expr": "memcache_client_bandwidth_bytes{rank=~\"$rank\", operation=\"put\"}",196+ "expr": "memcache_bandwidth_bytes{rank=~\"$rank\", operation=\"put\"}",
197 "legendFormat": "{{rank}}",197 "legendFormat": "{{rank}}",
198 "refId": "A"198 "refId": "A"
199 }199 }
@@ -230,7 +230,7 @@
230 },230 },
231 "targets": [231 "targets": [
232 {232 {
233- "expr": "memcache_client_bandwidth_bytes_per_sec{rank=~\"$rank\", operation=\"get\"}",233+ "expr": "memcache_bandwidth_bytes_per_sec{rank=~\"$rank\", operation=\"get\"}",
234 "legendFormat": "{{rank}}",234 "legendFormat": "{{rank}}",
235 "refId": "A"235 "refId": "A"
236 }236 }
@@ -267,7 +267,7 @@
267 },267 },
268 "targets": [268 "targets": [
269 {269 {
270- "expr": "memcache_client_bandwidth_bytes_per_sec{rank=~\"$rank\", operation=\"put\"}",270+ "expr": "memcache_bandwidth_bytes_per_sec{rank=~\"$rank\", operation=\"put\"}",
271 "legendFormat": "{{rank}}",271 "legendFormat": "{{rank}}",
272 "refId": "A"272 "refId": "A"
273 }273 }
@@ -317,7 +317,7 @@
317 },317 },
318 "targets": [318 "targets": [
319 {319 {
320- "expr": "memcache_client_bandwidth_duration_ms_cum_total{rank=~\"$rank\"} / 1000",320+ "expr": "memcache_bandwidth_duration_ms_cum_total{rank=~\"$rank\"} / 1000",
321 "legendFormat": "{{rank}} @ {{operation}}",321 "legendFormat": "{{rank}} @ {{operation}}",
322 "refId": "A"322 "refId": "A"
323 }323 }
@@ -354,7 +354,7 @@
354 },354 },
355 "targets": [355 "targets": [
356 {356 {
357- "expr": "memcache_client_bandwidth_bytes_cum_total{rank=~\"$rank\"}",357+ "expr": "memcache_bandwidth_bytes_cum_total{rank=~\"$rank\"}",
358 "legendFormat": "{{rank}} @ {{operation}}",358 "legendFormat": "{{rank}} @ {{operation}}",
359 "refId": "A"359 "refId": "A"
360 }360 }
@@ -391,7 +391,7 @@
391 },391 },
392 "targets": [392 "targets": [
393 {393 {
394- "expr": "memcache_client_bandwidth_bytes_cum_total{rank=~\"$rank\"} / (memcache_client_bandwidth_duration_ms_cum_total{rank=~\"$rank\"} / 1000)",394+ "expr": "memcache_bandwidth_bytes_cum_total{rank=~\"$rank\"} / (memcache_bandwidth_duration_ms_cum_total{rank=~\"$rank\"} / 1000)",
395 "legendFormat": "{{rank}} @ {{operation}}",395 "legendFormat": "{{rank}} @ {{operation}}",
396 "refId": "A"396 "refId": "A"
397 }397 }
@@ -442,12 +442,12 @@
442 },442 },
443 "targets": [443 "targets": [
444 {444 {
445- "expr": "memcache_client_ubs_io_disk_capacity_bytes{rank=~\"$rank\"}",445+ "expr": "memcache_ubs_io_disk_capacity_bytes{rank=~\"$rank\"}",
446 "legendFormat": "{{rank}} @ capacity",446 "legendFormat": "{{rank}} @ capacity",
447 "refId": "A"447 "refId": "A"
448 },448 },
449 {449 {
450- "expr": "memcache_client_ubs_io_disk_used_bytes{rank=~\"$rank\"}",450+ "expr": "memcache_ubs_io_disk_used_bytes{rank=~\"$rank\"}",
451 "legendFormat": "{{rank}} @ used",451 "legendFormat": "{{rank}} @ used",
452 "refId": "B"452 "refId": "B"
453 }453 }
@@ -484,12 +484,12 @@
484 },484 },
485 "targets": [485 "targets": [
486 {486 {
487- "expr": "memcache_client_ubs_io_mem_capacity_bytes{rank=~\"$rank\"}",487+ "expr": "memcache_ubs_io_mem_capacity_bytes{rank=~\"$rank\"}",
488 "legendFormat": "{{rank}} @ capacity",488 "legendFormat": "{{rank}} @ capacity",
489 "refId": "A"489 "refId": "A"
490 },490 },
491 {491 {
492- "expr": "memcache_client_ubs_io_mem_used_bytes{rank=~\"$rank\"}",492+ "expr": "memcache_ubs_io_mem_used_bytes{rank=~\"$rank\"}",
493 "legendFormat": "{{rank}} @ used",493 "legendFormat": "{{rank}} @ used",
494 "refId": "B"494 "refId": "B"
495 }495 }
@@ -526,7 +526,7 @@
526 },526 },
527 "targets": [527 "targets": [
528 {528 {
529- "expr": "memcache_client_ubs_io_disk_read_bandwidth_bytes_per_sec{rank=~\"$rank\", disk_path=~\"$disk_path\"}",529+ "expr": "memcache_ubs_io_disk_read_bandwidth_bytes_per_sec{rank=~\"$rank\", disk_path=~\"$disk_path\"}",
530 "legendFormat": "{{rank}} @ {{disk_path}}",530 "legendFormat": "{{rank}} @ {{disk_path}}",
531 "refId": "A"531 "refId": "A"
532 }532 }
@@ -563,7 +563,7 @@
563 },563 },
564 "targets": [564 "targets": [
565 {565 {
566- "expr": "memcache_client_ubs_io_disk_write_bandwidth_bytes_per_sec{rank=~\"$rank\", disk_path=~\"$disk_path\"}",566+ "expr": "memcache_ubs_io_disk_write_bandwidth_bytes_per_sec{rank=~\"$rank\", disk_path=~\"$disk_path\"}",
567 "legendFormat": "{{rank}} @ {{disk_path}}",567 "legendFormat": "{{rank}} @ {{disk_path}}",
568 "refId": "A"568 "refId": "A"
569 }569 }
@@ -600,7 +600,7 @@
600 },600 },
601 "targets": [601 "targets": [
602 {602 {
603- "expr": "memcache_client_ubs_io_disk_total_bandwidth_bytes_per_sec{rank=~\"$rank\", disk_path=~\"$disk_path\"}",603+ "expr": "memcache_ubs_io_disk_total_bandwidth_bytes_per_sec{rank=~\"$rank\", disk_path=~\"$disk_path\"}",
604 "legendFormat": "{{rank}} @ {{disk_path}}",604 "legendFormat": "{{rank}} @ {{disk_path}}",
605 "refId": "A"605 "refId": "A"
606 }606 }
@@ -637,12 +637,12 @@
637 },637 },
638 "targets": [638 "targets": [
639 {639 {
640- "expr": "memcache_client_ubs_io_disk_num{rank=~\"$rank\"}",640+ "expr": "memcache_ubs_io_disk_num{rank=~\"$rank\"}",
641 "legendFormat": "{{rank}} @ total",641 "legendFormat": "{{rank}} @ total",
642 "refId": "A"642 "refId": "A"
643 },643 },
644 {644 {
645- "expr": "memcache_client_ubs_io_fault_disk_num{rank=~\"$rank\"}",645+ "expr": "memcache_ubs_io_fault_disk_num{rank=~\"$rank\"}",
646 "legendFormat": "{{rank}} @ fault",646 "legendFormat": "{{rank}} @ fault",
647 "refId": "B"647 "refId": "B"
648 }648 }
@@ -683,7 +683,7 @@
683 "type": "prometheus",683 "type": "prometheus",
684 "uid": "${datasource}"684 "uid": "${datasource}"
685 },685 },
686- "definition": "label_values(memcache_client_bandwidth_bytes_cum_total, rank)",686+ "definition": "label_values(memcache_bandwidth_bytes_cum_total, rank)",
687 "hide": 0,687 "hide": 0,
688 "includeAll": true,688 "includeAll": true,
689 "label": "Rank",689 "label": "Rank",
@@ -691,7 +691,7 @@
691 "name": "rank",691 "name": "rank",
692 "options": [],692 "options": [],
693 "query": {693 "query": {
694- "query": "label_values(memcache_client_bandwidth_bytes_cum_total, rank)",694+ "query": "label_values(memcache_bandwidth_bytes_cum_total, rank)",
695 "refId": "StandardVariableQuery"695 "refId": "StandardVariableQuery"
696 },696 },
697 "refresh": 2,697 "refresh": 2,
@@ -710,7 +710,7 @@
710 "type": "prometheus",710 "type": "prometheus",
711 "uid": "${datasource}"711 "uid": "${datasource}"
712 },712 },
713- "definition": "label_values(memcache_client_bandwidth_latency_seconds, quantile)",713+ "definition": "label_values(memcache_bandwidth_latency_seconds, quantile)",
714 "hide": 0,714 "hide": 0,
715 "includeAll": true,715 "includeAll": true,
716 "label": "Quantile",716 "label": "Quantile",
@@ -718,7 +718,7 @@
718 "name": "quantile",718 "name": "quantile",
719 "options": [],719 "options": [],
720 "query": {720 "query": {
721- "query": "label_values(memcache_client_bandwidth_latency_seconds, quantile)",721+ "query": "label_values(memcache_bandwidth_latency_seconds, quantile)",
722 "refId": "StandardVariableQuery"722 "refId": "StandardVariableQuery"
723 },723 },
724 "refresh": 2,724 "refresh": 2,
@@ -737,7 +737,7 @@
737 "type": "prometheus",737 "type": "prometheus",
738 "uid": "${datasource}"738 "uid": "${datasource}"
739 },739 },
740- "definition": "label_values(memcache_client_ubs_io_disk_read_bandwidth_bytes_per_sec, disk_path)",740+ "definition": "label_values(memcache_ubs_io_disk_read_bandwidth_bytes_per_sec, disk_path)",
741 "hide": 0,741 "hide": 0,
742 "includeAll": true,742 "includeAll": true,
743 "label": "Disk Path",743 "label": "Disk Path",
@@ -745,7 +745,7 @@
745 "name": "disk_path",745 "name": "disk_path",
746 "options": [],746 "options": [],
747 "query": {747 "query": {
748- "query": "label_values(memcache_client_ubs_io_disk_read_bandwidth_bytes_per_sec, disk_path)",748+ "query": "label_values(memcache_ubs_io_disk_read_bandwidth_bytes_per_sec, disk_path)",
749 "refId": "StandardVariableQuery"749 "refId": "StandardVariableQuery"
750 },750 },
751 "refresh": 2,751 "refresh": 2,
@@ -21,7 +21,7 @@ namespace mmc {
21void UbsIoCollector::Collect(ClientMetricSnapshot &out) const21void UbsIoCollector::Collect(ClientMetricSnapshot &out) const
22{22{
23 auto proxy = MmcUbsIoProxyFactory::GetInstance("ubsIoProxyDefault");23 auto proxy = MmcUbsIoProxyFactory::GetInstance("ubsIoProxyDefault");
24- if (proxy == nullptr) {24+ if (proxy == nullptr || !proxy->IsReady()) {
25 return;25 return;
26 }26 }
27 27 
@@ -478,20 +478,6 @@ void MmcHttpServer::RegisterMetricsEndpoint()
478 };478 };
479 server_->RegisterHttpHandler(acc::AccHttpMethod::GET, "/api/v1/analysis/alloc_free_latency",479 server_->RegisterHttpHandler(acc::AccHttpMethod::GET, "/api/v1/analysis/alloc_free_latency",
480 allocFreeLatencyHandler);480 allocFreeLatencyHandler);
481- 
482- // Client metrics (Prometheus text format, separated from /metrics)
483- auto clientMetricsHandler = [this](acc::AccHttpRequestContext &ctx) -> int32_t {
484- if (restApiFacade_ == nullptr) {
485- return ReplyJsonError200(ctx, kErrorInternalServer);
486- }
487- std::string result;
488- const Result ret = restApiFacade_->BuildClientMetricsPrometheus(result);
489- if (ret != MMC_OK) {
490- return ReplyJsonError200(ctx, kErrorInternalServer);
491- }
492- return ReplyTextOk(ctx, result);
493- };
494- server_->RegisterHttpHandler(acc::AccHttpMethod::GET, "/metrics/client", clientMetricsHandler);
495}481}
496 482 
497bool MmcHttpServer::Start()483bool MmcHttpServer::Start()
@@ -108,61 +108,156 @@ void AppendOperationMetrics(std::ostringstream &oss, const std::string &metricNa
108 }108 }
109}109}
110 110 
111-void AppendBandwidthPrometheus(std::ostringstream &oss, const std::string &rank, const std::string &operation,111+void AppendClientStale(std::ostringstream &oss, const std::vector<ock::mmc::RankMetricView> &allViews,
112- const ock::mmc::BandwidthMetricData &data)112+ std::vector<ock::mmc::RankMetricView> &freshViews)
113{113{
114- // 窗口值 (gauge)114+ AppendMetricHeader(oss, "memcache_metric_stale", "Client metric stale status (1 = stale, 0 = fresh)", "gauge");
115- oss << "memcache_client_bandwidth_bytes{rank=\"" << rank << "\",operation=\"" << operation << "\"} "115+ for (const auto &view : allViews) {
116- << data.totalBytes << '\n';116+ if (view.rank == UINT32_MAX) {
117- oss << "memcache_client_bandwidth_duration_ms{rank=\"" << rank << "\",operation=\"" << operation << "\"} "117+ continue;
118- << data.totalDurationMs << '\n';118+ }
119- 119+ oss << "memcache_metric_stale{rank=\"" << view.rank << "\"} " << (view.stale ? 1 : 0) << '\n';
120- // 累计值 (counter)120+ }
121- oss << "memcache_client_bandwidth_bytes_cum_total{rank=\"" << rank << "\",operation=\"" << operation << "\"} "121+ for (const auto &view : allViews) {
122- << data.cumTotalBytes << '\n';122+ if (view.rank != UINT32_MAX && !view.stale) {
123- oss << "memcache_client_bandwidth_duration_ms_cum_total{rank=\"" << rank << "\",operation=\"" << operation << "\"} "123+ freshViews.push_back(view);
124- << data.cumTotalDurationMs << '\n';124+ }
125- 125+ }
126- oss << "memcache_client_bandwidth_latency_seconds{rank=\"" << rank << "\",operation=\"" << operation
127- << "\",quantile=\"P50\"} " << data.latencyP50 << '\n';
128- oss << "memcache_client_bandwidth_latency_seconds{rank=\"" << rank << "\",operation=\"" << operation
129- << "\",quantile=\"P90\"} " << data.latencyP90 << '\n';
130- oss << "memcache_client_bandwidth_latency_seconds{rank=\"" << rank << "\",operation=\"" << operation
131- << "\",quantile=\"P99\"} " << data.latencyP99 << '\n';
132- oss << "memcache_client_bandwidth_latency_seconds{rank=\"" << rank << "\",operation=\"" << operation
133- << "\",quantile=\"Avg\"} " << data.latencyAve << '\n';
134- 
135- oss << "memcache_client_bandwidth_bytes_per_sec{rank=\"" << rank << "\",operation=\"" << operation << "\"} "
136- << data.bytesPerSec << '\n';
137}126}
138 127 
139-void AppendUbsIoPrometheus(std::ostringstream &oss, const std::string &rank, const ock::mmc::UbsIoMetricData &data)128+void AppendBandwidthWindowGauges(std::ostringstream &oss, const std::vector<ock::mmc::RankMetricView> &freshViews)
140{129{
141- // WriteCache 容量/使用量130+ AppendMetricHeader(oss, "memcache_bandwidth_bytes", "Client bandwidth window bytes transferred", "gauge");
142- oss << "memcache_client_ubs_io_disk_capacity_bytes{rank=\"" << rank << "\"} " << data.diskCap << '\n';131+ for (const auto &view : freshViews) {
143- oss << "memcache_client_ubs_io_disk_used_bytes{rank=\"" << rank << "\"} " << data.diskUsed << '\n';132+ const std::string r = std::to_string(view.rank);
144- oss << "memcache_client_ubs_io_mem_capacity_bytes{rank=\"" << rank << "\"} " << data.memCap << '\n';133+ for (size_t opIdx = 0; opIdx < static_cast<size_t>(ock::mmc::MetricOp::COUNT); ++opIdx) {
145- oss << "memcache_client_ubs_io_mem_used_bytes{rank=\"" << rank << "\"} " << data.memUsed << '\n';134+ oss << "memcache_bandwidth_bytes{rank=\"" << r << "\",operation=\"" << ock::mmc::K_METRIC_OP_LABEL[opIdx]
146- 135+ << "\"} " << view.bandwidths[opIdx].totalBytes << '\n';
147- // 盘健康136+ }
148- oss << "memcache_client_ubs_io_disk_num{rank=\"" << rank << "\"} " << data.diskNum << '\n';
149- oss << "memcache_client_ubs_io_fault_disk_num{rank=\"" << rank << "\"} " << data.faultDiskNum << '\n';
150- 
151- // 每盘指标
152- uint32_t diskCount =
153- (data.perDiskCount < UBSIO_RESOURCE_MAX_DISK_NUM) ? data.perDiskCount : UBSIO_RESOURCE_MAX_DISK_NUM;
154- for (uint32_t i = 0; i < diskCount; ++i) {
155- const auto &disk = data.perDisk[i];
156- const std::string diskLabel(disk.path, strnlen(disk.path, sizeof(disk.path)));
157- oss << "memcache_client_ubs_io_disk_status{rank=\"" << rank << "\",disk_path=\"" << diskLabel << "\"} "
158- << disk.status << '\n';
159- oss << "memcache_client_ubs_io_disk_read_bandwidth_bytes_per_sec{rank=\"" << rank << "\",disk_path=\""
160- << diskLabel << "\"} " << disk.readBandwidth << '\n';
161- oss << "memcache_client_ubs_io_disk_write_bandwidth_bytes_per_sec{rank=\"" << rank << "\",disk_path=\""
162- << diskLabel << "\"} " << disk.writeBandwidth << '\n';
163- oss << "memcache_client_ubs_io_disk_total_bandwidth_bytes_per_sec{rank=\"" << rank << "\",disk_path=\""
164- << diskLabel << "\"} " << disk.totalBandwidth << '\n';
165 }137 }
138+ 
139+ AppendMetricHeader(oss, "memcache_bandwidth_duration_ms", "Client bandwidth window duration in milliseconds",
140+ "gauge");
141+ for (const auto &view : freshViews) {
142+ const std::string r = std::to_string(view.rank);
143+ for (size_t opIdx = 0; opIdx < static_cast<size_t>(ock::mmc::MetricOp::COUNT); ++opIdx) {
144+ oss << "memcache_bandwidth_duration_ms{rank=\"" << r << "\",operation=\""
145+ << ock::mmc::K_METRIC_OP_LABEL[opIdx] << "\"} " << view.bandwidths[opIdx].totalDurationMs << '\n';
146+ }
147+ }
148+}
149+ 
150+void AppendBandwidthCumulativeCounters(std::ostringstream &oss, const std::vector<ock::mmc::RankMetricView> &freshViews)
151+{
152+ AppendMetricHeader(oss, "memcache_bandwidth_bytes_cum_total", "Client bandwidth cumulative bytes transferred",
153+ "counter");
154+ for (const auto &view : freshViews) {
155+ const std::string r = std::to_string(view.rank);
156+ for (size_t opIdx = 0; opIdx < static_cast<size_t>(ock::mmc::MetricOp::COUNT); ++opIdx) {
157+ oss << "memcache_bandwidth_bytes_cum_total{rank=\"" << r << "\",operation=\""
158+ << ock::mmc::K_METRIC_OP_LABEL[opIdx] << "\"} " << view.bandwidths[opIdx].cumTotalBytes << '\n';
159+ }
160+ }
161+ 
162+ AppendMetricHeader(oss, "memcache_bandwidth_duration_ms_cum_total",
163+ "Client bandwidth cumulative duration in milliseconds", "counter");
164+ for (const auto &view : freshViews) {
165+ const std::string r = std::to_string(view.rank);
166+ for (size_t opIdx = 0; opIdx < static_cast<size_t>(ock::mmc::MetricOp::COUNT); ++opIdx) {
167+ oss << "memcache_bandwidth_duration_ms_cum_total{rank=\"" << r << "\",operation=\""
168+ << ock::mmc::K_METRIC_OP_LABEL[opIdx] << "\"} " << view.bandwidths[opIdx].cumTotalDurationMs << '\n';
169+ }
170+ }
171+}
172+ 
173+void AppendBandwidthLatency(std::ostringstream &oss, const std::vector<ock::mmc::RankMetricView> &freshViews)
174+{
175+ AppendMetricHeader(oss, "memcache_bandwidth_latency_seconds", "Client bandwidth operation latency in seconds",
176+ "gauge");
177+ for (const auto &view : freshViews) {
178+ const std::string r = std::to_string(view.rank);
179+ for (size_t opIdx = 0; opIdx < static_cast<size_t>(ock::mmc::MetricOp::COUNT); ++opIdx) {
180+ const auto &bw = view.bandwidths[opIdx];
181+ const char *op = ock::mmc::K_METRIC_OP_LABEL[opIdx];
182+ oss << "memcache_bandwidth_latency_seconds{rank=\"" << r << "\",operation=\"" << op
183+ << "\",quantile=\"P50\"} " << bw.latencyP50 << '\n';
184+ oss << "memcache_bandwidth_latency_seconds{rank=\"" << r << "\",operation=\"" << op
185+ << "\",quantile=\"P90\"} " << bw.latencyP90 << '\n';
186+ oss << "memcache_bandwidth_latency_seconds{rank=\"" << r << "\",operation=\"" << op
187+ << "\",quantile=\"P99\"} " << bw.latencyP99 << '\n';
188+ oss << "memcache_bandwidth_latency_seconds{rank=\"" << r << "\",operation=\"" << op
189+ << "\",quantile=\"Avg\"} " << bw.latencyAve << '\n';
190+ }
191+ }
192+}
193+ 
194+void AppendBandwidthBytesPerSec(std::ostringstream &oss, const std::vector<ock::mmc::RankMetricView> &freshViews)
195+{
196+ AppendMetricHeader(oss, "memcache_bandwidth_bytes_per_sec", "Client bandwidth instantaneous bytes per second",
197+ "gauge");
198+ for (const auto &view : freshViews) {
199+ const std::string r = std::to_string(view.rank);
200+ for (size_t opIdx = 0; opIdx < static_cast<size_t>(ock::mmc::MetricOp::COUNT); ++opIdx) {
201+ oss << "memcache_bandwidth_bytes_per_sec{rank=\"" << r << "\",operation=\""
202+ << ock::mmc::K_METRIC_OP_LABEL[opIdx] << "\"} " << view.bandwidths[opIdx].bytesPerSec << '\n';
203+ }
204+ }
205+}
206+ 
207+void AppendUbsIoAggregate(std::ostringstream &oss, const std::vector<ock::mmc::RankMetricView> &freshViews)
208+{
209+ AppendMetricHeader(oss, "memcache_ubs_io_disk_capacity_bytes", "Client UBS IO SSD total capacity in bytes",
210+ "gauge");
211+ for (const auto &view : freshViews) {
212+ oss << "memcache_ubs_io_disk_capacity_bytes{rank=\"" << view.rank << "\"} " << view.ubsIo.diskCap << '\n';
213+ }
214+ AppendMetricHeader(oss, "memcache_ubs_io_disk_used_bytes", "Client UBS IO SSD used bytes", "gauge");
215+ for (const auto &view : freshViews) {
216+ oss << "memcache_ubs_io_disk_used_bytes{rank=\"" << view.rank << "\"} " << view.ubsIo.diskUsed << '\n';
217+ }
218+ AppendMetricHeader(oss, "memcache_ubs_io_mem_capacity_bytes", "Client UBS IO memory total capacity in bytes",
219+ "gauge");
220+ for (const auto &view : freshViews) {
221+ oss << "memcache_ubs_io_mem_capacity_bytes{rank=\"" << view.rank << "\"} " << view.ubsIo.memCap << '\n';
222+ }
223+ AppendMetricHeader(oss, "memcache_ubs_io_mem_used_bytes", "Client UBS IO memory used bytes", "gauge");
224+ for (const auto &view : freshViews) {
225+ oss << "memcache_ubs_io_mem_used_bytes{rank=\"" << view.rank << "\"} " << view.ubsIo.memUsed << '\n';
226+ }
227+ AppendMetricHeader(oss, "memcache_ubs_io_disk_num", "Client UBS IO total disk count", "gauge");
228+ for (const auto &view : freshViews) {
229+ oss << "memcache_ubs_io_disk_num{rank=\"" << view.rank << "\"} " << view.ubsIo.diskNum << '\n';
230+ }
231+ AppendMetricHeader(oss, "memcache_ubs_io_fault_disk_num", "Client UBS IO fault disk count", "gauge");
232+ for (const auto &view : freshViews) {
233+ oss << "memcache_ubs_io_fault_disk_num{rank=\"" << view.rank << "\"} " << view.ubsIo.faultDiskNum << '\n';
234+ }
235+}
236+ 
237+void AppendUbsIoPerDisk(std::ostringstream &oss, const std::vector<ock::mmc::RankMetricView> &freshViews)
238+{
239+ auto out = [&oss, &freshViews](const char *metric, const char *help,
240+ uint64_t (*v)(const ock::mmc::UbsIoPerDiskMetric &)) {
241+ AppendMetricHeader(oss, metric, help, "gauge");
242+ for (const auto &view : freshViews) {
243+ const std::string r = std::to_string(view.rank);
244+ uint32_t n = (view.ubsIo.perDiskCount < UBSIO_RESOURCE_MAX_DISK_NUM) ? view.ubsIo.perDiskCount
245+ : UBSIO_RESOURCE_MAX_DISK_NUM;
246+ for (uint32_t i = 0; i < n; ++i) {
247+ const auto &d = view.ubsIo.perDisk[i];
248+ const std::string p(d.path, strnlen(d.path, sizeof(d.path)));
249+ oss << metric << "{rank=\"" << r << "\",disk_path=\"" << p << "\"} " << v(d) << '\n';
250+ }
251+ }
252+ };
253+ out("memcache_ubs_io_disk_status", "Client UBS IO per-disk status (0=normal, non-zero=fault)",
254+ [](const auto &d) -> uint64_t { return d.status; });
255+ out("memcache_ubs_io_disk_read_bandwidth_bytes_per_sec", "Client UBS IO per-disk read bandwidth",
256+ [](const auto &d) -> uint64_t { return d.readBandwidth; });
257+ out("memcache_ubs_io_disk_write_bandwidth_bytes_per_sec", "Client UBS IO per-disk write bandwidth",
258+ [](const auto &d) -> uint64_t { return d.writeBandwidth; });
259+ out("memcache_ubs_io_disk_total_bandwidth_bytes_per_sec", "Client UBS IO per-disk total bandwidth",
260+ [](const auto &d) -> uint64_t { return d.totalBandwidth; });
166}261}
167 262 
168} // namespace263} // namespace
@@ -769,31 +864,6 @@ Result MmcRestApiFacade::BuildPrometheusMetrics(bool serviceReady, std::string &
769 AppendMetricHeader(oss, "memcache_stored_keys", "Current number of stored keys", "gauge");864 AppendMetricHeader(oss, "memcache_stored_keys", "Current number of stored keys", "gauge");
770 AppendMetricValue(oss, "memcache_stored_keys", keys.size());865 AppendMetricValue(oss, "memcache_stored_keys", keys.size());
771 866 
772- AppendMetricHeader(oss, "memcache_segment_capacity_bytes", "Segment total capacity in bytes", "gauge");
773- for (size_t i = 0; i < segments.size(); ++i) {
774- AppendLabeledMetricValue(oss, "memcache_segment_capacity_bytes", "segment", segments[i].segmentName,
775- segments[i].totalBytes);
776- }
777- AppendMetricHeader(oss, "memcache_segment_allocated_bytes", "Segment allocated bytes", "gauge");
778- for (size_t i = 0; i < segments.size(); ++i) {
779- AppendLabeledMetricValue(oss, "memcache_segment_allocated_bytes", "segment", segments[i].segmentName,
780- segments[i].usedBytes);
781- }
782- 
783- AppendMetricHeader(oss, "memcache_total_capacity_bytes", "Total capacity by medium in bytes", "gauge");
784- AppendLabeledMetricValue(oss, "memcache_total_capacity_bytes", "medium", kLowerMediumHbm, hbmUsage.totalBytes);
785- AppendLabeledMetricValue(oss, "memcache_total_capacity_bytes", "medium", kLowerMediumDram, dramUsage.totalBytes);
786- if (ssdUsage.totalBytes > 0 || ssdUsage.usedBytes > 0) {
787- AppendLabeledMetricValue(oss, "memcache_total_capacity_bytes", "medium", kLowerMediumSsd, ssdUsage.totalBytes);
788- }
789- 
790- AppendMetricHeader(oss, "memcache_allocated_bytes", "Allocated bytes by medium", "gauge");
791- AppendLabeledMetricValue(oss, "memcache_allocated_bytes", "medium", kLowerMediumHbm, hbmUsage.usedBytes);
792- AppendLabeledMetricValue(oss, "memcache_allocated_bytes", "medium", kLowerMediumDram, dramUsage.usedBytes);
793- if (ssdUsage.totalBytes > 0 || ssdUsage.usedBytes > 0) {
794- AppendLabeledMetricValue(oss, "memcache_allocated_bytes", "medium", kLowerMediumSsd, ssdUsage.usedBytes);
795- }
796- 
797 const kv_event::KvEventStats kvStats =867 const kv_event::KvEventStats kvStats =
798 metaService_ != nullptr ? metaService_->GetKvEventStats() : kv_event::KvEventStats{};868 metaService_ != nullptr ? metaService_->GetKvEventStats() : kv_event::KvEventStats{};
799 AppendMetricHeader(oss, "memcache_kv_events_published_total", "Total KV cache events published", "counter");869 AppendMetricHeader(oss, "memcache_kv_events_published_total", "Total KV cache events published", "counter");
@@ -837,66 +907,31 @@ Result MmcRestApiFacade::BuildPrometheusMetrics(bool serviceReady, std::string &
837 AppendMetricValue(oss, "memcache_kv_events_publisher_active", kvStats.publisherActive ? 1 : 0);907 AppendMetricValue(oss, "memcache_kv_events_publisher_active", kvStats.publisherActive ? 1 : 0);
838 AppendMetricHeader(oss, "memcache_kv_events_last_sequence", "Last published KV event ZMQ sequence", "gauge");908 AppendMetricHeader(oss, "memcache_kv_events_last_sequence", "Last published KV event ZMQ sequence", "gauge");
839 AppendMetricValue(oss, "memcache_kv_events_last_sequence", kvStats.lastSequence);909 AppendMetricValue(oss, "memcache_kv_events_last_sequence", kvStats.lastSequence);
910+ AppendClientMetrics(oss);
840 911 
841 result = oss.str();912 result = oss.str();
842 return MMC_OK;913 return MMC_OK;
843}914}
844 915 
845-Result MmcRestApiFacade::BuildClientMetricsPrometheus(std::string &result) const916+void MmcRestApiFacade::AppendClientMetrics(std::ostringstream &oss) const
846{917{
847- std::ostringstream oss;
848 const auto clientViews = MmcClientMetricStore::GetInstance().GetAll(CLIENT_METRIC_STALE_THRESHOLD_SECONDS);918 const auto clientViews = MmcClientMetricStore::GetInstance().GetAll(CLIENT_METRIC_STALE_THRESHOLD_SECONDS);
849- if (!clientViews.empty()) {919+ if (clientViews.empty()) {
850- // 窗口值 (gauge): 每 30s 重置920+ return;
851- AppendMetricHeader(oss, "memcache_client_bandwidth_bytes", "Client bandwidth window bytes transferred",
852- "gauge");
853- AppendMetricHeader(oss, "memcache_client_bandwidth_duration_ms",
854- "Client bandwidth window duration in milliseconds", "gauge");
855- // 累计值 (counter): 永不复位
856- AppendMetricHeader(oss, "memcache_client_bandwidth_bytes_cum_total",
857- "Client bandwidth cumulative bytes transferred", "counter");
858- AppendMetricHeader(oss, "memcache_client_bandwidth_duration_ms_cum_total",
859- "Client bandwidth cumulative duration in milliseconds", "counter");
860- AppendMetricHeader(oss, "memcache_client_bandwidth_latency_seconds",
861- "Client bandwidth operation latency in seconds", "gauge");
862- AppendMetricHeader(oss, "memcache_client_bandwidth_bytes_per_sec",
863- "Client bandwidth instantaneous bytes per second", "gauge");
864- AppendMetricHeader(oss, "memcache_client_metric_stale", "Client metric stale status (1 = stale, 0 = fresh)",
865- "gauge");
866- AppendMetricHeader(oss, "memcache_client_ubs_io_disk_capacity_bytes",
867- "Client UBS IO SSD total capacity in bytes", "gauge");
868- AppendMetricHeader(oss, "memcache_client_ubs_io_disk_used_bytes", "Client UBS IO SSD used bytes", "gauge");
869- AppendMetricHeader(oss, "memcache_client_ubs_io_mem_capacity_bytes",
870- "Client UBS IO memory total capacity in bytes", "gauge");
871- AppendMetricHeader(oss, "memcache_client_ubs_io_mem_used_bytes", "Client UBS IO memory used bytes", "gauge");
872- AppendMetricHeader(oss, "memcache_client_ubs_io_disk_num", "Client UBS IO total disk count", "gauge");
873- AppendMetricHeader(oss, "memcache_client_ubs_io_fault_disk_num", "Client UBS IO fault disk count", "gauge");
874- AppendMetricHeader(oss, "memcache_client_ubs_io_disk_status",
875- "Client UBS IO per-disk status (0=normal, non-zero=fault)", "gauge");
876- AppendMetricHeader(oss, "memcache_client_ubs_io_disk_read_bandwidth_bytes_per_sec",
877- "Client UBS IO per-disk read bandwidth", "gauge");
878- AppendMetricHeader(oss, "memcache_client_ubs_io_disk_write_bandwidth_bytes_per_sec",
879- "Client UBS IO per-disk write bandwidth", "gauge");
880- AppendMetricHeader(oss, "memcache_client_ubs_io_disk_total_bandwidth_bytes_per_sec",
881- "Client UBS IO per-disk total bandwidth", "gauge");
882 }921 }
883- for (const auto &view : clientViews) {
884- if (view.rank == UINT32_MAX) {
885- continue;
886- }
887- const std::string rankStr = std::to_string(view.rank);
888 922 
889- oss << "memcache_client_metric_stale{rank=\"" << rankStr << "\"} " << (view.stale ? 1 : 0) << '\n';923+ std::vector<RankMetricView> freshViews;
890- if (view.stale) {924+ AppendClientStale(oss, clientViews, freshViews);
891- continue; // 避免 Grafana 显示已退出 client 的旧数据925+ if (freshViews.empty()) {
892- }926+ return;
893- for (size_t opIdx = 0; opIdx < static_cast<size_t>(MetricOp::COUNT); ++opIdx) {
894- AppendBandwidthPrometheus(oss, rankStr, K_METRIC_OP_LABEL[opIdx], view.bandwidths[opIdx]);
895- }
896- AppendUbsIoPrometheus(oss, rankStr, view.ubsIo);
897 }927 }
898- result = oss.str();928+ 
899- return MMC_OK;929+ AppendBandwidthWindowGauges(oss, freshViews);
930+ AppendBandwidthCumulativeCounters(oss, freshViews);
931+ AppendBandwidthLatency(oss, freshViews);
932+ AppendBandwidthBytesPerSec(oss, freshViews);
933+ AppendUbsIoAggregate(oss, freshViews);
934+ AppendUbsIoPerDisk(oss, freshViews);
900}935}
901 936 
902nlohmann::json MmcRestApiFacade::BuildKvEventsStatus() const937nlohmann::json MmcRestApiFacade::BuildKvEventsStatus() const
@@ -14,6 +14,7 @@
14#define MMC_REST_API_FACADE_H14#define MMC_REST_API_FACADE_H
15 15 
16#include <functional>16#include <functional>
17+#include <sstream>
17#include <string>18#include <string>
18#include <vector>19#include <vector>
19 20 
@@ -85,7 +86,6 @@ public:
85 86 
86 Result BuildMetricsSummary(bool serviceReady, std::string &result) const;87 Result BuildMetricsSummary(bool serviceReady, std::string &result) const;
87 Result BuildPrometheusMetrics(bool serviceReady, std::string &result) const;88 Result BuildPrometheusMetrics(bool serviceReady, std::string &result) const;
88- Result BuildClientMetricsPrometheus(std::string &result) const;
89 89 
90 Result GetPtracerText(std::string &result) const;90 Result GetPtracerText(std::string &result) const;
91 Result GetAllocFreeLatencyText(std::string &result) const;91 Result GetAllocFreeLatencyText(std::string &result) const;
@@ -98,6 +98,7 @@ private:
98 static std::string BuildSegmentId(uint32_t rank, const std::string &medium);98 static std::string BuildSegmentId(uint32_t rank, const std::string &medium);
99 static std::string JoinLines(const std::vector<std::string> &items);99 static std::string JoinLines(const std::vector<std::string> &items);
100 static uint64_t CurrentTimestamp();100 static uint64_t CurrentTimestamp();
101+ void AppendClientMetrics(std::ostringstream &oss) const;
101 102 
102private:103private:
103 MmcMetaService *metaService_{nullptr};104 MmcMetaService *metaService_{nullptr};
@@ -175,7 +175,6 @@ public:
175 static inline Result UbsioGetResourceInfo(UbsioResourceInfo &info)175 static inline Result UbsioGetResourceInfo(UbsioResourceInfo &info)
176 {176 {
177 if (pUbsioGetResourceInfo == nullptr) {177 if (pUbsioGetResourceInfo == nullptr) {
178- MMC_LOG_WARN("UbsioGetResourceInfo not loaded");
179 return MMC_NOT_INITIALIZED;178 return MMC_NOT_INITIALIZED;
180 }179 }
181 return pUbsioGetResourceInfo(&info);180 return pUbsioGetResourceInfo(&info);
@@ -61,6 +61,10 @@ public:
61 metaEventCallback_ = std::move(callback);61 metaEventCallback_ = std::move(callback);
62 }62 }
63 63 
64+ bool IsReady() const
65+ {
66+ return started_;
67+ }
64 Result GetResourceInfo(UbsioResourceInfo &info) const;68 Result GetResourceInfo(UbsioResourceInfo &info) const;
65 Result RegisterMetaEventCallback();69 Result RegisterMetaEventCallback();
66 70