Skip to content

Commit

Permalink
adding flagset info in proxy mode
Browse files Browse the repository at this point in the history
  • Loading branch information
sanzmauro committed Jan 29, 2024
1 parent 8958a26 commit 41ef641
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 18 deletions.
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
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
64 changes: 64 additions & 0 deletions splitio/proxy/storage/splits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,67 @@ func TestSplitStorageWithFlagsets(t *testing.T) {
{Name: "f2", ChangeNumber: 2, Status: "ACTIVE", Sets: []string{"s2", "s3"}},
}, res.Splits)
}

func TestGetNamesByFlagSets(t *testing.T) {
dbw, err := persistent.NewBoltWrapper(persistent.BoltInMemoryMode, nil)
if err != nil {
t.Error("error creating bolt wrapper: ", err)
}

logger := logging.NewLogger(nil)

splitC := persistent.NewSplitChangesCollection(dbw, logger)
flags := []dtos.SplitDTO{
{Name: "f0", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_1", "set2"}},
{Name: "f1", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_1"}},
{Name: "f2", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set2"}},
{Name: "f3", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_1", "set2"}},
{Name: "f4", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_1", "set6"}},
{Name: "f5", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_5", "set6"}},
}
splitC.Update(flags, nil, 0)

pss := NewProxySplitStorage(dbw, logger, flagsets.NewFlagSetFilter(nil), true)

namesBySets := pss.GetNamesByFlagSets([]string{"set_1", "set2"})

if len(namesBySets) != 2 {
t.Errorf("namesBySets len should be 3. Actual %v", len(namesBySets))
}

if len(namesBySets["set_1"]) != 4 {
t.Errorf("set_1 len should be 4. Actual %v", len(namesBySets["set_1"]))
}

if len(namesBySets["set2"]) != 3 {
t.Errorf("set2 len should be 3. Actual %v", len(namesBySets["set2"]))
}
}

func TestGetAllFlagSetNames(t *testing.T) {
dbw, err := persistent.NewBoltWrapper(persistent.BoltInMemoryMode, nil)
if err != nil {
t.Error("error creating bolt wrapper: ", err)
}

logger := logging.NewLogger(nil)

splitC := persistent.NewSplitChangesCollection(dbw, logger)
flags := []dtos.SplitDTO{
{Name: "f0", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_1", "set2"}},
{Name: "f1", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_1"}},
{Name: "f2", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set2"}},
{Name: "f3", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_1", "set2"}},
{Name: "f4", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_1", "set6"}},
{Name: "f5", ChangeNumber: 0, Status: "ACTIVE", TrafficTypeName: "ttt", Sets: []string{"set_5", "set6"}},
}
splitC.Update(flags, nil, 0)

pss := NewProxySplitStorage(dbw, logger, flagsets.NewFlagSetFilter(nil), true)

setNames := pss.GetAllFlagSetNames()

if len(setNames) != 4 {
t.Errorf("setNames len should be 4. Actual %v", len(setNames))
}
}

0 comments on commit 41ef641

Please sign in to comment.