trace/runtime.go
2025-04-12 17:53:07 +08:00

151 lines
3.3 KiB
Go

// Package trace ...
//
// Description : trace ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2022-10-14 23:25
package trace
import (
"sync"
"time"
"git.zhangdeman.cn/zhangdeman/wrapper"
)
// NewRuntime 获取runtime实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 23:26 2022/10/14
func NewRuntime(traceID string, stackOffset int) *Runtime {
if len(traceID) == 0 {
// 若不指定 trace id , 随机生成
traceID = wrapper.StringFromRandom(32, "").Md5().Value
}
if stackOffset < 0 {
stackOffset = 0
}
return &Runtime{
lock: &sync.RWMutex{},
traceID: traceID,
behaviorList: make([]Behavior, 0),
stackOffset: stackOffset,
}
}
// Runtime ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 23:32 2022/10/14
type Runtime struct {
lock *sync.RWMutex // 锁
traceID string // 日志追踪ID
behaviorList []Behavior // 行为列表
stackOffset int // 堆栈回溯层级
}
// StartBehavior 开始一个行为
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 23:41 2022/10/14
func (r *Runtime) StartBehavior(action string, data map[string]any) *Behavior {
if nil == data {
data = make(map[string]any)
}
r.lock.Lock()
defer r.lock.Unlock()
b := Behavior{
ID: len(r.behaviorList),
Stack: GetTraceFileInfo(r.stackOffset),
Action: action,
Type: BehaviorActionTypeStart,
Timestamp: time.Now().UnixNano(),
Data: data,
}
r.behaviorList = append(r.behaviorList, b)
return &b
}
// FinishBehavior 结束某一个行为
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 23:53 2022/10/14
func (r *Runtime) FinishBehavior(b *Behavior, data map[string]any) {
if nil == data {
data = make(map[string]any)
}
r.lock.Lock()
defer r.lock.Unlock()
finishTimestamp := time.Now().UnixNano()
fb := Behavior{
ID: len(r.behaviorList),
StartBehaviorID: b.StartBehaviorID,
Stack: GetTraceFileInfo(r.stackOffset),
Action: b.Action,
Type: BehaviorActionTypeFinish,
Timestamp: finishTimestamp,
CostNano: finishTimestamp - b.Timestamp,
CostMs: (finishTimestamp - b.Timestamp) / 1e6,
Data: data,
}
r.behaviorList = append(r.behaviorList, fb)
}
// WrapRun ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 00:17 2022/10/15
func (r *Runtime) WrapRun(action string, startData map[string]any, logic LogicFunc) error {
if nil == logic {
return nil
}
var (
err error
)
b := r.StartBehavior(action, startData)
// 执行逻辑
err = logic()
finishData := map[string]any{}
if nil != err {
finishData["error"] = err.Error()
finishData["success"] = false
} else {
finishData["success"] = true
finishData["error"] = "success"
}
r.FinishBehavior(b, finishData)
return err
}
// GetTraceID 获取 trace id
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 00:28 2022/10/15
func (r *Runtime) GetTraceID() string {
return r.traceID
}
// GetBehaviorList 获取行为列表
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 00:29 2022/10/15
func (r *Runtime) GetBehaviorList() []Behavior {
r.lock.RLock()
defer r.lock.RUnlock()
behaviorList := make([]Behavior, 0)
for _, item := range r.behaviorList {
behaviorList = append(behaviorList, item)
}
return behaviorList
}