Compare commits

...

1 Commits

Author SHA1 Message Date
Naman Verma
4afbaccd91 fix: make span gaps accept day and week as units 2026-07-10 10:55:35 +05:30
3 changed files with 49 additions and 7 deletions

View File

@@ -38,7 +38,7 @@ func newTestDashboardV2(t *testing.T, orgID valuer.UUID, source Source) *Dashboa
LineInterpolation: LineInterpolationSpline,
LineStyle: LineStyleSolid,
FillMode: FillModeSolid,
SpanGaps: SpanGaps{FillLessThan: valuer.MustParseTextDuration("60s")},
SpanGaps: SpanGaps{FillLessThan: "60s"},
},
Legend: Legend{Position: LegendPositionBottom, Mode: LegendModeList},
},

View File

@@ -6,7 +6,6 @@ import (
"os"
"strings"
"testing"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/perses/spec/go/dashboard"
@@ -1371,7 +1370,7 @@ func TestSpanGaps(t *testing.T) {
t.Run("defaults", func(t *testing.T) {
var sg SpanGaps
assert.False(t, sg.FillOnlyBelow, "expected FillOnlyBelow default false")
assert.True(t, sg.FillLessThan.IsZero(), "expected FillLessThan default zero")
assert.Empty(t, sg.FillLessThan, "expected FillLessThan default empty")
})
t.Run("fillOnlyBelow true", func(t *testing.T) {
@@ -1382,12 +1381,27 @@ func TestSpanGaps(t *testing.T) {
t.Run("fillLessThan duration", func(t *testing.T) {
sg := unmarshal(t, `{"fillOnlyBelow": false, "fillLessThan": "5m"}`)
assert.False(t, sg.FillOnlyBelow)
assert.Equal(t, 5*time.Minute, sg.FillLessThan.Duration())
assert.Equal(t, "5m", sg.FillLessThan)
})
t.Run("fillLessThan compound duration", func(t *testing.T) {
sg := unmarshal(t, `{"fillLessThan": "1h30m"}`)
assert.Equal(t, 90*time.Minute, sg.FillLessThan.Duration())
assert.Equal(t, "1h30m", sg.FillLessThan)
})
t.Run("fillLessThan day duration", func(t *testing.T) {
sg := unmarshal(t, `{"fillLessThan": "1d"}`)
assert.Equal(t, "1d", sg.FillLessThan)
})
t.Run("invalid fillLessThan rejected on unmarshal", func(t *testing.T) {
var sg SpanGaps
require.Error(t, json.Unmarshal([]byte(`{"fillLessThan": "not-a-duration"}`), &sg))
})
t.Run("non-positive fillLessThan rejected on unmarshal", func(t *testing.T) {
var sg SpanGaps
require.Error(t, json.Unmarshal([]byte(`{"fillLessThan": "0s"}`), &sg))
})
}

View File

@@ -8,6 +8,7 @@ import (
qb "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/prometheus/common/model"
"github.com/swaggest/jsonschema-go"
)
@@ -621,8 +622,35 @@ func (fm *FillMode) UnmarshalJSON(data []byte) error {
}
type SpanGaps struct {
FillOnlyBelow bool `json:"fillOnlyBelow" description:"Controls whether lines connect across null values. When false (default), all gaps are connected. When true, only gaps smaller than fillLessThan are connected."`
FillLessThan valuer.TextDuration `json:"fillLessThan" description:"The maximum gap size to connect when fillOnlyBelow is true. Gaps larger than this duration are left disconnected."`
FillOnlyBelow bool `json:"fillOnlyBelow" description:"Controls whether lines connect across null values. When false (default), all gaps are connected. When true, only gaps smaller than fillLessThan are connected."`
FillLessThan string `json:"fillLessThan" description:"The maximum gap size to connect when fillOnlyBelow is true. Gaps larger than this duration are left disconnected."`
}
func (sg *SpanGaps) UnmarshalJSON(data []byte) error {
type alias SpanGaps
var tmp alias
if err := json.Unmarshal(data, &tmp); err != nil {
return errors.WrapInvalidInputf(err, ErrCodeDashboardInvalidInput, "invalid spanGaps")
}
*sg = SpanGaps(tmp)
return sg.validate()
}
// validate checks that FillLessThan, when set, is a valid positive duration.
// It uses prometheus's parser so day/week/year units (e.g. "1d") are accepted;
// time.ParseDuration caps at hours.
func (sg SpanGaps) validate() error {
if sg.FillLessThan == "" {
return nil
}
d, err := model.ParseDuration(sg.FillLessThan)
if err != nil {
return errors.WrapInvalidInputf(err, ErrCodeDashboardInvalidInput, "invalid spanGaps.fillLessThan duration %q", sg.FillLessThan)
}
if d <= 0 {
return errors.NewInvalidInputf(ErrCodeDashboardInvalidInput, "spanGaps.fillLessThan duration must be positive, got %q", sg.FillLessThan)
}
return nil
}
type PrecisionOption struct{ valuer.String }