Skip to content

Commit

Permalink
sync with master
Browse files Browse the repository at this point in the history
  • Loading branch information
baurine committed Dec 30, 2021
1 parent 1a7c822 commit e321e7e
Show file tree
Hide file tree
Showing 40 changed files with 993 additions and 420 deletions.
2 changes: 1 addition & 1 deletion pkg/apiserver/diagnose/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ func GetReportTablesIn2Range(startTime1, endTime1, startTime2, endTime2 string,
GetTiDBSlowQueryWithDiffPlan,

// Diagnose
GetDiagnoseReport,
GetAllDiagnoseReport,
}
atomic.AddInt32(totalTableCount, int32(len(funcs)*2))

Expand Down
125 changes: 9 additions & 116 deletions pkg/apiserver/diagnose/diagnose.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@ package diagnose

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"sync"
"time"

"github.com/gin-gonic/gin"
"github.com/goccy/go-graphviz"
"github.com/pingcap/log"
"go.uber.org/zap"

Expand All @@ -31,8 +24,6 @@ const (
timeLayout = "2006-01-02 15:04:05"
)

var graphvizMutex sync.Mutex

type Service struct {
// FIXME: Use fx.In
config *config.Config
Expand Down Expand Up @@ -69,109 +60,18 @@ func RegisterRouter(r *gin.RouterGroup, auth *user.AuthService, s *Service) {
endpoint.GET("/reports/:id/status",
auth.MWAuthRequired(),
s.reportStatusHandler)
endpoint.POST("/metrics_relation/generate", auth.MWAuthRequired(), s.metricsRelationHandler)
endpoint.GET("/metrics_relation/view", s.metricsRelationViewHandler)
}

func (s *Service) generateMetricsRelation(startTime, endTime time.Time, graphType string) (string, error) {
params := url.Values{}
params.Add("start", startTime.Format(time.RFC3339))
params.Add("end", endTime.Format(time.RFC3339))
params.Add("type", graphType)
encodedParams := params.Encode()

data, err := s.tidbClient.SendGetRequest("/metrics/profile?" + encodedParams)
if err != nil {
return "", err
}

file, err := ioutil.TempFile("", "metrics*.svg")
if err != nil {
return "", fmt.Errorf("failed to create temp file: %v", err)
}
_ = file.Close()

g := graphviz.New()
// FIXME: should share a global mutex for profiling.
graphvizMutex.Lock()
defer graphvizMutex.Unlock()
graph, err := graphviz.ParseBytes(data)
if err != nil {
_ = os.Remove(file.Name())
return "", fmt.Errorf("failed to parse DOT file: %v", err)
}

if err := g.RenderFilename(graph, graphviz.SVG, file.Name()); err != nil {
_ = os.Remove(file.Name())
return "", fmt.Errorf("failed to render SVG: %v", err)
}

return file.Name(), nil
}

type GenerateMetricsRelationRequest struct {
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
Type string `json:"type"`
}

// @Id diagnoseGenerateMetricsRelationship
// @Summary Generate metrics relationship graph.
// @Param request body GenerateMetricsRelationRequest true "Request body"
// @Router /diagnose/metrics_relation/generate [post]
// @Success 200 {string} string
// @Security JwtAuth
// @Failure 401 {object} utils.APIError "Unauthorized failure"
func (s *Service) metricsRelationHandler(c *gin.Context) {
var req GenerateMetricsRelationRequest
if err := c.ShouldBindJSON(&req); err != nil {
utils.MakeInvalidRequestErrorFromError(c, err)
return
}

startTime := time.Unix(req.StartTime, 0)
endTime := time.Unix(req.EndTime, 0)

path, err := s.generateMetricsRelation(startTime, endTime, req.Type)
if err != nil {
_ = c.Error(err)
return
}

token, err := utils.NewJWTString("diagnose/metrics", path)
if err != nil {
_ = c.Error(err)
return
}

c.JSON(http.StatusOK, token)
endpoint.POST("/diagnosis",
auth.MWAuthRequired(),
utils.MWConnectTiDB((s.tidbClient)),
s.genDiagnosisHandler)
}

// @Summary View metrics relationship graph.
// @Produce image/svg
// @Param token query string true "token"
// @Failure 400 {object} utils.APIError
// @Failure 401 {object} utils.APIError "Unauthorized failure"
// @Failure 500 {object} utils.APIError
// @Router /diagnose/metrics_relation/view [get]
func (s *Service) metricsRelationViewHandler(c *gin.Context) {
token := c.Query("token")
path, err := utils.ParseJWTString("diagnose/metrics", token)
if err != nil {
utils.MakeInvalidRequestErrorFromError(c, err)
return
}

data, err := ioutil.ReadFile(filepath.Clean(path))
if err != nil {
_ = c.Error(err)
return
}

// Do not remove it? Otherwise the link will just expire..
// _ = os.Remove(path)

c.Data(http.StatusOK, "image/svg+xml", data)
type GenerateReportRequest struct {
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
CompareStartTime int64 `json:"compare_start_time"`
CompareEndTime int64 `json:"compare_end_time"`
}

// @Summary SQL diagnosis reports history
Expand All @@ -189,13 +89,6 @@ func (s *Service) reportsHandler(c *gin.Context) {
c.JSON(http.StatusOK, reports)
}

type GenerateReportRequest struct {
StartTime int64 `json:"start_time"`
EndTime int64 `json:"end_time"`
CompareStartTime int64 `json:"compare_start_time"`
CompareEndTime int64 `json:"compare_end_time"`
}

// @Summary SQL diagnosis report
// @Description Generate sql diagnosis report
// @Param request body GenerateReportRequest true "Request body"
Expand Down
30 changes: 19 additions & 11 deletions pkg/apiserver/diagnose/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ import (
)

type TableDef struct {
Category []string // The category of the table, such as [TiDB]
Title string
Comment string // English Comment
Category []string `json:"category"` // The category of the table, such as [TiDB]
Title string `json:"title"`
Comment string `json:"comment"`
joinColumns []int
compareColumns []int
Column []string // Column name
Rows []TableRowDef
Column []string `json:"column"`
Rows []TableRowDef `json:"rows"`
}

type TableRowDef struct {
Values []string
SubValues [][]string // SubValues need fold default.
Values []string `json:"values"`
SubValues [][]string `json:"sub_values"` // SubValues need fold default.
ratio float64
Comment string
Comment string `json:"comment"`
}

func (t TableDef) ColumnWidth() []int {
Expand Down Expand Up @@ -80,6 +80,7 @@ func GetReportTablesForDisplay(startTime, endTime string, db *gorm.DB, sqliteDB
return []*TableDef{GenerateReportError(errRows)}
}
tables := GetReportTables(startTime, endTime, db, sqliteDB, reportID)

lastCategory := ""
for _, tbl := range tables {
if tbl == nil {
Expand Down Expand Up @@ -127,7 +128,7 @@ func GetReportTables(startTime, endTime string, db *gorm.DB, sqliteDB *dbstore.D
GetClusterInfoTable,

// Diagnose
GetDiagnoseReport,
GetAllDiagnoseReport,

// Load
GetLoadTable,
Expand Down Expand Up @@ -313,14 +314,21 @@ func GetHeaderTimeTable(startTime, endTime string, db *gorm.DB) (TableDef, error
}, nil
}

func GetDiagnoseReport(startTime, endTime string, db *gorm.DB) (TableDef, error) {
func GetAllDiagnoseReport(startTime, endTime string, db *gorm.DB) (TableDef, error) {
return GetDiagnoseReport(startTime, endTime, db, nil)
}

func GetDiagnoseReport(startTime, endTime string, db *gorm.DB, rules []string) (TableDef, error) {
table := TableDef{
Category: []string{CategoryDiagnose},
Title: "diagnose",
Comment: "",
Column: []string{"RULE", "ITEM", "TYPE", "INSTANCE", "STATUS_ADDRESS", "VALUE", "REFERENCE", "SEVERITY", "DETAILS"},
}
sql := fmt.Sprintf("select /*+ time_range('%s','%s') */ %s from information_schema.INSPECTION_RESULT", startTime, endTime, strings.Join(table.Column, ","))
if len(rules) > 0 {
sql = fmt.Sprintf("%s where RULE in ('%s')", sql, strings.Join(rules, "','"))
}
rows, err := getSQLRows(db, sql)
if err != nil {
return table, err
Expand Down Expand Up @@ -2113,7 +2121,7 @@ func GetClusterHardwareInfoTable(startTime, endTime string, db *gorm.DB) (TableD
FROM information_schema.CLUSTER_HARDWARE
WHERE device_type='cpu'
group by instance,type,VALUE,NAME HAVING NAME = 'cpu-physical-cores'
OR NAME = 'cpu-logical-cores' ORDER BY INSTANCE `
OR NAME = 'cpu-logical-cores' ORDER BY INSTANCE`
rows, err := querySQL(db, sql)
if err != nil {
return table, err
Expand Down
3 changes: 0 additions & 3 deletions scripts/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,3 @@ ${LINT_BIN} run --fix

echo "+ Clean up go mod"
go mod tidy

echo "+ Run lints for docs"
npm_config_yes=true npx [email protected] docs/**/*.md
2 changes: 2 additions & 0 deletions ui/dashboardApp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import AppOverview from '@lib/apps/Overview/index.meta'
import AppClusterInfo from '@lib/apps/ClusterInfo/index.meta'
import AppKeyViz from '@lib/apps/KeyViz/index.meta'
import AppStatement from '@lib/apps/Statement/index.meta'
import AppSystemReport from '@lib/apps/SystemReport/index.meta'
import AppSlowQuery from '@lib/apps/SlowQuery/index.meta'
import AppDiagnose from '@lib/apps/Diagnose/index.meta'
import AppSearchLogs from '@lib/apps/SearchLogs/index.meta'
Expand Down Expand Up @@ -112,6 +113,7 @@ async function webPageStart() {
.register(AppClusterInfo)
.register(AppKeyViz)
.register(AppStatement)
.register(AppSystemReport)
.register(AppSlowQuery)
.register(AppDiagnose)
.register(AppSearchLogs)
Expand Down
1 change: 1 addition & 0 deletions ui/dashboardApp/layout/main/Sider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ function Sider({
useAppMenuItem(registry, 'statement'),
useAppMenuItem(registry, 'slow_query'),
useAppMenuItem(registry, 'keyviz'),
useAppMenuItem(registry, 'system_report'),
useAppMenuItem(registry, 'diagnose'),
useAppMenuItem(registry, 'search_logs'),
// useAppMenuItem(registry, '__APP_NAME__'),
Expand Down
10 changes: 5 additions & 5 deletions ui/diagnoseReportApp/components/DiagnosisReport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ function TablesNavMenu({ diagnosisTables }: Props) {
}}
>
{diagnosisTables.map((item) => (
<React.Fragment key={item.Title}>
<React.Fragment key={item.title}>
<h2 style={{ paddingLeft: 16 }}>
{item.Category[0] &&
t(`diagnosis.tables.category.${item.Category[0]}`)}
{item.category[0] &&
t(`diagnosis.tables.category.${item.category[0]}`)}
</h2>
<a
style={{ paddingLeft: 32 }}
className="dropdown-item"
href={`#${item.Title}`}
href={`#${item.title}`}
>
{t(`diagnosis.tables.title.${item.Title}`)}
{t(`diagnosis.tables.title.${item.title}`)}
</a>
</React.Fragment>
))}
Expand Down
6 changes: 3 additions & 3 deletions ui/diagnoseReportApp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ function refineDiagnosisData() {

let preCategory = ''
diagnosisData.forEach((d) => {
if (d.Category.join('') === preCategory) {
d.Category = []
if (d.category.join('') === preCategory) {
d.category = []
} else {
preCategory = d.Category.join('')
preCategory = d.category.join('')
}
})
return diagnosisData
Expand Down
4 changes: 2 additions & 2 deletions ui/diagnoseReportApp/translations/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ diagnosis:
fold_all: Collapse All
expand: Expand
fold: Collapse
all_tables: Diagnostics Overview
all_tables: Report Overview
tables:
category:
header: Basic Info
Expand All @@ -30,7 +30,7 @@ diagnosis:
max_diff_item: Maximum Different Item
slow_query_t2: Slow Queries In Time Range t2
generate_report_error: Report Generation Error
report_time_range: Diagnostics Time Range
report_time_range: Report Time Range
diagnose: Diagnosis Result
total_time_consume: Time Consumed by Each Component
total_error: Errors Occurred in Each Component
Expand Down
6 changes: 3 additions & 3 deletions ui/diagnoseReportApp/translations/zh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ diagnosis:
fold_all: 收起所有
expand: 展开
fold: 收起
all_tables: 诊断信息总览
all_tables: 报告信息总览
tables:
category:
header: 基本信息
Expand All @@ -18,7 +18,7 @@ diagnosis:
error: 错误
title:
compare_diagnose: 诊断对比
compare_report_time_range: 对比诊断区间
compare_report_time_range: 对比报告区间
top_10_slow_query_in_time_range_t1: t1 中的 Top 10 慢查询
top_10_slow_query_in_time_range_t2: t2 中的 Top 10 慢查询
top_10_slow_query_group_by_digest_in_time_range_t1: 按 SQL 指纹聚合的 t1 Top 10 慢查询
Expand All @@ -30,7 +30,7 @@ diagnosis:
max_diff_item: 最大不同项
slow_query_t2: t2 中的慢查询
generate_report_error: 生成报告的报错
report_time_range: 诊断区间
report_time_range: 报告区间
diagnose: 诊断结果
total_time_consume: 各组件总耗时
total_error: 各组件总报错数
Expand Down
19 changes: 8 additions & 11 deletions ui/diagnoseReportApp/types.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { createContext } from 'react'

export interface TableRowDef {
Values: string[]
SubValues: string[][]
ratio: number
Comment: string
values: string[]
sub_values: string[][]
comment: string
}

export interface TableDef {
Category: string[]
Title: string
Comment: string
joinColumns: number[]
compareColumns: number[]
Column: string[]
Rows: TableRowDef[]
category: string[]
title: string
comment: string
column: string[]
rows: TableRowDef[]
}

export const ExpandContext = createContext(false)
Loading

0 comments on commit e321e7e

Please sign in to comment.