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

refine(ui): debug api #927

Merged
merged 33 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
94e63aa
refine(ui): debugapi layout
shhdgit May 17, 2021
bd7394f
tweak(ui): debug api descriptions
shhdgit May 19, 2021
1560e1c
feat(ui): support debug api database/table select
shhdgit May 19, 2021
d83e855
feat(debugapi): add more debug api endpoints
shhdgit May 20, 2021
b0db8ce
revert(httpclient): pd client with host
shhdgit May 20, 2021
e47bd11
chore: typo
shhdgit May 20, 2021
eada291
tweak(debugapi): test
shhdgit May 21, 2021
3249e0b
test(debugapi): add transformer test
shhdgit May 21, 2021
2143e07
feat(debugapi): add table id widget
shhdgit May 21, 2021
33810a5
refine(debugapi): param transform process
shhdgit May 24, 2021
fe1eca2
tweak(debugapi): transform extension by mime type
shhdgit May 24, 2021
3bc9b54
chore(debugapi): endpoint desc style adjustment
shhdgit May 24, 2021
cccd669
chore: styles & typo
shhdgit May 24, 2021
9e9f6b2
Merge branch 'master' into improve-debug-api
breezewish May 24, 2021
5045904
tweak(debugapi): add pd stores state widget
shhdgit May 24, 2021
31b8884
Merge branch 'improve-debug-api' of github.com:shhdgit/tidb-dashboard…
shhdgit May 24, 2021
3adfd9a
fix(debugapi): pd http schema by cluster config
shhdgit May 25, 2021
a6de666
fix(debugapi): endpoint path
shhdgit May 25, 2021
46fb401
fix(debugapi): error response transform
shhdgit May 25, 2021
fed1d4f
fix(info): `show databases` field database
shhdgit May 26, 2021
e0896f5
feat(debugapi): enum support
shhdgit May 26, 2021
e565c4d
refine(debugapi): pprof endpoints & desc
shhdgit May 26, 2021
e93902d
feat(debugapi): add constant param model
shhdgit May 26, 2021
7b1cf30
refine(debugapi): param model interface
shhdgit May 27, 2021
63da39e
tweak(debugapi): sticky header
shhdgit May 27, 2021
a5915d1
fix(debugapi): search endpoint name
shhdgit May 27, 2021
fb7eafd
Grumble
breezewish May 27, 2021
5673812
Uri -> URI to make linter happy
breezewish May 27, 2021
65aba24
Make linter happy again
breezewish May 27, 2021
29b40e1
Make linter happy again *2
breezewish May 27, 2021
e174341
fix(debugapi): profile format
shhdgit May 30, 2021
da2d030
refine(debugapi): transform data by stream
shhdgit May 31, 2021
e6780ad
feat(debugapi): support bool-type model & add tikv config endpoint
shhdgit Jun 1, 2021
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
1 change: 0 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.12.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
Expand Down
59 changes: 41 additions & 18 deletions pkg/apiserver/debugapi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,26 @@ package debugapi

import (
"fmt"
"time"

"go.uber.org/fx"

"github.com/pingcap/tidb-dashboard/pkg/apiserver/debugapi/endpoint"
"github.com/pingcap/tidb-dashboard/pkg/apiserver/model"
"github.com/pingcap/tidb-dashboard/pkg/httpc"
"github.com/pingcap/tidb-dashboard/pkg/pd"
"github.com/pingcap/tidb-dashboard/pkg/tidb"
"github.com/pingcap/tidb-dashboard/pkg/tiflash"
"github.com/pingcap/tidb-dashboard/pkg/tikv"
)

const (
defaultTimeout = time.Second * 45 // Default profiling can be as long as 30s.
)

type Client interface {
Send(request *Request) ([]byte, error)
Get(request *Request) ([]byte, error)
Send(request *endpoint.Request) (*httpc.Response, error)
Get(request *endpoint.Request) (*httpc.Response, error)
}

type ClientMap map[model.NodeKind]Client
Expand All @@ -42,40 +49,51 @@ func newClientMap(tidbImpl tidbImplement, tikvImpl tikvImplement, tiflashImpl ti
return &clientMap
}

