Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dashboard #266

Merged
merged 14 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
5.6.1 (Jan 29, 2024)
- Fixed Data Inspector view.
- Updated docker images for vulnerability fixes.
- Updated dependencies for vulnerability fixes.

5.6.0 (Jan 23, 2024)
- Replaced redis KEYS operation in favor of SCAN.
- Added FlagSets stats into Split dashboard.
Expand Down
4 changes: 2 additions & 2 deletions docker/Dockerfile.proxy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build stage
FROM golang:1.21.5-alpine3.19 AS builder
FROM golang:1.21.6-alpine3.19 AS builder

ARG EXTRA_BUILD_ARGS

Expand All @@ -16,7 +16,7 @@ COPY . .
RUN make clean split-proxy entrypoints EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS}"

# Runner stage
FROM alpine:3.19.0 AS runner
FROM alpine:3.19.1 AS runner

RUN apk add bash

Expand Down
4 changes: 2 additions & 2 deletions docker/Dockerfile.synchronizer
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build stage
FROM golang:1.21.5-alpine3.19 AS builder
FROM golang:1.21.6-alpine3.19 AS builder

ARG EXTRA_BUILD_ARGS

Expand All @@ -16,7 +16,7 @@ COPY . .
RUN make clean split-sync entrypoints EXTRA_BUILD_ARGS="${EXTRA_BUILD_ARGS}"

# Runner stage
FROM alpine:3.19.0 AS runner
FROM alpine:3.19.1 AS runner

RUN apk add bash

Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/gin-gonic/gin v1.9.1
github.com/google/uuid v1.3.0
github.com/splitio/gincache v1.0.1
github.com/splitio/go-split-commons/v5 v5.2.0
github.com/splitio/go-split-commons/v5 v5.2.1
github.com/splitio/go-toolkit/v5 v5.4.0
github.com/stretchr/testify v1.8.4
go.etcd.io/bbolt v1.3.6
Expand Down Expand Up @@ -42,11 +42,11 @@ require (
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
16 changes: 10 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,12 @@ github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUA
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/splitio/gincache v1.0.1 h1:dLYdANY/BqH4KcUMCe/LluLyV5WtuE/LEdQWRE06IXU=
github.com/splitio/gincache v1.0.1/go.mod h1:CcgJDSM9Af75kyBH0724v55URVwMBuSj5x1eCWIOECY=
github.com/splitio/go-split-commons/v5 v5.1.1 h1:lLOqNQMdZA5Z7FBBh4YODWdE2QFgxSPMptX9ty14x4c=
github.com/splitio/go-split-commons/v5 v5.1.1/go.mod h1:9vAZrlhKvhensyRC11hyVFdgLIBrkX9D5vdYc9qB13w=
github.com/splitio/go-split-commons/v5 v5.2.0 h1:1P66JdUV1Fj1DUeWU1rwkeObqinl9AecRxDsktBsx0g=
github.com/splitio/go-split-commons/v5 v5.2.0/go.mod h1:m1Od/jxiSUJXpdbRvRxTaKeSAdQVem5AZr7AjI4xXn8=
github.com/splitio/go-split-commons/v5 v5.2.1 h1:h8Up3Jk6NFkHSYCj4Sr15uuoxQwFqPr3gn0G4vghM/8=
github.com/splitio/go-split-commons/v5 v5.2.1/go.mod h1:344KP05ULARzjRfnC4VtGSyu5l3kmIM375WUIzrURs0=
github.com/splitio/go-toolkit/v5 v5.4.0 h1:g5WFpRhQomnXCmvfsNOWV4s5AuUrWIZ+amM68G8NBKM=
github.com/splitio/go-toolkit/v5 v5.4.0/go.mod h1:xYhUvV1gga9/1029Wbp5pjnR6Cy8nvBpjw99wAbsMko=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down Expand Up @@ -122,8 +126,8 @@ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUu
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
Expand All @@ -138,13 +142,13 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
Expand Down
Binary file removed main
Binary file not shown.
4 changes: 4 additions & 0 deletions splitio/admin/controllers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ func bundleSplitInfo(splitStorage storage.SplitStorageConsumer) []dashboard.Spli
treatmentsS = append(treatmentsS, t)
}

