Skip to content

Commit

Permalink
新增:数据库的链路追踪
Browse files Browse the repository at this point in the history
  • Loading branch information
steden committed Oct 16, 2023
1 parent 6986715 commit 979b461
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 13 deletions.
88 changes: 77 additions & 11 deletions TrackContext.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
package linkTrace

import (
"fmt"
"github.com/farseer-go/collections"
"github.com/farseer-go/fs"
"github.com/farseer-go/fs/flog"
"github.com/farseer-go/fs/parse"
"github.com/farseer-go/fs/snowflake"
"github.com/farseer-go/linkTrace/eumCallType"
"github.com/farseer-go/linkTrace/eumLinkType"
"github.com/farseer-go/queue"
"strings"
"time"
)

type TraceContext struct {
TraceId int64 `es:"primaryKey"` // 上下文ID
AppId int64 // 应用ID
AppName string // 应用名称
AppIp string // 应用IP
ParentAppName string // 上游应用
TraceId int64 // 上下文ID
StartTs int64 // 调用开始时间戳
EndTs int64 // 调用结束时间戳
UseTs time.Duration // 总共使用时间毫秒
LinkType eumLinkType.Enum // 状态码
Domain string // 请求域名
Path string // 请求地址
Path string `es_type:"text"` // 请求地址
Method string // 请求方式
ContentType string // 请求内容类型
StatusCode int // 状态码
Headers collections.Dictionary[string, string] // 请求头部
RequestBody string // 请求参数
ResponseBody string // 输出参数
Headers collections.Dictionary[string, string] `es_type:"flattened"` // 请求头部
RequestBody string `es_type:"text"` // 请求参数
ResponseBody string `es_type:"text"` // 输出参数
RequestIp string // 客户端IP
List collections.List[LinkTraceDetail] // 调用的上下文
ExceptionDetail ExceptionDetail // 是否执行异常
List collections.List[TraceDetail] `es_type:"object"` // 调用的上下文
ExceptionDetail ExceptionDetail `es_type:"object"` // 是否执行异常
}

func NewWebApi(domain string, path string, method string, contentType string, headerDictionary collections.ReadonlyDictionary[string, string], requestBody string, requestIp string) *TraceContext {
func TraceWebApi(domain string, path string, method string, contentType string, headerDictionary collections.ReadonlyDictionary[string, string], requestBody string, requestIp string) *TraceContext {
traceId := parse.ToInt64(headerDictionary.GetValue("TraceId"))
if traceId == 0 {
traceId = snowflake.GenerateId()
}
return &TraceContext{
AppId: fs.AppId,
AppName: fs.AppName,
AppIp: fs.AppIp,
ParentAppName: headerDictionary.GetValue("AppName"),
TraceId: traceId,
StartTs: time.Now().UnixMicro(),
Expand All @@ -46,23 +57,78 @@ func NewWebApi(domain string, path string, method string, contentType string, he
Headers: headerDictionary.ToDictionary(),
RequestBody: requestBody,
RequestIp: requestIp,
//List: collections.List[LinkTraceDetail]{},
List: collections.NewList[TraceDetail](),
//ExceptionDetail: ExceptionDetail{},
}
}

func TraceDatabase(dbName, tableName string, sql string) {
if defConfig.Enable {
trace := GetCurTrace()
if trace != nil {
trace.List.Add(TraceDetail{
CallType: eumCallType.Database,
Data: map[string]any{
"DbName": dbName,
"TableName": tableName,
"Sql": sql,
},
CallStackTrace: CallStackTrace{},
CallMethod: "",
StartTs: 0,
EndTs: 0,
IsException: false,
ExceptionMessage: "",
})
}
}
}

// End 结束当前链路
func (receiver *TraceContext) End() {
receiver.EndTs = time.Now().UnixMicro()
receiver.UseTs = time.Duration(receiver.EndTs-receiver.StartTs) * time.Microsecond

// 启用了链路追踪后,把数据写入到本地队列中
if Enable {
if defConfig.Enable {
queue.Push("TraceContext", receiver)
}

// 打印日志
if defConfig.PrintLog {
lst := collections.NewList[string]()
receiver.List.For(func(index int, item *TraceDetail) {
switch item.CallType {
case eumCallType.Database:
tableName := parse.ToString(item.Data["TableName"])
sql := flog.ReplaceBlues(parse.ToString(item.Data["Sql"]), "SELECT ", "UPDATE ", "DELETE ", " FROM ", " WHERE ", " LIMIT ", " SET ", " ORDER BY ", " and ", " or ")
sql = strings.ReplaceAll(sql, tableName, flog.Red(tableName))
lst.Add(fmt.Sprintf("%s:[%s] %s", flog.Blue(index+1), flog.Yellow(item.CallType.ToString()), sql))
}
})
flog.Printf("【链路追踪】TraceId:%s,耗时:%s,%s,详情如下:\n%s\n", flog.Green(parse.ToString(receiver.TraceId)), flog.Red(receiver.UseTs.String()), receiver.Path, strings.Join(lst.ToArray(), "\n"))
fmt.Println("-----------------------------------------------------------------")
}
}

// TraceDetail 埋点明细
type TraceDetail struct {
CallStackTrace CallStackTrace // 调用栈
CallMethod string // 调用方法
CallType eumCallType.Enum // 调用类型
Data map[string]any // 埋点数据
StartTs int64 // 调用开始时间戳
EndTs int64 // 调用停止时间戳
IsException bool // 是否执行异常
ExceptionMessage string // 异常信息
}

type LinkTraceDetail struct {
type CallStackTrace struct {
CallMethod string // 调用方法
FileName string // 执行文件名称
FileLineNumber int // 方法执行行数
ReturnType string // 方法返回类型
MethodParams map[string]string // 方法入参
}

type ExceptionDetail struct {
Expand Down
6 changes: 6 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package linkTrace

type config struct {
Enable bool
PrintLog bool
}
38 changes: 38 additions & 0 deletions eumCallType/enum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package eumCallType

type Enum int

const (
HttpClient Enum = iota // HttpClient
GrpcClient // GrpcClient
Database // Database
Redis // Redis
Mq // Mq
Elasticsearch // Elasticsearch
Custom // Custom
KeyLocation // KeyLocation
)

func (receiver Enum) ToString() string {
switch receiver {
case HttpClient:
return "HttpClient"
case GrpcClient:
return "GrpcClient"
case Database:
return "Database"
case Redis:
return "Redis"
case Mq:
return "Mq"
case Elasticsearch:
return "Elasticsearch"
return "Mq"
case Custom:
return "Custom"
return "Mq"
case KeyLocation:
return "KeyLocation"
}
return ""
}
4 changes: 2 additions & 2 deletions module.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

// Enable 是否启用
var Enable bool
var defConfig config

type Module struct {
}
Expand All @@ -18,7 +18,7 @@ func (module Module) DependsModule() []modules.FarseerModule {
}

func (module Module) PreInitialize() {
Enable = configure.GetBool("LinkTrace.Enable")
defConfig = configure.ParseConfig[config]("LinkTrace")
}

func (module Module) PostInitialize() {
Expand Down

0 comments on commit 979b461

Please sign in to comment.