Skip to content

Commit

Permalink
feature: Trace query and debug enhancement (#1553)
Browse files Browse the repository at this point in the history
* trace feature

* openapi

* fix duration check

* fix duration bug

* fix service name

* update ut

* add license

* imports format

* update ut

* update ut

* add ut TestTranslateCondition()

* add ut Test_queryConditions()

* add ut Test_traceService_getDebugStatus()

* imports format

* Keep spaces between Chinese characters and letters
  • Loading branch information
innerpeacez authored Aug 25, 2021
1 parent 6103ca2 commit 8d486f5
Show file tree
Hide file tree
Showing 15 changed files with 710 additions and 104 deletions.
3 changes: 3 additions & 0 deletions .erda/migrations/msp/20210818-sp_trace_request_history.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE `sp_trace_request_history` MODIFY COLUMN `response_body` MEDIUMTEXT DEFAULT NULL COMMENT '请求响应体';

ALTER TABLE `sp_trace_request_history` ADD COLUMN `name` VARCHAR(100) NOT NULL COMMENT '链路调试名称' AFTER `request_id`;
28 changes: 27 additions & 1 deletion conf/msp/i18n/msp-i18n.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ en:
workspace_default: "DEFAULT"
project_type_dop: "DevOps Project"
project_type_msp: "MSP Project"
span_count_desc: Span Count DESC
span_count_asc: Span Count ASC
trace_duration_desc: Trace Duration DESC
trace_duration_asc: Trace Duration ASC
trace_time_desc: Trace Time DESC
trace_time_asc: Trace Time ASC
service_name: Service Name
trace_id: Trace ID
dubbo_method: Dubbo Method
http_path: HTTP Path
trace_success: SUCCESS
trace_error: ERROR
trace_all: ALL
zh:
waiting_for_tracing_data: "正在获取链路追踪数据"
success_get_tracing_data: "获取链路追踪数据成功"
Expand All @@ -21,4 +34,17 @@ zh:
workspace_prod: "生产"
workspace_default: "默认"
project_type_dop: "DevOps 项目"
project_type_msp: "微服务治理项目"
project_type_msp: "微服务治理项目"
span_count_desc: Span 数量倒序
span_count_asc: Span 数量正序
trace_duration_desc: 追踪持续时间倒序
trace_duration_asc: 追踪持续时间正序
trace_time_desc: 追踪发生时间倒序
trace_time_asc: 追踪发生时间正序
service_name: 服务名
trace_id: 追踪 ID
dubbo_method: Dubbo Method
http_path: HTTP Path
trace_success: 成功
trace_error: 错误
trace_all: 所有
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ require (
github.com/elastic/cloud-on-k8s v0.0.0-20210205172912-5ce0eca90c60
github.com/elazarl/goproxy v0.0.0-20200421181703-e76ad31c14f6
github.com/erda-project/erda-infra v0.0.0-20210817063509-a477b158393d
github.com/erda-project/erda-proto-go v0.0.0-20210805063629-d4e8ac75e06d
github.com/erda-project/erda-proto-go v0.0.0-20210823110307-c397defb820e
github.com/extrame/ole2 v0.0.0-20160812065207-d69429661ad7 // indirect
github.com/extrame/xls v0.0.1
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
Expand Down Expand Up @@ -113,7 +113,7 @@ require (
github.com/shopspring/decimal v1.2.0
github.com/sirupsen/logrus v1.8.1
github.com/sony/sonyflake v1.0.0
github.com/spf13/cobra v1.1.3
github.com/spf13/cobra v1.2.1
github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.1-0.20190625010220-02440ea7a285
github.com/t-tiger/gorm-bulk-insert v1.3.0
Expand Down
83 changes: 74 additions & 9 deletions go.sum

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions modules/monitor/apm/topology/topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,10 @@ func queryConditions(indexType string, params Vo) *elastic.BoolQuery {
sbq.Should(elastic.NewTermQuery(apm.TagsApplicationName, value)).
Should(elastic.NewTermQuery(apm.TagsTargetApplicationName, value)).
Should(elastic.NewTermQuery(apm.TagsSourceApplicationName, value))
case ServiceSearchTag.Tag:
sbq.Should(elastic.NewTermQuery(apm.TagsServiceName, value)).
Should(elastic.NewTermQuery(apm.TagsTargetServiceName, value)).
Should(elastic.NewTermQuery(apm.TagsSourceServiceName, value))
}
}
boolQuery.Filter(sbq)
Expand Down
24 changes: 24 additions & 0 deletions modules/monitor/apm/topology/topology_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,27 @@ func Test_getDashboardId(t *testing.T) {
})
}
}