if split.Sets == nil {
split.Sets = make([]string, 0)
}

summaries = append(summaries, dashboard.SplitSummary{
Name: split.Name,
Active: split.Status == "ACTIVE",
Expand Down
1 change: 1 addition & 0 deletions splitio/admin/controllers/observability.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func (c *ProxyObservabilityController) observability(ctx *gin.Context) {
ctx.JSON(200, gin.H{
"activeSplits": c.splits.SplitNames(),
"activeSegments": c.segments.NamesAndCount(),
"activeFlagSets": c.splits.GetAllFlagSetNames(),
"proxyEndpointStats": c.telemetry.TimeslicedReport(),
"proxyEndpointStatsTotal": c.telemetry.TotalMetricsReport(),
})
Expand Down
98 changes: 97 additions & 1 deletion splitio/admin/controllers/observability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/splitio/go-toolkit/v5/logging"
adminCommon "github.com/splitio/split-synchronizer/v5/splitio/admin/common"
"github.com/splitio/split-synchronizer/v5/splitio/provisional/observability"
"github.com/splitio/split-synchronizer/v5/splitio/proxy/storage"
)

func TestSyncObservabilityEndpoint(t *testing.T) {
Expand Down Expand Up @@ -79,7 +80,7 @@ func TestSyncObservabilityEndpoint(t *testing.T) {
router.ServeHTTP(resp, ctx.Request)

if resp.Code != 200 {
t.Error("hay crap.")
t.Errorf("Something went wrong. Status Code %v", resp.Code)
}

body, err := io.ReadAll(resp.Body)
Expand Down Expand Up @@ -129,3 +130,98 @@ func (e *extMockSegmentStorage) UpdateWithSummary(name string, toAdd *set.Thread
func (e *extMockSegmentStorage) Size(name string) (int, error) {
return e.SizeCall(name)
}

func TestProxyObservabilityEndpoint(t *testing.T) {
logger := logging.NewLogger(nil)
extSplitStorage := &extMockSplitStorage{
&mocks.MockSplitStorage{
SplitNamesCall: func() []string {
return []string{"split1", "split2", "split3"}
},
SegmentNamesCall: func() *set.ThreadUnsafeSet {
return set.NewSet("segment1")
},
GetAllFlagSetNamesCall: func() []string {
return []string{"fSet1", "fSet2"}
},
},
nil,
}

extSegmentStorage := &extMockSegmentStorage{
MockSegmentStorage: &mocks.MockSegmentStorage{},
SizeCall: func(name string) (int, error) {
switch name {
case "segment1":
return 10, nil
case "segment2":
return 20, nil
}
return 0, nil
},
}

oSplitStorage, err := observability.NewObservableSplitStorage(extSplitStorage, logger)
if err != nil {
t.Error(err)
return
}

oSegmentStorage, err := observability.NewObservableSegmentStorage(logger, extSplitStorage, extSegmentStorage)
if err != nil {
t.Error(err)
return
}

localTelemetryStorage := storage.NewTimeslicedProxyEndpointTelemetry(
storage.NewProxyTelemetryFacade(),
50,
5,
)

storages := adminCommon.Storages{
SplitStorage: oSplitStorage,
SegmentStorage: oSegmentStorage,
LocalTelemetryStorage: localTelemetryStorage,
}

ctrl, err := NewObservabilityController(true, logger, storages)
if err != nil {
t.Error(err)
return
}

resp := httptest.NewRecorder()
ctx, router := gin.CreateTestContext(resp)
ctrl.Register(router)

ctx.Request, _ = http.NewRequest(http.MethodGet, "/observability", nil)
router.ServeHTTP(resp, ctx.Request)

if resp.Code != 200 {
t.Errorf("Something went wrong. Status Code %v", resp.Code)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
t.Error(err)
return
}

var result ObservabilityDto
if err := json.Unmarshal(body, &result); err != nil {
t.Error("there should be no error ", err)
}

if len(result.ActiveFlagSets) != 2 {
t.Errorf("Active flag sets should be 2. Actual %d", len(result.ActiveFlagSets))
}

if len(result.ActiveSplits) != 3 {
t.Errorf("Active splits should be 3. Actual %d", len(result.ActiveSplits))
}

if len(result.ActiveSegments) != 1 {
t.Errorf("Active segments should be 1. Actual %d", len(result.ActiveSegments))
}
}
10 changes: 3 additions & 7 deletions splitio/admin/views/dashboard/datainspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,9 @@ const dataInspector = `
<table id="flag_sets_rows" class="table table-condensed table-hover">
<thead>
<tr>
{{if .ProxyMode}}
<th>&nbsp;</th>
{{else}}
<th>Flag Set</th>
<th>Total Feature Flags Associated</th>
<th>Feature Flags</th>
{{end}}
<th>Flag Set</th>
<th>Total Feature Flags Associated</th>
<th>Feature Flags</th>
</tr>
</thead>
<tbody>
Expand Down
10 changes: 8 additions & 2 deletions splitio/admin/views/dashboard/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,24 @@ const cards = `

<div class="row">
{{if .ProxyMode}}
<div class="col-md-6">
<div class="col-md-4">
<div class="gray2Box metricBox">
<h4>Cached Feature Flags</h4>
<h1 id="feature_flags_number" class="centerText"></h1>
</div>
</div>
<div class="col-md-6">
<div class="col-md-4">
<div class="gray2Box metricBox">
<h4>Cached Segments</h4>
<h1 id="segments_number" class="centerText"></h1>
</div>
</div>
<div class="col-md-4">
<div class="gray2Box metricBox">
<h4>Cached Flag Sets</h4>
<h1 id="flag_sets_number" class="centerText"></h1>
</div>
</div>
{{else}}
<div class="col-md-2">
<div class="gray1Box metricBox">
Expand Down
2 changes: 1 addition & 1 deletion splitio/producer/initialization.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func Start(logger logging.LoggerInterface, cfg *conf.Main) error {
flagSetsFilter := flagsets.NewFlagSetFilter(cfg.FlagSetsFilter)

// These storages are forwarded to the dashboard, the sdk-telemetry is irrelevant there
splitStorage, err := observability.NewObservableSplitStorage(redis.NewSplitStorage(redisClient, logger, flagSetsFilter, int64(redisOptions.ScanCount)), logger)
splitStorage, err := observability.NewObservableSplitStorage(redis.NewSplitStorage(redisClient, logger, flagSetsFilter), logger)
if err != nil {
return fmt.Errorf("error instantiating observable feature flag storage: %w", err)
}
Expand Down
2 changes: 0 additions & 2 deletions splitio/producer/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
const (
impressionsCountPeriodTaskInMemory = 1800 // 30 min
impressionObserverSize = 500
ScanCount = 10
)

func parseTLSConfig(opt *conf.Redis) (*tls.Config, error) {
Expand Down Expand Up @@ -100,7 +99,6 @@ func parseRedisOptions(cfg *conf.Redis) (*config.RedisConfig, error) {
WriteTimeout: cfg.WriteTimeout,
PoolSize: cfg.PoolSize,
TLSConfig: tlsCfg,
ScanCount: ScanCount,
}

if cfg.SentinelReplication {
Expand Down
12 changes: 4 additions & 8 deletions splitio/proxy/storage/splits.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,13 @@ func (p *ProxySplitStorageImpl) Count() int {
}

// GetNamesByFlagSets implements storage.SplitStorage
func (*ProxySplitStorageImpl) GetNamesByFlagSets(sets []string) map[string][]string {
// NOTE: This method is NOT used by the proxy.
// we need to revisit our interfaces so that we're not obliged to do this smeely empty impls.
return nil
func (p *ProxySplitStorageImpl) GetNamesByFlagSets(sets []string) map[string][]string {
return p.snapshot.GetNamesByFlagSets(sets)
}

// GetAllFlagSetNames implements storage.SplitStorage
func (*ProxySplitStorageImpl) GetAllFlagSetNames() []string {
// NOTE: This method is NOT used by the proxy.
// we need to revisit our interfaces so that we're not obliged to do this smeely empty impls.
return nil
func (p *ProxySplitStorageImpl) GetAllFlagSetNames() []string {
return p.snapshot.GetAllFlagSetNames()
}

func (p *ProxySplitStorageImpl) setStartingPoint(cn int64) {
Expand Down
Loading
Loading