mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-18 20:40:54 +02:00
* telemetry: total disk usage over time counted each cluster on one day GetMetrics aggregated s.instances, which holds only each cluster's most recent report. Every cluster therefore landed in a single date bucket -- the day it last reported on -- so the chart plotted the disk usage of clusters that went silent that day, and piled the whole live fleet onto today. Aggregate the daily histories instead, reusing the day alignment that the per-cluster size series already does. * telemetry: don't pad the charts with days the server has no history for The dashboard asks for 30 days, but daily history only starts when a server first collects it, so the charts opened on a run of zeros and then jumped -- reading as a fleet that appeared overnight. Start the window at the oldest sample on hand when it is younger than the requested range.
78 lines
2.4 KiB
Go
78 lines
2.4 KiB
Go
package storage
|
|
|
|
import (
|
|
"sort"
|
|
"time"
|
|
)
|
|
|
|
// ClusterSeries is one cluster's daily disk usage, aligned to the shared date
|
|
// axis of the enclosing ClusterSizeSeries.
|
|
type ClusterSeries struct {
|
|
ClusterId string `json:"cluster_id"`
|
|
Disk []uint64 `json:"disk"`
|
|
}
|
|
|
|
// OtherSeries is the clusters beyond the caller's limit, summed per day so a
|
|
// stacked chart still adds up to the fleet total.
|
|
type OtherSeries struct {
|
|
Count int `json:"count"`
|
|
Disk []uint64 `json:"disk"`
|
|
}
|
|
|
|
// ClusterSizeSeries is per-cluster disk usage over time: one value per cluster
|
|
// per day, largest cluster first, ranked by their most recent day.
|
|
type ClusterSizeSeries struct {
|
|
Dates []string `json:"dates"`
|
|
Clusters []ClusterSeries `json:"clusters"`
|
|
Other *OtherSeries `json:"other,omitempty"`
|
|
ClusterCount int `json:"cluster_count"`
|
|
TotalDisk uint64 `json:"total_disk"` // across all clusters on the last day
|
|
}
|
|
|
|
// GetClusterSizeSeries returns the last `days` days of per-cluster disk usage.
|
|
// Clusters beyond `limit` are folded into Other.
|
|
func (s *PrometheusStorage) GetClusterSizeSeries(days, limit int) ClusterSizeSeries {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
axis := newDailySeries(days, s.histories)
|
|
activeSince := time.Now().UTC().AddDate(0, 0, -activeDays).Unix()
|
|
last := len(axis.dates) - 1
|
|
series := ClusterSizeSeries{Dates: axis.dates}
|
|
|
|
for id, history := range s.histories {
|
|
disk, ok := axis.align(history, activeSince, diskBytes)
|
|
if !ok {
|
|
continue
|
|
}
|
|
series.Clusters = append(series.Clusters, ClusterSeries{ClusterId: id, Disk: disk})
|
|
series.TotalDisk += disk[last]
|
|
}
|
|
series.ClusterCount = len(series.Clusters)
|
|
|
|
// Rank by the latest day so the stack reads largest-first at its right
|
|
// edge, tie-breaking on id to keep the order stable across refreshes.
|
|
sort.Slice(series.Clusters, func(i, j int) bool {
|
|
a, b := series.Clusters[i], series.Clusters[j]
|
|
if a.Disk[last] != b.Disk[last] {
|
|
return a.Disk[last] > b.Disk[last]
|
|
}
|
|
return a.ClusterId < b.ClusterId
|
|
})
|
|
|
|
if limit > 0 && len(series.Clusters) > limit {
|
|
other := OtherSeries{
|
|
Count: len(series.Clusters) - limit,
|
|
Disk: make([]uint64, len(axis.dates)),
|
|
}
|
|
for _, c := range series.Clusters[limit:] {
|
|
for i, v := range c.Disk {
|
|
other.Disk[i] += v
|
|
}
|
|
}
|
|
series.Clusters = series.Clusters[:limit]
|
|
series.Other = &other
|
|
}
|
|
return series
|
|
}
|