func Test_queryConditions(t *testing.T) {
type args struct {
indexType string
params Vo
}
tests := []struct {
name string
args args
want bool
}{
{"case1", args{indexType: MQDBCacheIndexType, params: Vo{Tags: []string{"service:apm-demo-api"}}}, false},
{"case1", args{indexType: HttpRecMircoIndexType, params: Vo{Tags: []string{"application:apm-demo"}}}, false},
{"case1", args{indexType: ServiceNodeIndexType, params: Vo{Tags: nil}}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := queryConditions(tt.args.indexType, tt.args.params)
if got == nil {
t.Errorf("queryConditions() = %v, want %v", got, tt.want)
}
})
}
}
19 changes: 19 additions & 0 deletions modules/msp/apm/trace/core/common/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2021 Terminus, 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package common

const Layout = "2006-01-02 15:04:05"

type Void struct{}
24 changes: 24 additions & 0 deletions modules/msp/apm/trace/core/debug/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2021 Terminus, 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package debug

type Status int32

const (
Init Status = 0
Success Status = 1
Fail Status = 2
Stop Status = 3
)
89 changes: 89 additions & 0 deletions modules/msp/apm/trace/core/query/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright (c) 2021 Terminus, 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package query

import (
"encoding/json"
"strings"

"github.com/erda-project/erda-infra/providers/i18n"
"github.com/erda-project/erda-proto-go/msp/apm/trace/pb"
)

type SpanTree map[string]*pb.Span
type ConditionType string

const (
INPUT ConditionType = "input"
)

var sortConditions = []*pb.TraceQueryCondition{
{Key: strings.ToLower(pb.SortCondition_TRACE_TIME_DESC.String()), Value: strings.ToLower(pb.SortCondition_TRACE_TIME_DESC.String())},
{Key: strings.ToLower(pb.SortCondition_TRACE_TIME_ASC.String()), Value: strings.ToLower(pb.SortCondition_TRACE_TIME_ASC.String())},
{Key: strings.ToLower(pb.SortCondition_SPAN_COUNT_DESC.String()), Value: strings.ToLower(pb.SortCondition_SPAN_COUNT_DESC.String())},
{Key: strings.ToLower(pb.SortCondition_SPAN_COUNT_ASC.String()), Value: strings.ToLower(pb.SortCondition_SPAN_COUNT_ASC.String())},
{Key: strings.ToLower(pb.SortCondition_TRACE_DURATION_DESC.String()), Value: strings.ToLower(pb.SortCondition_TRACE_DURATION_DESC.String())},
{Key: strings.ToLower(pb.SortCondition_TRACE_DURATION_ASC.String()), Value: strings.ToLower(pb.SortCondition_TRACE_DURATION_ASC.String())},
}

var limitConditions = []*pb.TraceQueryCondition{
{Key: strings.ToLower(pb.LimitCondition_NUMBER_100.String()), Value: "100", DisplayName: "100"},
{Key: strings.ToLower(pb.LimitCondition_NUMBER_200.String()), Value: "200", DisplayName: "200"},
{Key: strings.ToLower(pb.LimitCondition_NUMBER_500.String()), Value: "500", DisplayName: "500"},
{Key: strings.ToLower(pb.LimitCondition_NUMBER_1000.String()), Value: "1000", DisplayName: "1000"},
}

var TraceStatusConditions = []*pb.TraceQueryCondition{
{Key: strings.ToLower(pb.TraceStatusCondition_TRACE_ALL.String()), Value: strings.ToLower(pb.TraceStatusCondition_TRACE_ALL.String())},
{Key: strings.ToLower(pb.TraceStatusCondition_TRACE_SUCCESS.String()), Value: strings.ToLower(pb.TraceStatusCondition_TRACE_SUCCESS.String())},
{Key: strings.ToLower(pb.TraceStatusCondition_TRACE_ERROR.String()), Value: strings.ToLower(pb.TraceStatusCondition_TRACE_ERROR.String())},
}

var TraceQueryConditions = pb.TraceQueryConditions{
Sort: sortConditions,
Limit: limitConditions,
TraceStatus: TraceStatusConditions,
Others: []*pb.OtherTraceQueryCondition{
{Key: strings.ToLower(pb.OtherCondition_SERVICE_NAME.String()), ParamKey: "serviceName", Type: string(INPUT)},
{Key: strings.ToLower(pb.OtherCondition_TRACE_ID.String()), ParamKey: "traceID", Type: string(INPUT)},
{Key: strings.ToLower(pb.OtherCondition_DUBBO_METHOD.String()), ParamKey: "dubboMethod", Type: string(INPUT)},
{Key: strings.ToLower(pb.OtherCondition_HTTP_PATH.String()), ParamKey: "httpPath", Type: string(INPUT)},
},
}

func TranslateCondition(i18n i18n.Translator, lang i18n.LanguageCodes, key string) string {
if lang == nil {
return key
}
return i18n.Text(lang, strings.ToLower(key))
}

