Skip to content

Commit

Permalink
Merge pull request #266 from splitio/fix-dashboard
Browse files Browse the repository at this point in the history
Fix dashboard
  • Loading branch information
sanzmauro authored Jan 30, 2024
2 parents 3f5718f + dcdd9de commit c2750bd
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 36 deletions.
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

0 comments on commit c2750bd

Please sign in to comment.