mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Metrics visualization: Show extrapolated rate for short-duration profiles.
All rate metrics currently show per-second rates, which cannot be computed before we have at least 1 second's worth of profile data. However, it's reasonable to want to run very short workloads (less than 1 second) and still want to see how those rates evolved over this duration. So this change computes an extrapolated per-second rate for the first second of execution. PiperOrigin-RevId: 648513094
This commit is contained in:
committed by
gVisor bot
parent
a5fbf8ba58
commit
bcc785fc78
@@ -221,9 +221,13 @@ func (c *chart) getXAxis() ([]string, error) {
|
||||
|
||||
// series returns a single line series of the chart.
|
||||
func (c *chart) series(ts *TimeSeries, isCumulative bool) ([]opts.LineData, error) {
|
||||
const windowDuration = time.Second
|
||||
const (
|
||||
windowDuration = time.Second
|
||||
minTimeToReport = 10 * time.Millisecond
|
||||
)
|
||||
seriesData := make([]opts.LineData, len(ts.Data))
|
||||
if isCumulative {
|
||||
timeSeriesIsLongEnough := false
|
||||
lastValidXIndex := 0
|
||||
for i, p := range ts.Data {
|
||||
baselineWhen := p.When.Add(-windowDuration)
|
||||
@@ -263,12 +267,30 @@ func (c *chart) series(ts *TimeSeries, isCumulative bool) ([]opts.LineData, erro
|
||||
baselineWhenFraction := float64(baselineWhen.Sub(whenBefore)) / float64(whenDelta)
|
||||
baseline := baselineBefore + uint64(float64(baselineDelta)*baselineWhenFraction)
|
||||
seriesData[i] = opts.LineData{Value: p.Value - baseline, YAxisIndex: 0, Symbol: "none"}
|
||||
timeSeriesIsLongEnough = true
|
||||
case p.When.Sub(ts.Data[0].When) >= minTimeToReport:
|
||||
// We don't yet have enough points to get a full `windowDuration`'s
|
||||
// worth of data, but we do have enough data to report something if
|
||||
// we assume that the rate can be extrapolated from the first point
|
||||
// until now.
|
||||
baselineBefore := ts.Data[0].Value
|
||||
baselineAfter := p.Value
|
||||
baselineDelta := baselineAfter - baselineBefore
|
||||
whenBefore := ts.Data[0].When
|
||||
whenAfter := p.When
|
||||
whenDelta := whenAfter.Sub(whenBefore)
|
||||
interpolationMultiplier := float64(windowDuration.Nanoseconds()) / float64(whenDelta.Nanoseconds())
|
||||
seriesData[i] = opts.LineData{Value: uint64(float64(baselineDelta) * interpolationMultiplier), YAxisIndex: 0, Symbol: "none"}
|
||||
timeSeriesIsLongEnough = true
|
||||
default:
|
||||
// Happens naturally for points too early in the timeseries,
|
||||
// set the point to nil.
|
||||
seriesData[i] = opts.LineData{Value: nil, YAxisIndex: 0, Symbol: "none"}
|
||||
}
|
||||
}
|
||||
if !timeSeriesIsLongEnough {
|
||||
return nil, fmt.Errorf("metric %v is cumulative but timeseries data for it is smaller than minimum chartable duration (%v), please run the workload for longer for cumulative timeseries to become meaningful", ts.Metric.Name, minTimeToReport)
|
||||
}
|
||||
} else {
|
||||
// Non-cumulative time series are more straightforward.
|
||||
for i, p := range ts.Data {
|
||||
|
||||
Reference in New Issue
Block a user