func defaultSendRequest(client Client, req *Request) ([]byte, error) {
func defaultSendRequest(client Client, req *endpoint.Request) (*httpc.Response, error) {
switch req.Method {
case EndpointMethodGet:
case endpoint.MethodGet:
return client.Get(req)
default:
return nil, fmt.Errorf("invalid request method `%s`, host: %s, path: %s", req.Method, req.Host, req.Path)
}
}

func buildRelativeURI(path string, query string) string {
if len(query) == 0 {
return path
}
return fmt.Sprintf("%s?%s", path, query)
}

type tidbImplement struct {
fx.In
Client *tidb.Client
}

func (impl *tidbImplement) Get(req *Request) ([]byte, error) {
return impl.Client.WithEnforcedStatusAPIAddress(req.Host, req.Port).SendGetRequest(req.Path)
func (impl *tidbImplement) Get(req *endpoint.Request) (*httpc.Response, error) {
return impl.Client.
WithEnforcedStatusAPIAddress(req.Host, req.Port).
WithStatusAPITimeout(defaultTimeout).
Get(buildRelativeURI(req.Path, req.Query))
}

func (impl *tidbImplement) Send(req *Request) ([]byte, error) {
func (impl *tidbImplement) Send(req *endpoint.Request) (*httpc.Response, error) {
return defaultSendRequest(impl, req)
}

// TODO: tikv/tiflash/pd forwarder impl

type tikvImplement struct {
fx.In
Client *tikv.Client
}

func (impl *tikvImplement) Get(req *Request) ([]byte, error) {
return impl.Client.SendGetRequest(req.Host, req.Port, req.Path)
func (impl *tikvImplement) Get(req *endpoint.Request) (*httpc.Response, error) {
return impl.Client.
WithTimeout(defaultTimeout).
Get(req.Host, req.Port, buildRelativeURI(req.Path, req.Query))
}

func (impl *tikvImplement) Send(req *Request) ([]byte, error) {
// FIXME: Deduplicate default implementation.
func (impl *tikvImplement) Send(req *endpoint.Request) (*httpc.Response, error) {
return defaultSendRequest(impl, req)
}

Expand All @@ -84,11 +102,13 @@ type tiflashImplement struct {
Client *tiflash.Client
}

func (impl *tiflashImplement) Get(req *Request) ([]byte, error) {
return impl.Client.SendGetRequest(req.Host, req.Port, req.Path)
func (impl *tiflashImplement) Get(req *endpoint.Request) (*httpc.Response, error) {
return impl.Client.
WithTimeout(defaultTimeout).
Get(req.Host, req.Port, buildRelativeURI(req.Path, req.Query))
}

func (impl *tiflashImplement) Send(req *Request) ([]byte, error) {
func (impl *tiflashImplement) Send(req *endpoint.Request) (*httpc.Response, error) {
return defaultSendRequest(impl, req)
}

Expand All @@ -97,10 +117,13 @@ type pdImplement struct {
Client *pd.Client
}

func (impl *pdImplement) Get(req *Request) ([]byte, error) {
return impl.Client.SendGetRequest(req.Path)
func (impl *pdImplement) Get(req *endpoint.Request) (*httpc.Response, error) {
return impl.Client.
WithAddress(req.Host, req.Port).
WithTimeout(defaultTimeout).
Get(buildRelativeURI(req.Path, req.Query))
}

func (impl *pdImplement) Send(req *Request) ([]byte, error) {
func (impl *pdImplement) Send(req *endpoint.Request) (*httpc.Response, error) {
return defaultSendRequest(impl, req)
}
172 changes: 0 additions & 172 deletions pkg/apiserver/debugapi/endpoint.go

This file was deleted.

86 changes: 86 additions & 0 deletions pkg/apiserver/debugapi/endpoint/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2021 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package endpoint

// Context is design for request transform process
type Context struct {
breezewish marked this conversation as resolved.
Show resolved Hide resolved
paramValues Values
paramName string
}

// Value return current param's value
func (c *Context) Value() string {
return c.paramValues.Get(c.paramName)
}

func (c *Context) SetValue(val string) {
c.paramValues.Set(c.paramName, val)
}

// Values return current param's multiple values
func (c *Context) Values() []string {
return c.paramValues[c.paramName]
}

func (c *Context) SetValues(vals []string) {
c.paramValues.Del(c.paramName)
for _, v := range vals {
c.paramValues.Add(c.paramName, v)
}
}

// ParamValue return param's value with the given key
func (c *Context) ParamValue(key string) string {
return c.paramValues.Get(key)
}

// ParamValues return param's multiple values with the given key
func (c *Context) ParamValues(key string) []string {
return c.paramValues[c.paramName]
}

// Values maps a string key to a list of values.
type Values map[string][]string

// Get gets the first value associated with the given key.
// If there are no values associated with the key, Get returns
// the empty string. To access multiple values, use the map
// directly.
func (v Values) Get(key string) string {
if v == nil {
return ""
}
vs := v[key]
if len(vs) == 0 {
return ""
}
return vs[0]
}

// Set sets the key to value. It replaces any existing
// values.
func (v Values) Set(key, value string) {
v[key] = []string{value}
}

// Add adds the value to key. It appends to any existing
// values associated with key.
func (v Values) Add(key, value string) {
v[key] = append(v[key], value)
}

// Del deletes the values associated with key.
func (v Values) Del(key string) {
delete(v, key)
}
Loading