From 792532310a2934d055a5ce1ad5c0edf0431a11f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=84=B6?= Date: Thu, 26 Jun 2025 16:38:23 +0800 Subject: [PATCH] fix: Problem with no results when calling the query_range API using VictoriaMetrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 王然 --- server/internal/service/monitor.go | 32 ++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/server/internal/service/monitor.go b/server/internal/service/monitor.go index 0911c3b..d54fd2c 100644 --- a/server/internal/service/monitor.go +++ b/server/internal/service/monitor.go @@ -2,13 +2,15 @@ package service import ( "context" - "github.com/jinzhu/copier" - v1 "github.com/prometheus/client_golang/api/prometheus/v1" - "github.com/prometheus/common/model" + "math" "time" pb "vgpu/api/v1" "vgpu/internal/biz" "vgpu/internal/data/prom" + + "github.com/jinzhu/copier" + v1 "github.com/prometheus/client_golang/api/prometheus/v1" + "github.com/prometheus/common/model" ) type MonitorService struct { @@ -68,7 +70,7 @@ func fillLessSamplePoint(startTime, endTime time.Time, step time.Duration, value } var filledValues []*pb.SamplePair - currentTime := startTime + currentTime := getSamplePointStartTime(startTime, step, values) for !currentTime.After(endTime) { currentTimestamp := currentTime.UnixMilli() if value, exists := existingPoints[currentTimestamp]; exists { @@ -81,6 +83,28 @@ func fillLessSamplePoint(startTime, endTime time.Time, step time.Duration, value return filledValues } +// Compatible with both Prometheus and VictoriaMetrics +func getSamplePointStartTime(startTime time.Time, step time.Duration, values []*pb.SamplePair) time.Time { + if len(values) == 0 { + return startTime + } + startTimeMilli := startTime.UnixMilli() + firstValue := values[0] + // Case: Prometheus + if firstValue.Timestamp == startTimeMilli { + return startTime + } + // Case: VictoriaMetrics + stepMilli := step.Milliseconds() + // exists startTime data point + if math.Abs(float64(firstValue.Timestamp-startTimeMilli)) <= float64(stepMilli) { + return time.UnixMilli(firstValue.Timestamp) + } + // data points within the query time range + stepCount := (firstValue.Timestamp - startTimeMilli) / stepMilli + return time.UnixMilli(firstValue.Timestamp - stepCount*stepMilli) +} + func (s *MonitorService) QueryInstant(ctx context.Context, req *pb.QueryInstantRequest) (*pb.InstantResponse, error) { value, err := s.promClient.Query(ctx, req.GetQuery()) if err != nil {