func DepthCopyQueryConditions() *pb.TraceQueryConditions {
conditions, err := clone(&TraceQueryConditions)
if err != nil {
return nil
}
return conditions
}

func clone(src *pb.TraceQueryConditions) (*pb.TraceQueryConditions, error) {
var dst pb.TraceQueryConditions
buffer, _ := json.Marshal(&src)
err := json.Unmarshal(buffer, &dst)
if err != nil {
return nil, err
}
return &dst, nil
}
132 changes: 132 additions & 0 deletions modules/msp/apm/trace/core/query/query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright (c) 2021 Terminus, 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package query

import (
"fmt"
"reflect"
"testing"

"github.com/erda-project/erda-infra/providers/i18n"
"github.com/erda-project/erda-proto-go/msp/apm/trace/pb"
)

func TestDepthCopyQueryConditions(t *testing.T) {
tests := []struct {
name string
want *pb.TraceQueryConditions
}{
{"case1", &TraceQueryConditions},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := DepthCopyQueryConditions()
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("DepthCopyQueryConditions() = %v, want %v", got, tt.want)
}
// got point
gotPoint := getMemoryPoint(got)
gotPointOthers := getMemoryPoint(got.Others)
gotPointLimit := getMemoryPoint(got.Limit)
gotPointSort := getMemoryPoint(got.Sort)
gotPointTraceStatus := getMemoryPoint(got.TraceStatus)

// TraceQueryConditions point
wantPoint := getMemoryPoint(tt.want)
wantPointOthers := getMemoryPoint(tt.want.Others)
wantPointLimit := getMemoryPoint(tt.want.Limit)
wantPointSort := getMemoryPoint(tt.want.Sort)
wantPointTraceStatus := getMemoryPoint(tt.want.TraceStatus)

if gotPoint == wantPoint {
t.Errorf("gotPointServiceName = %v, wantPointServiceName %v", gotPoint, wantPoint)
}
if gotPointOthers == wantPointOthers {
t.Errorf("gotPointOthers = %v, wantPointOthers %v", gotPointOthers, wantPointOthers)
}
if gotPointLimit == wantPointLimit {
t.Errorf("gotPointServiceName = %v, wantPointServiceName %v", gotPointLimit, wantPointLimit)
}
if gotPointSort == wantPointSort {
t.Errorf("gotPointServiceName = %v, wantPointServiceName %v", gotPointSort, wantPointSort)
}
if gotPointTraceStatus == wantPointTraceStatus {
t.Errorf("gotPointServiceName = %v, wantPointServiceName %v", gotPointTraceStatus, wantPointTraceStatus)
}
})
}
}

func getMemoryPoint(need interface{}) string {
return fmt.Sprintf("%p", need)
}

func Test_clone(t *testing.T) {
type args struct {
src *pb.TraceQueryConditions
}
tests := []struct {
name string
args args
want *pb.TraceQueryConditions
wantErr bool
}{
{"case1", args{src: &TraceQueryConditions}, &TraceQueryConditions, false},
{"case2", args{src: nil}, &TraceQueryConditions, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := clone(tt.args.src)
if (err != nil) != tt.wantErr {
t.Errorf("clone() error = %v, wantErr %v", err, tt.wantErr)
return
}
if err != nil {
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("clone() got = %v, want %v", got, tt.want)
}
gotPoint := getMemoryPoint(got)
wantPoint := getMemoryPoint(tt.want)
if gotPoint == wantPoint {
t.Errorf("gotPointServiceName = %v, wantPointServiceName %v", gotPoint, wantPoint)
}
})
}
}

func TestTranslateCondition(t *testing.T) {
type args struct {
i18n i18n.Translator
lang i18n.LanguageCodes
key string
}
i18n := new(i18n.Translator)
tests := []struct {
name string
args args
want string
}{
{"case1", args{i18n: *i18n, lang: nil, key: "test"}, "test"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := TranslateCondition(tt.args.i18n, tt.args.lang, tt.args.key); got != tt.want {
t.Errorf("TranslateCondition() = %v, want %v", got, tt.want)
}
})
}
}
1 change: 1 addition & 0 deletions modules/msp/apm/trace/db/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const (

type TraceRequestHistory struct {
RequestId string `gorm:"column:request_id" db:"request_id" json:"request_id" form:"request_id"`
Name string `gorm:"column:name" db:"name" json:"name" form:"name"`
TerminusKey string `gorm:"column:terminus_key" db:"terminus_key" json:"terminus_key" form:"terminus_key"`
Url string `gorm:"column:url" db:"url" json:"url" form:"url"`
QueryString string `gorm:"column:query_string" db:"query_string" json:"query_string" form:"query_string"`
Expand Down
Loading

0 comments on commit 8d486f5

Please sign in to comment.