From cda3d75bd921128a58f6be95ff3945e2d64c4e66 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Sat, 1 Aug 2020 03:48:24 +0200 Subject: [PATCH 1/8] Add realtimeStats to Vtctld /api/keyspace//tablets API --- go/vt/vtctld/api.go | 79 +++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/go/vt/vtctld/api.go b/go/vt/vtctld/api.go index ede03e98815..deb3a36f086 100644 --- a/go/vt/vtctld/api.go +++ b/go/vt/vtctld/api.go @@ -42,6 +42,7 @@ import ( "vitess.io/vitess/go/vt/mysqlctl" logutilpb "vitess.io/vitess/go/vt/proto/logutil" + querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/proto/vttime" ) @@ -60,8 +61,15 @@ const ( jsonContentType = "application/json; charset=utf-8" ) -// TabletWithURL wraps topo.Tablet and adds a URL property. -type TabletWithURL struct { +// TabletStats represents the realtime stats of a tablet +type TabletStats struct { + Up bool `json:"up,omitempty"` + Serving bool `json:"serving,omitempty"` + Realtime *querypb.RealtimeStats `json:"realtime,omitempty"` +} + +// TabletWithStatsAndURL wraps topo.Tablet and adds a URL property and discovery.TabletStats. +type TabletWithStatsAndURL struct { Alias *topodatapb.TabletAlias `json:"alias,omitempty"` Hostname string `json:"hostname,omitempty"` PortMap map[string]int32 `json:"port_map,omitempty"` @@ -75,6 +83,44 @@ type TabletWithURL struct { MysqlPort int32 `json:"mysql_port,omitempty"` MasterTermStartTime *vttime.Time `json:"master_term_start_time,omitempty"` URL string `json:"url,omitempty"` + Stats *TabletStats `json:"stats,omitempty"` +} + +func NewTabletWithStatsAndURL(t *topodatapb.Tablet, realtimeStats *realtimeStats) (*TabletWithStatsAndURL, error) { + tab := &TabletWithStatsAndURL{ + Alias: t.Alias, + Hostname: t.Hostname, + PortMap: t.PortMap, + Keyspace: t.Keyspace, + Shard: t.Shard, + KeyRange: t.KeyRange, + Type: t.Type, + DbNameOverride: t.DbNameOverride, + Tags: t.Tags, + MysqlHostname: t.MysqlHostname, + MysqlPort: t.MysqlPort, + MasterTermStartTime: t.MasterTermStartTime, + } + + if *proxyTablets { + tab.URL = fmt.Sprintf("/vttablet/%s-%d", t.Alias.Cell, t.Alias.Uid) + } else { + tab.URL = "http://" + netutil.JoinHostPort(t.Hostname, t.PortMap["vt"]) + } + + if realtimeStats != nil { + tabletStats, err := realtimeStats.tabletStats(tab.Alias) + if err != nil { + return nil, err + } + tab.Stats = &TabletStats{ + Up: tabletStats.Up, + Serving: tabletStats.Serving, + Realtime: tabletStats.Stats, + } + } + + return tab, nil } func httpErrorf(w http.ResponseWriter, r *http.Request, format string, args ...interface{}) { @@ -218,7 +264,7 @@ func initAPI(ctx context.Context, ts *topo.Server, actions *ActionRepository, re return nil, err } } - tablets := [](*topodatapb.Tablet){} + tablets := [](*TabletWithStatsAndURL){} for _, shard := range shardNames { // Get tablets for this shard. tabletAliases, err := ts.FindAllTabletAliasesInShard(ctx, keyspace, shard) @@ -230,7 +276,11 @@ func initAPI(ctx context.Context, ts *topo.Server, actions *ActionRepository, re if err != nil { return nil, err } - tablets = append(tablets, t.Tablet) + tablet, err := NewTabletWithStatsAndURL(t.Tablet, realtimeStats) + if err != nil { + return nil, err + } + tablets = append(tablets, tablet) } } return tablets, nil @@ -394,26 +444,7 @@ func initAPI(ctx context.Context, ts *topo.Server, actions *ActionRepository, re return nil, err } - tab := &TabletWithURL{ - Alias: t.Alias, - Hostname: t.Hostname, - PortMap: t.PortMap, - Keyspace: t.Keyspace, - Shard: t.Shard, - KeyRange: t.KeyRange, - Type: t.Type, - DbNameOverride: t.DbNameOverride, - Tags: t.Tags, - MysqlHostname: t.MysqlHostname, - MysqlPort: t.MysqlPort, - MasterTermStartTime: t.MasterTermStartTime, - } - if *proxyTablets { - tab.URL = fmt.Sprintf("/vttablet/%s-%d", t.Alias.Cell, t.Alias.Uid) - } else { - tab.URL = "http://" + netutil.JoinHostPort(t.Hostname, t.PortMap["vt"]) - } - return tab, nil + return NewTabletWithStatsAndURL(t.Tablet, nil) }) // Healthcheck real time status per (cell, keyspace, tablet type, metric). From 1fc43833fcd2f0714dafad84652f80ff0f893182 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Sat, 1 Aug 2020 17:57:04 +0200 Subject: [PATCH 2/8] Tidy up code --- go/vt/vtctld/api.go | 41 ++++++++++++++++++++++++++-------------- go/vt/vtctld/api_test.go | 14 ++++++++++++++ 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/go/vt/vtctld/api.go b/go/vt/vtctld/api.go index 9e87abe0fd6..b78cf481a26 100644 --- a/go/vt/vtctld/api.go +++ b/go/vt/vtctld/api.go @@ -63,9 +63,9 @@ const ( // TabletStats represents the realtime stats of a tablet type TabletStats struct { - Up bool `json:"up,omitempty"` - Serving bool `json:"serving,omitempty"` - Realtime *querypb.RealtimeStats `json:"realtime,omitempty"` + RealtimeStats *querypb.RealtimeStats `json:"realtime_stats,omitempty"` + Serving bool `json:"serving,omitempty"` + Up bool `json:"up,omitempty"` } // TabletWithStatsAndURL wraps topo.Tablet and adds a URL property and discovery.TabletStats. @@ -82,12 +82,12 @@ type TabletWithStatsAndURL struct { MysqlHostname string `json:"mysql_hostname,omitempty"` MysqlPort int32 `json:"mysql_port,omitempty"` MasterTermStartTime *vttime.Time `json:"master_term_start_time,omitempty"` - URL string `json:"url,omitempty"` Stats *TabletStats `json:"stats,omitempty"` + URL string `json:"url,omitempty"` } func NewTabletWithStatsAndURL(t *topodatapb.Tablet, realtimeStats *realtimeStats) (*TabletWithStatsAndURL, error) { - tab := &TabletWithStatsAndURL{ + tablet := &TabletWithStatsAndURL{ Alias: t.Alias, Hostname: t.Hostname, PortMap: t.PortMap, @@ -103,24 +103,24 @@ func NewTabletWithStatsAndURL(t *topodatapb.Tablet, realtimeStats *realtimeStats } if *proxyTablets { - tab.URL = fmt.Sprintf("/vttablet/%s-%d", t.Alias.Cell, t.Alias.Uid) + tablet.URL = fmt.Sprintf("/vttablet/%s-%d", t.Alias.Cell, t.Alias.Uid) } else { - tab.URL = "http://" + netutil.JoinHostPort(t.Hostname, t.PortMap["vt"]) + tablet.URL = "http://" + netutil.JoinHostPort(t.Hostname, t.PortMap["vt"]) } if realtimeStats != nil { - tabletStats, err := realtimeStats.tabletStats(tab.Alias) + stats, err := realtimeStats.tabletStats(tablet.Alias) if err != nil { return nil, err } - tab.Stats = &TabletStats{ - Up: tabletStats.Up, - Serving: tabletStats.Serving, - Realtime: tabletStats.Stats, + tablet.Stats = &TabletStats{ + Up: stats.Up, + Serving: stats.Serving, + RealtimeStats: stats.Stats, } } - return tab, nil + return tablet, nil } func httpErrorf(w http.ResponseWriter, r *http.Request, format string, args ...interface{}) { @@ -264,10 +264,23 @@ func initAPI(ctx context.Context, ts *topo.Server, actions *ActionRepository, re return nil, err } } + + if err := r.ParseForm(); err != nil { + return nil, err + } + cell := r.FormValue("cell") + cells := r.FormValue("cells") + filterCells := []string{} // empty == all cells + if cell != "" { + filterCells[0] = cell // single cell + } else if cells != "" { + filterCells = strings.Split(cells, ",") // list of cells + } + tablets := [](*TabletWithStatsAndURL){} for _, shard := range shardNames { // Get tablets for this shard. - tabletAliases, err := ts.FindAllTabletAliasesInShard(ctx, keyspace, shard) + tabletAliases, err := ts.FindAllTabletAliasesInShardByCell(ctx, keyspace, shard, filterCells) if err != nil && !topo.IsErrType(err, topo.PartialResult) { return nil, err } diff --git a/go/vt/vtctld/api_test.go b/go/vt/vtctld/api_test.go index 0ff316ce180..a4dc939f1c0 100644 --- a/go/vt/vtctld/api_test.go +++ b/go/vt/vtctld/api_test.go @@ -139,6 +139,20 @@ func TestAPI(t *testing.T) { // Cells {"GET", "cells", "", `["cell1","cell2"]`}, + // Keyspace + {"GET", "keyspace/test_ks/tablets/", "", `[ + ]`}, + {"GET", "keyspace/test_ks/tablets/?cell=cell1", "", `[ + ]`}, + {"GET", "keyspace/test_ks/tablets/?cells=cell1,cell2", "", `[ + ]`}, + {"GET", "keyspace/test_ks/tablets/test_shard", "", `[ + ]`}, + {"GET", "keyspace/test_ks/tablets/test_shard?cell=cell1", "", `[ + ]`}, + {"GET", "keyspace/test_ks/tablets/test_shard?cells=cell1,cell2", "", `[ + ]`}, + // Keyspaces {"GET", "keyspaces", "", `["ks1", "ks3"]`}, {"GET", "keyspaces/ks1", "", `{ From 9ecb354d98053713c03d9efaab389b419754e20f Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Sat, 1 Aug 2020 18:22:51 +0200 Subject: [PATCH 3/8] Fix /debug/status in tablet URL Signed-off-by: Tim Vaillancourt --- go/vt/vtctld/api.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/go/vt/vtctld/api.go b/go/vt/vtctld/api.go index b78cf481a26..78c537af70d 100644 --- a/go/vt/vtctld/api.go +++ b/go/vt/vtctld/api.go @@ -63,6 +63,7 @@ const ( // TabletStats represents the realtime stats of a tablet type TabletStats struct { + LastError string `json:"last_error,omitempty"` RealtimeStats *querypb.RealtimeStats `json:"realtime_stats,omitempty"` Serving bool `json:"serving,omitempty"` Up bool `json:"up,omitempty"` @@ -103,7 +104,7 @@ func NewTabletWithStatsAndURL(t *topodatapb.Tablet, realtimeStats *realtimeStats } if *proxyTablets { - tablet.URL = fmt.Sprintf("/vttablet/%s-%d", t.Alias.Cell, t.Alias.Uid) + tab.URL = fmt.Sprintf("/vttablet/%s-%d/debug/status", t.Alias.Cell, t.Alias.Uid) } else { tablet.URL = "http://" + netutil.JoinHostPort(t.Hostname, t.PortMap["vt"]) } @@ -114,9 +115,10 @@ func NewTabletWithStatsAndURL(t *topodatapb.Tablet, realtimeStats *realtimeStats return nil, err } tablet.Stats = &TabletStats{ - Up: stats.Up, - Serving: stats.Serving, + LastError: stats.LastError.Error(), RealtimeStats: stats.Stats, + Serving: stats.Serving, + Up: stats.Up, } } From 931dbb2759eeb1a6deefd6fdf406f124f2b95f4b Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Sat, 1 Aug 2020 18:53:03 +0200 Subject: [PATCH 4/8] Fix CI typo problem Signed-off-by: Tim Vaillancourt --- go/vt/vtctld/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtctld/api.go b/go/vt/vtctld/api.go index 78c537af70d..2792c17d60e 100644 --- a/go/vt/vtctld/api.go +++ b/go/vt/vtctld/api.go @@ -104,7 +104,7 @@ func NewTabletWithStatsAndURL(t *topodatapb.Tablet, realtimeStats *realtimeStats } if *proxyTablets { - tab.URL = fmt.Sprintf("/vttablet/%s-%d/debug/status", t.Alias.Cell, t.Alias.Uid) + tablet.URL = fmt.Sprintf("/vttablet/%s-%d/debug/status", t.Alias.Cell, t.Alias.Uid) } else { tablet.URL = "http://" + netutil.JoinHostPort(t.Hostname, t.PortMap["vt"]) } From 417890e2ed05e4bfb8ea3cec78f1bf48f70932ea Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Sat, 1 Aug 2020 21:07:36 +0200 Subject: [PATCH 5/8] Fix comments Signed-off-by: Tim Vaillancourt --- go/vt/vtctld/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/vtctld/api.go b/go/vt/vtctld/api.go index 2792c17d60e..88e911484d6 100644 --- a/go/vt/vtctld/api.go +++ b/go/vt/vtctld/api.go @@ -61,7 +61,7 @@ const ( jsonContentType = "application/json; charset=utf-8" ) -// TabletStats represents the realtime stats of a tablet +// TabletStats represents realtime stats from a discovery.LegacyTabletStats struct. type TabletStats struct { LastError string `json:"last_error,omitempty"` RealtimeStats *querypb.RealtimeStats `json:"realtime_stats,omitempty"` @@ -69,7 +69,7 @@ type TabletStats struct { Up bool `json:"up,omitempty"` } -// TabletWithStatsAndURL wraps topo.Tablet and adds a URL property and discovery.TabletStats. +// TabletWithStatsAndURL wraps topo.Tablet, adding a URL property and optional realtime stats. type TabletWithStatsAndURL struct { Alias *topodatapb.TabletAlias `json:"alias,omitempty"` Hostname string `json:"hostname,omitempty"` From 373ebf07457a2522a3324ffe6e3c8bcd1bfa8e26 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Fri, 14 Aug 2020 17:39:59 +0200 Subject: [PATCH 6/8] Attempt unit testing Signed-off-by: Tim Vaillancourt --- go/vt/vtctld/api_test.go | 64 +++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/go/vt/vtctld/api_test.go b/go/vt/vtctld/api_test.go index a4dc939f1c0..d5a11c3af15 100644 --- a/go/vt/vtctld/api_test.go +++ b/go/vt/vtctld/api_test.go @@ -140,18 +140,60 @@ func TestAPI(t *testing.T) { {"GET", "cells", "", `["cell1","cell2"]`}, // Keyspace - {"GET", "keyspace/test_ks/tablets/", "", `[ - ]`}, - {"GET", "keyspace/test_ks/tablets/?cell=cell1", "", `[ - ]`}, - {"GET", "keyspace/test_ks/tablets/?cells=cell1,cell2", "", `[ - ]`}, - {"GET", "keyspace/test_ks/tablets/test_shard", "", `[ - ]`}, - {"GET", "keyspace/test_ks/tablets/test_shard?cell=cell1", "", `[ - ]`}, - {"GET", "keyspace/test_ks/tablets/test_shard?cells=cell1,cell2", "", `[ + {"GET", "keyspace/ks1/tablets/", "", `[ + { + "alias": { + "cell": "cell1", + "uid": 170947604 + }, + "hostname": "db-mysql-792a7de.cell1-iad.test.com", + "port_map": { + "grpc": 15991, + "mysql": 3306, + "vt": 15101 + }, + "keyspace": "test_ks", + "shard": "-80", + "key_range": { + "start": "wA==" + }, + "type": 2, + "db_name_override": "test", + "mysql_hostname": "db-mysql-792a7de.cell1-iad.test.com", + "mysql_port": 3306 + }, + { + "alias": { + "cell": "cell2", + "uid": 170947605 + }, + "hostname": "mysql2.test.com", + "port_map": { + "grpc": 15991, + "mysql": 3306, + "vt": 15101 + }, + "keyspace": "test_ks", + "shard": "-80", + "key_range": { + "start": "wA==" + }, + "type": 2, + "db_name_override": "test", + "mysql_hostname": "mysql2.test.com", + "mysql_port": 3306 + } ]`}, + //{"GET", "keyspace/ks1/tablets/?cell=cell1", "", `[ + //]`}, + //{"GET", "keyspace/ks1/tablets/?cells=cell1,cell2", "", `[ + //]`}, + //{"GET", "keyspace/ks1/tablets/-80", "", `[ + //]`}, + //{"GET", "keyspace/ks1/tablets/-80?cell=cell1", "", `[ + //]`}, + //{"GET", "keyspace/ks1/tablets/-80?cells=cell1,cell2", "", `[ + //]`}, // Keyspaces {"GET", "keyspaces", "", `["ks1", "ks3"]`}, From 4423a774817f5b7b18a70b9944b99a8a1b5ec1e2 Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Fri, 14 Aug 2020 19:07:15 +0200 Subject: [PATCH 7/8] Fix unit test Signed-off-by: Tim Vaillancourt --- go/vt/vtctld/api.go | 20 ++++---- go/vt/vtctld/api_test.go | 107 ++++++++++++++++++++++++++------------- 2 files changed, 83 insertions(+), 44 deletions(-) diff --git a/go/vt/vtctld/api.go b/go/vt/vtctld/api.go index 88e911484d6..cc03a2c3cb1 100644 --- a/go/vt/vtctld/api.go +++ b/go/vt/vtctld/api.go @@ -110,15 +110,15 @@ func NewTabletWithStatsAndURL(t *topodatapb.Tablet, realtimeStats *realtimeStats } if realtimeStats != nil { - stats, err := realtimeStats.tabletStats(tablet.Alias) - if err != nil { - return nil, err - } - tablet.Stats = &TabletStats{ - LastError: stats.LastError.Error(), - RealtimeStats: stats.Stats, - Serving: stats.Serving, - Up: stats.Up, + if stats, err := realtimeStats.tabletStats(tablet.Alias); err == nil { + tablet.Stats = &TabletStats{ + RealtimeStats: stats.Stats, + Serving: stats.Serving, + Up: stats.Up, + } + if stats.LastError != nil { + tablet.Stats.LastError = stats.LastError.Error() + } } } @@ -274,7 +274,7 @@ func initAPI(ctx context.Context, ts *topo.Server, actions *ActionRepository, re cells := r.FormValue("cells") filterCells := []string{} // empty == all cells if cell != "" { - filterCells[0] = cell // single cell + filterCells = []string{cell} // single cell } else if cells != "" { filterCells = strings.Split(cells, ",") // list of cells } diff --git a/go/vt/vtctld/api_test.go b/go/vt/vtctld/api_test.go index d5a11c3af15..f4a2927fa03 100644 --- a/go/vt/vtctld/api_test.go +++ b/go/vt/vtctld/api_test.go @@ -126,6 +126,49 @@ func TestAPI(t *testing.T) { realtimeStats.StatsUpdate(ts5) realtimeStats.StatsUpdate(ts6) + // all-tablets response for keyspace/ks1/tablets/ endpoints + keyspaceKs1AllTablets := `[ + { + "alias": { + "cell": "cell1", + "uid": 100 + }, + "port_map": { + "vt": 100 + }, + "keyspace": "ks1", + "shard": "-80", + "key_range": { + "end": "gA==" + }, + "type": 2, + "stats": { + "realtime_stats": { + "seconds_behind_master": 100 + }, + "serving": true, + "up": true + }, + "url": "http://:100" + }, + { + "alias": { + "cell": "cell2", + "uid": 200 + }, + "port_map": { + "vt": 200 + }, + "keyspace": "ks1", + "shard": "-80", + "key_range": { + "end": "gA==" + }, + "type": 2, + "url": "http://:200" + } + ]` + // Test cases. table := []struct { method, path, body, want string @@ -140,60 +183,56 @@ func TestAPI(t *testing.T) { {"GET", "cells", "", `["cell1","cell2"]`}, // Keyspace - {"GET", "keyspace/ks1/tablets/", "", `[ + {"GET", "keyspace/doesnt-exist/tablets/", "", ``}, + {"GET", "keyspace/ks1/tablets/", "", keyspaceKs1AllTablets}, + {"GET", "keyspace/ks1/tablets/-80", "", keyspaceKs1AllTablets}, + {"GET", "keyspace/ks1/tablets/80-", "", `[]`}, + {"GET", "keyspace/ks1/tablets/?cells=cell1,cell2", "", keyspaceKs1AllTablets}, + {"GET", "keyspace/ks1/tablets/?cells=cell1", "", `[ { "alias": { - "cell": "cell1", - "uid": 170947604 + "cell": "cell1", + "uid": 100 }, - "hostname": "db-mysql-792a7de.cell1-iad.test.com", "port_map": { - "grpc": 15991, - "mysql": 3306, - "vt": 15101 + "vt": 100 }, - "keyspace": "test_ks", + "keyspace": "ks1", "shard": "-80", "key_range": { - "start": "wA==" + "end": "gA==" }, "type": 2, - "db_name_override": "test", - "mysql_hostname": "db-mysql-792a7de.cell1-iad.test.com", - "mysql_port": 3306 - }, + "stats": { + "realtime_stats": { + "seconds_behind_master": 100 + }, + "serving": true, + "up": true + }, + "url": "http://:100" + } + ]`}, + {"GET", "keyspace/ks1/tablets/?cells=cell3", "", `[]`}, + {"GET", "keyspace/ks1/tablets/?cell=cell2", "", `[ { "alias": { - "cell": "cell2", - "uid": 170947605 + "cell": "cell2", + "uid": 200 }, - "hostname": "mysql2.test.com", "port_map": { - "grpc": 15991, - "mysql": 3306, - "vt": 15101 + "vt": 200 }, - "keyspace": "test_ks", + "keyspace": "ks1", "shard": "-80", "key_range": { - "start": "wA==" + "end": "gA==" }, "type": 2, - "db_name_override": "test", - "mysql_hostname": "mysql2.test.com", - "mysql_port": 3306 + "url": "http://:200" } ]`}, - //{"GET", "keyspace/ks1/tablets/?cell=cell1", "", `[ - //]`}, - //{"GET", "keyspace/ks1/tablets/?cells=cell1,cell2", "", `[ - //]`}, - //{"GET", "keyspace/ks1/tablets/-80", "", `[ - //]`}, - //{"GET", "keyspace/ks1/tablets/-80?cell=cell1", "", `[ - //]`}, - //{"GET", "keyspace/ks1/tablets/-80?cells=cell1,cell2", "", `[ - //]`}, + {"GET", "keyspace/ks1/tablets/?cell=cell3", "", `[]`}, // Keyspaces {"GET", "keyspaces", "", `["ks1", "ks3"]`}, From 68cc97c01d04b2c7050a269ac78d99ca0f32a09d Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Fri, 14 Aug 2020 19:56:22 +0200 Subject: [PATCH 8/8] Update json hint Signed-off-by: Tim Vaillancourt --- go/vt/vtctld/api.go | 2 +- go/vt/vtctld/api_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/vt/vtctld/api.go b/go/vt/vtctld/api.go index cc03a2c3cb1..1d4cc66bb18 100644 --- a/go/vt/vtctld/api.go +++ b/go/vt/vtctld/api.go @@ -64,7 +64,7 @@ const ( // TabletStats represents realtime stats from a discovery.LegacyTabletStats struct. type TabletStats struct { LastError string `json:"last_error,omitempty"` - RealtimeStats *querypb.RealtimeStats `json:"realtime_stats,omitempty"` + RealtimeStats *querypb.RealtimeStats `json:"realtime,omitempty"` Serving bool `json:"serving,omitempty"` Up bool `json:"up,omitempty"` } diff --git a/go/vt/vtctld/api_test.go b/go/vt/vtctld/api_test.go index f4a2927fa03..ee8796cfad9 100644 --- a/go/vt/vtctld/api_test.go +++ b/go/vt/vtctld/api_test.go @@ -143,7 +143,7 @@ func TestAPI(t *testing.T) { }, "type": 2, "stats": { - "realtime_stats": { + "realtime": { "seconds_behind_master": 100 }, "serving": true, @@ -204,7 +204,7 @@ func TestAPI(t *testing.T) { }, "type": 2, "stats": { - "realtime_stats": { + "realtime": { "seconds_behind_master": 100 }, "serving": true,