apm_exporter.go 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178
  1. package otlptrace
  2. import (
  3. "crypto/md5"
  4. "encoding/json"
  5. "fmt"
  6. . "github.com/coroot/coroot-node-agent/ebpftracer"
  7. "github.com/coroot/coroot-node-agent/ebpftracer/l7"
  8. "github.com/coroot/coroot-node-agent/utils"
  9. klog "github.com/sirupsen/logrus"
  10. "math"
  11. "net/url"
  12. "sort"
  13. "strconv"
  14. "sync"
  15. "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform"
  16. tracesdk "go.opentelemetry.io/otel/sdk/trace"
  17. tracepb "go.opentelemetry.io/proto/otlp/trace/v1"
  18. )
  19. const (
  20. APP_SERVICE_TYPE = "APPLICATION"
  21. SQL_SERVICE_TYPE = "SQL"
  22. NOSQL_SERVICE_TYPE = "NOSQL"
  23. HTTP_SERVICE_TYPE = "HTTP"
  24. NET_SERVICE_TYPE = "L7_NET"
  25. RPC_SERVICE_TYPE = "RPC"
  26. )
  27. const (
  28. GO_SERVICE_NAME = "GO"
  29. MYSQL_SERVICE_NAME = "MYSQL"
  30. DM_SERVICE_NAME = "DM"
  31. REDIS_SERVICE_NAME = "REDIS"
  32. MONGO_SERVICE_NAME = "MONGODB"
  33. HTTP_SERVICE_NAME = "HTTPCLIENT"
  34. POSTGRESQL_SERVICE_NAME = "POSTGRESQL"
  35. GRPC_SERVICE_NAME = "GRPC"
  36. )
  37. type apmTraceSpan tracesdk.ReadOnlySpan
  38. // GO:0:10154813500555812:5450531005555981:5610250100539899:ee022542c3940f1b:1001025098564810:888ceb3df1bdbe2c:110
  39. type RootDataT struct {
  40. AccountId int `json:"account_id"`
  41. AgentId int64 `json:"agent_id"`
  42. AgentVersion string `json:"agent_version"`
  43. AppId int64 `json:"app_id"`
  44. AppIdFrom int64 `json:"app_id_from"` // from header app_id
  45. AppName string `json:"app_name"`
  46. CalledId int64 `json:"called_id"` // from header assumed_app_id
  47. ClientIp string `json:"client_ip"`
  48. CollTime uint64 `json:"coll_time"`
  49. Cpu int `json:"cpu"`
  50. Custom string `json:"custom"`
  51. HostId int64 `json:"host_id"`
  52. HostName string `json:"host_name"`
  53. HttpCode int64 `json:"http_code"`
  54. HttpMethod string `json:"http_method"`
  55. InstanceId int64 `json:"instance_id"`
  56. InstanceIdFrom int64 `json:"instance_id_from"` // from header instance_id
  57. LocalPort int64 `json:"local_port"`
  58. Maps []MapInfoT `json:"maps"`
  59. MemU int `json:"mem_u"`
  60. MemUP int `json:"mem_u_p"`
  61. OperType string `json:"oper_type"`
  62. Parameters []ParamStruct `json:"parameters,omitempty"`
  63. ParentTaskName int `json:"parent_task_name"`
  64. Period int `json:"period"`
  65. RespTime uint64 `json:"resp_time"`
  66. Sampling int `json:"sampling"`
  67. ServiceName string `json:"service_name"`
  68. ServiceType string `json:"service_type"`
  69. Sip string `json:"sip"`
  70. Sn string `json:"sn"`
  71. SpanIdFrom string `json:"span_id_from"` // from header span_id
  72. Sport int64 `json:"sport"`
  73. TId int `json:"t_id"`
  74. TName string `json:"t_name"`
  75. TraceId string `json:"trace_id"` // from header trace_id
  76. TransIds []interface{} `json:"trans_ids"`
  77. TypeFrom string `json:"type_from"`
  78. Uri string `json:"uri"`
  79. UserDir int `json:"user_dir"`
  80. VipIds []interface{} `json:"vip_ids"`
  81. SrcAddr string `json:"src_addr"`
  82. DestinationAddr string `json:"destination_addr"`
  83. }
  84. // ParamStruct 定义目标结构
  85. type ParamStruct struct {
  86. Name string `json:"name"`
  87. Values []string `json:"values"`
  88. }
  89. type MapInfoT struct {
  90. Dbn string `json:"dbn,omitempty"`
  91. Exception int `json:"exception,omitempty"`
  92. ExceptionMsg string `json:"exception_msg,omitempty"`
  93. ExceptionStack string `json:"exception_stack,omitempty"`
  94. Ip string `json:"ip,omitempty"`
  95. Level int `json:"level"`
  96. MethodDesc string `json:"method_desc,omitempty"`
  97. MethodName string `json:"method_name"`
  98. Nid int `json:"nid"`
  99. OperType string `json:"oper_type,omitempty"`
  100. Pid int `json:"pid"`
  101. Port int64 `json:"port,omitempty"`
  102. Ps []string `json:"ps,omitempty"`
  103. PureTime uint64 `json:"pure_time"`
  104. ServiceName string `json:"service_name"`
  105. ServiceType string `json:"service_type"`
  106. StartTime uint64 `json:"-"`
  107. EndTime uint64 `json:"-"`
  108. StartTimeMs uint64 `json:"start_time"`
  109. EndTimeMs uint64 `json:"end_time"`
  110. WallTime uint64 `json:"wall_time"`
  111. Schema string `json:"schema,omitempty"`
  112. AssumedAppId int64 `json:"assumed_app_id,omitempty"`
  113. Uri string `json:"uri,omitempty"`
  114. SpanId string `json:"span_id,omitempty"`
  115. SrcAddr string `json:"src_addr,omitempty"`
  116. DestinationAddr string `json:"destination_addr,omitempty"`
  117. }
  118. type TraceMapT struct {
  119. RootData RootDataT
  120. Index int
  121. lock *sync.RWMutex
  122. TheEnd bool
  123. }
  124. var TraceRootMap map[string]*TraceMapT
  125. func init() {
  126. TraceRootMap = make(map[string]*TraceMapT)
  127. //go func() {
  128. // for {
  129. // //fmt.Println(G_sdl)
  130. // time.Sleep(5 * time.Second)
  131. // }
  132. //}()
  133. }
  134. var G_sdl int
  135. func tracetransformData(sdl []tracesdk.ReadOnlySpan) map[int][]RootDataT {
  136. //G_sdl += len(sdl)
  137. if len(sdl) == 0 {
  138. return nil
  139. }
  140. // 多次请求 sdl
  141. sendDataMap := make(map[int][]RootDataT)
  142. //sendData := []RootDataT{}
  143. for _, sd := range sdl {
  144. if sd == nil {
  145. continue
  146. }
  147. //traceId := sd.SpanContext().TraceID().String()
  148. fmt.Println("------event_num---- "+sd.Name(), "--->", len(sd.Events())) // 一次请求完整数据
  149. // 构建map *RootDataT
  150. var rootData RootDataT
  151. rootData = initRootDataFromEvent()
  152. // build http入口 MapInfoT
  153. code_type := buildAppMapFromEvent(&rootData, sd)
  154. // 构建maps
  155. for _, event := range sd.Events() {
  156. //aaa, _ := json.Marshal(event)
  157. //fmt.Println("event.info", string(aaa))
  158. mNode := buildMapNodeFromEvent(event)
  159. switch EventType(event.EventType) {
  160. // stack
  161. case EventTypeFunEnt:
  162. // l7 event
  163. case EventTypeL7Request:
  164. switch l7.Protocol(event.ProtocolType) {
  165. case l7.ProtocolHTTP:
  166. buildHttpMapFromEvent(&mNode, event)
  167. case l7.ProtocolDNS:
  168. buildDNSMapEvent(&mNode, event)
  169. case l7.ProtocolMysql:
  170. buildSQLMapEvent(&mNode, event)
  171. case l7.ProtocolRedis:
  172. buildRedisMapEvent(&mNode, event)
  173. case l7.ProtocolMongo:
  174. buildMongoMapEvent(&mNode, event)
  175. // dm
  176. case l7.ProtocolDM:
  177. buildSQLMapEvent(&mNode, event)
  178. case l7.ProtocolPostgres:
  179. buildSQLMapEvent(&mNode, event)
  180. case l7.ProtocolGrpc:
  181. buildGrpcMapEvent(&mNode, event)
  182. }
  183. }
  184. rootData.Maps = append(rootData.Maps, mNode)
  185. //fmt.Println(event.Name)
  186. //buildAndAssemblyMapFromEvent(event, rootData)
  187. }
  188. buildLevelFromEvent(&rootData)
  189. sendDataMap[code_type] = append(sendDataMap[code_type], rootData)
  190. //a, _ := json.Marshal(rootData)
  191. //fmt.Println(string(a))
  192. //sendData = append(sendData, rootData)
  193. //if _, ok := TraceRootMap[traceId]; !ok {
  194. //TraceRootMap[traceId] = &TraceMapT{RootData: initRootData(traceId), Index: 1}
  195. //}
  196. //TraceRootMap[traceId].Index++
  197. //buildAndAssemblyMap(sd, TraceRootMap[traceId])
  198. }
  199. // 发送完整数据 | 大量长耗时请求会增加内存占用
  200. //sendData := []RootDataT{}
  201. //for traceId, v := range TraceRootMap {
  202. // if v.TheEnd {
  203. // buildLevel(v)
  204. // sendData = append(sendData, v.RootData)
  205. // delete(TraceRootMap, traceId)
  206. // //fmt.Println("the end!")
  207. // } else {
  208. // //fmt.Println("not end!")
  209. // }
  210. //}
  211. //Transform the categorized map into a slice
  212. data, _ := json.Marshal(sendDataMap)
  213. klog.Debug(string(data))
  214. //fmt.Println(len(sendData))
  215. //fmt.Println("sdl len:", len(sdl))
  216. return sendDataMap
  217. }
  218. type TimeMap struct {
  219. Time uint64
  220. Type int
  221. Map *MapInfoT
  222. }
  223. //type TraceMapT struct {
  224. // RootData RootDataT
  225. // Index int
  226. // lock *sync.RWMutex
  227. // TheEnd bool
  228. //}
  229. //func buildLevel(sdl *TraceMapT) {
  230. // nidMap := make(map[int]*MapInfoT)
  231. //
  232. // mapSlice := []TimeMap{}
  233. //
  234. // for i, v := range sdl.RootData.Maps {
  235. // if v.ServiceType == "APPLICATION" {
  236. // continue
  237. // }
  238. // nidMap[v.Nid] = &sdl.RootData.Maps[i]
  239. // timeStartMap := TimeMap{
  240. // Time: v.StartTime,
  241. // Type: 0,
  242. // Map: &sdl.RootData.Maps[i],
  243. // }
  244. // mapSlice = append(mapSlice, timeStartMap)
  245. // timeEndMap := TimeMap{
  246. // Time: v.EndTime,
  247. // Type: 1,
  248. // Map: &sdl.RootData.Maps[i],
  249. // }
  250. // mapSlice = append(mapSlice, timeEndMap)
  251. // }
  252. // sort.Slice(mapSlice, func(i, j int) bool {
  253. // return mapSlice[i].Time < mapSlice[j].Time
  254. // })
  255. //
  256. // funStack := []TimeMap{}
  257. //
  258. // currentNid := 1
  259. // Nid := 2
  260. // level := 2
  261. //
  262. // for _, v := range mapSlice {
  263. // // fmt.Println("SliceSliceindex", k, "value", v.Time, v.Type, v.Map.MethodName, v.Map.Nid)
  264. // if v.Type == 0 {
  265. // // 函数入口
  266. // funStack = append(funStack, v)
  267. // v.Map.Pid = currentNid
  268. // v.Map.Level = level
  269. // v.Map.Nid = Nid
  270. // currentNid = Nid
  271. // level += 1
  272. // Nid += 1
  273. // } else if v.Type == 1 {
  274. // // 函数出口
  275. // len := len(funStack)
  276. // funStack = funStack[:len-1]
  277. // if (len - 2) < 0 {
  278. // currentNid = 1
  279. // } else {
  280. // currentNid = funStack[len-2].Map.Nid
  281. // }
  282. //
  283. // level -= 1
  284. // }
  285. // }
  286. //}
  287. func buildLevelFromEvent(sdl *RootDataT) {
  288. nidMap := make(map[int]*MapInfoT)
  289. mapSlice := []TimeMap{}
  290. for i, v := range sdl.Maps {
  291. if v.ServiceType == "APPLICATION" {
  292. continue
  293. }
  294. nidMap[v.Nid] = &sdl.Maps[i]
  295. timeStartMap := TimeMap{
  296. Time: v.StartTime,
  297. Type: 0,
  298. Map: &sdl.Maps[i],
  299. }
  300. mapSlice = append(mapSlice, timeStartMap)
  301. timeEndMap := TimeMap{
  302. Time: v.EndTime,
  303. Type: 1,
  304. Map: &sdl.Maps[i],
  305. }
  306. mapSlice = append(mapSlice, timeEndMap)
  307. }
  308. sort.Slice(mapSlice, func(i, j int) bool {
  309. return mapSlice[i].Time < mapSlice[j].Time
  310. })
  311. funStack := []TimeMap{}
  312. currentNid := 1
  313. Nid := 2
  314. level := 2
  315. for _, v := range mapSlice {
  316. //klog.Debugln("SliceSliceindex", k, "value", v.Time, v.Type, v.Map.MethodName, v.Map.Nid)
  317. if v.Type == 0 {
  318. // 函数入口
  319. funStack = append(funStack, v)
  320. v.Map.Pid = currentNid
  321. v.Map.Level = level
  322. v.Map.Nid = Nid
  323. currentNid = Nid
  324. level += 1
  325. Nid += 1
  326. } else if v.Type == 1 {
  327. // 函数出口
  328. len := len(funStack)
  329. funStack = funStack[:len-1]
  330. if (len - 2) < 0 {
  331. currentNid = 1
  332. } else {
  333. currentNid = funStack[len-2].Map.Nid
  334. }
  335. level -= 1
  336. }
  337. }
  338. }
  339. //func initRootData(traceId string) RootDataT {
  340. // data := RootDataT{
  341. // AccountId: 110,
  342. // AgentId: 1011005252979954, // TODO 更新 基于 ip:port + process_name + exe路径生成
  343. // AgentVersion: "2.1.0",
  344. // AppId: 5410049101545798, // TODO 更新 基于appname生成
  345. // AppIdFrom: -1,
  346. // AppName: "eBPF-agent", // TODO 更新 ip:port || process_name
  347. // CalledId: -1,
  348. // ClientIp: "",
  349. // CollTime: 0,
  350. // Cpu: 0,
  351. // Custom: "",
  352. // HostId: 10154813500555812,
  353. // HostName: "localhost",
  354. // HttpCode: 0,
  355. // HttpMethod: "",
  356. // InstanceId: 1005051101515357, // TODO 更新 基于ip:port
  357. // InstanceIdFrom: -1,
  358. // Maps: []MapInfoT{},
  359. // MemU: 0,
  360. // MemUP: 0,
  361. // OperType: "",
  362. // Parameters: []interface{}{},
  363. // ParentTaskName: 0,
  364. // Period: -1,
  365. // RespTime: 0,
  366. // Sampling: 0,
  367. // ServiceName: "GO",
  368. // ServiceType: APP_SERVICE_TYPE,
  369. // Sip: "",
  370. // Sn: "",
  371. // SpanIdFrom: "",
  372. // Sport: 0,
  373. // TId: -1,
  374. // TName: "",
  375. // TraceId: traceId,
  376. // TransIds: []interface{}{},
  377. // TypeFrom: "",
  378. // Uri: "",
  379. // UserDir: 0,
  380. // VipIds: []interface{}{},
  381. // }
  382. // return data
  383. //}
  384. func initRootDataFromEvent() RootDataT {
  385. hostID := utils.GetHostID()
  386. accountID := utils.GetAccountID()
  387. data := RootDataT{
  388. // todo AccountId
  389. AccountId: accountID,
  390. AgentId: 0, // 基于 ip:port + process_name + exe路径生成
  391. AgentVersion: "2.1.0",
  392. AppId: 0, // 基于appname生成
  393. AppIdFrom: -1,
  394. AppName: "eBPF-agent", // server配置
  395. CalledId: -1,
  396. ClientIp: "",
  397. CollTime: 0,
  398. Cpu: 0,
  399. Custom: "",
  400. HostId: hostID,
  401. HostName: "localhost",
  402. HttpCode: 0,
  403. HttpMethod: "",
  404. InstanceId: 0, // 基于ip:port
  405. InstanceIdFrom: -1,
  406. Maps: []MapInfoT{},
  407. MemU: 0,
  408. MemUP: 0,
  409. OperType: "",
  410. Parameters: []ParamStruct{},
  411. ParentTaskName: 0,
  412. Period: -1,
  413. RespTime: 0,
  414. Sampling: 0,
  415. ServiceName: "",
  416. ServiceType: APP_SERVICE_TYPE,
  417. Sip: "",
  418. Sn: "",
  419. SpanIdFrom: "",
  420. Sport: 0,
  421. TId: -1,
  422. TName: "",
  423. TraceId: "",
  424. TransIds: []interface{}{},
  425. TypeFrom: "",
  426. Uri: "",
  427. UserDir: 0,
  428. VipIds: []interface{}{},
  429. SrcAddr: "",
  430. DestinationAddr: "",
  431. }
  432. return data
  433. }
  434. func initRootDataJava() RootDataT {
  435. data := RootDataT{
  436. AccountId: 110,
  437. AgentId: 3934815089541000, // TODO 更新 基于 ip:port + process_name + exe路径生成
  438. AgentVersion: "2.21.0",
  439. AppId: 3365853273187618, // TODO 更新 基于appname生成
  440. AppIdFrom: -1,
  441. AppName: "eBPF-javaApplication", // TODO 更新 ip:port || process_name
  442. CalledId: -1,
  443. ClientIp: "",
  444. CollTime: 0,
  445. Cpu: 0,
  446. Custom: "",
  447. HostId: 2315065183171055,
  448. HostName: "localhost",
  449. HttpCode: 0,
  450. HttpMethod: "",
  451. InstanceId: 1128864082033413, // TODO 更新 基于ip:port
  452. InstanceIdFrom: -1,
  453. Maps: []MapInfoT{},
  454. MemU: 0,
  455. MemUP: 0,
  456. OperType: "",
  457. Parameters: []ParamStruct{},
  458. ParentTaskName: 0,
  459. Period: -1,
  460. RespTime: 0,
  461. Sampling: 0,
  462. ServiceName: "TOMCAT",
  463. ServiceType: APP_SERVICE_TYPE,
  464. Sip: "",
  465. Sn: "",
  466. SpanIdFrom: "",
  467. Sport: 0,
  468. TId: -1,
  469. TName: "",
  470. TraceId: "",
  471. TransIds: []interface{}{},
  472. TypeFrom: "",
  473. Uri: "",
  474. UserDir: 0,
  475. VipIds: []interface{}{},
  476. }
  477. return data
  478. }
  479. //func initMapNode(spanSd *tracepb.Span) (MapInfoT, string) {
  480. // mNode := MapInfoT{
  481. // Exception: 0,
  482. // ExceptionMsg: "",
  483. // ExceptionStack: "",
  484. // Ip: "",
  485. // Level: 2,
  486. // Pid: 1,
  487. // Port: 0,
  488. // Ps: []string{},
  489. // ServiceName: "",
  490. // ServiceType: "",
  491. // WallTime: 0,
  492. // }
  493. // mNode.MethodName = spanSd.Name
  494. // mNode.PureTime = (spanSd.EndTimeUnixNano - spanSd.StartTimeUnixNano) / 1e3
  495. // mNode.WallTime = mNode.PureTime
  496. // mNode.StartTime = spanSd.StartTimeUnixNano
  497. // mNode.EndTime = spanSd.EndTimeUnixNano
  498. //
  499. // for _, attr := range spanSd.GetAttributes() {
  500. // fmt.Println(attr.Key, ":", attr.Value.GetValue())
  501. //
  502. // switch attr.Key {
  503. // case "nid":
  504. // mNode.Nid = int(attr.Value.GetIntValue())
  505. // case "pid":
  506. // mNode.Pid = int(attr.Value.GetIntValue())
  507. // case "level":
  508. // mNode.Level = int(attr.Value.GetIntValue())
  509. // }
  510. // }
  511. //
  512. // return mNode, spanSd.Name
  513. //}
  514. func buildMapNodeFromEvent(event tracesdk.Event) MapInfoT {
  515. mNode := MapInfoT{
  516. Exception: 0,
  517. ExceptionMsg: "",
  518. ExceptionStack: "",
  519. Ip: "",
  520. Level: 2,
  521. Pid: 1,
  522. Port: 0,
  523. Ps: []string{},
  524. ServiceName: "",
  525. ServiceType: "",
  526. WallTime: 0,
  527. }
  528. mNode.MethodName = event.Name
  529. //mNode.PureTime = (event.EndTimeUnixNano - event.StartTimeUnixNano) / 1e3
  530. //mNode.WallTime = mNode.PureTime
  531. //mNode.StartTime = spanSd.StartTimeUnixNano
  532. //mNode.EndTime = spanSd.EndTimeUnixNano
  533. for _, attr := range event.Attributes {
  534. //fmt.Println(event.Name, "--->buildMapNodeFromEvent--->", attr.Key, ":", attr.Value.AsInterface())
  535. switch attr.Key {
  536. case "nid":
  537. mNode.Nid = int(attr.Value.AsInt64())
  538. case "pid":
  539. mNode.Pid = int(attr.Value.AsInt64())
  540. case "level":
  541. mNode.Level = int(attr.Value.AsInt64())
  542. case "time.start_at":
  543. mNode.StartTime, mNode.StartTimeMs = cleanNsTime(attr.Value.AsInt64())
  544. case "time.end_at":
  545. mNode.EndTime, mNode.EndTimeMs = cleanNsTime(attr.Value.AsInt64())
  546. case "time.duration":
  547. //mNode.PureTime = uint64(attr.Value.AsInt64()) / 1e3
  548. mNode.WallTime = uint64(attr.Value.AsInt64()) / 1e3
  549. }
  550. }
  551. return mNode
  552. }
  553. func parseURIToParams(input string) (string, []ParamStruct, error) {
  554. // 解析输入 URI
  555. parsedURL, err := url.Parse(input)
  556. if err != nil {
  557. return "", nil, fmt.Errorf("failed to parse URI: %w", err)
  558. }
  559. // 提取查询参数
  560. queryParams := parsedURL.Query()
  561. // 转换为目标结构
  562. var params []ParamStruct
  563. for key, values := range queryParams {
  564. params = append(params, ParamStruct{
  565. Name: key,
  566. Values: values,
  567. })
  568. }
  569. return parsedURL.Path, params, nil
  570. }
  571. // 构建拼装
  572. //func buildAndAssemblyMap(sd apmTraceSpan, traceRoot *TraceMapT) MapInfoT {
  573. // mNode, mapType := initMapNode(span(sd))
  574. // switch mapType {
  575. // case "APPLICATION":
  576. // buildAppMap(&mNode, traceRoot, sd)
  577. // traceRoot.TheEnd = true
  578. // case "HTTP":
  579. // buildHttpMap(&mNode, sd)
  580. // case "Mysql":
  581. // buildMysqlMap(&mNode, sd)
  582. // case "Redis":
  583. // buildRedisMap(&mNode, sd)
  584. // }
  585. // if mapType != "" {
  586. // mNode.Nid = traceRoot.Index
  587. // traceRoot.RootData.Maps = append(traceRoot.RootData.Maps, mNode)
  588. // }
  589. // return mNode
  590. //}
  591. //func buildAndAssemblyMapFromEvent(event tracesdk.Event, traceRoot *RootDataT) MapInfoT {
  592. // mNode := buildMapNodeFromEvent(event)
  593. // switch mapType {
  594. // case "HTTP":
  595. // buildHttpMapFromEvent(mNode, event)
  596. // //case "Mysql":
  597. // // buildMysqlMap(mNode, sd)
  598. // //case "Redis":
  599. // // buildRedisMap(mNode, sd)
  600. // }
  601. // if mapType != "" {
  602. // //mNode.Nid = traceRoot.Index
  603. // traceRoot.Maps = append(traceRoot.Maps, mNode)
  604. // }
  605. // return mNode
  606. //}
  607. //func buildAppMap(mNode *MapInfoT, traceRoot *TraceMapT, sd apmTraceSpan) {
  608. // mNode.ServiceName = GO_SERVICE_NAME
  609. // mNode.ServiceType = APP_SERVICE_TYPE
  610. // mNode.MethodName = "net/http.(*Transport).roundTrip()"
  611. // mNode.Level = 1
  612. // mNode.Pid = 0
  613. // mNode.Nid = 1
  614. // // 构建root节点
  615. // traceRoot.RootData.RespTime = mNode.PureTime
  616. // traceRoot.RootData.CollTime = mNode.StartTime
  617. // traceRoot.Index = 1
  618. // for _, attr := range sd.Attributes() {
  619. // fmt.Println(attr.Key, ":", attr.Value.AsInterface())
  620. // switch attr.Key {
  621. // case "http.uri":
  622. // traceRoot.RootData.Uri = attr.Value.AsString()
  623. // case "http.method":
  624. // traceRoot.RootData.HttpMethod = attr.Value.AsString()
  625. // case "http.status_code":
  626. // traceRoot.RootData.HttpCode = attr.Value.AsInt64()
  627. // case "net.peer.name":
  628. // traceRoot.RootData.ClientIp = attr.Value.AsString()
  629. // traceRoot.RootData.Sip = attr.Value.AsString()
  630. // traceRoot.RootData.Sn = attr.Value.AsString()
  631. // case "net.peer.port":
  632. // traceRoot.RootData.Sport = attr.Value.AsInt64()
  633. // traceRoot.RootData.LocalPort = attr.Value.AsInt64()
  634. // case "server.trace_id_from":
  635. // traceRoot.RootData.TraceId = attr.Value.AsString()
  636. // case "server.called_id":
  637. // traceRoot.RootData.CalledId = attr.Value.AsInt64()
  638. // case "server.instance_id_from":
  639. // traceRoot.RootData.InstanceIdFrom = attr.Value.AsInt64()
  640. // case "server.app_id_from":
  641. // traceRoot.RootData.AppIdFrom = attr.Value.AsInt64()
  642. // case "server.span_id_from":
  643. // traceRoot.RootData.SpanIdFrom = attr.Value.AsString()
  644. // case "server.type_from":
  645. // traceRoot.RootData.TypeFrom = attr.Value.AsString()
  646. // }
  647. // }
  648. //
  649. //}
  650. func buildAppMapFromEvent(traceRoot *RootDataT, sd apmTraceSpan) int {
  651. mNode := MapInfoT{
  652. Exception: 0,
  653. ExceptionMsg: "",
  654. ExceptionStack: "",
  655. Ip: "",
  656. Level: 1,
  657. Pid: 1,
  658. Port: 0,
  659. Ps: []string{},
  660. ServiceName: "",
  661. ServiceType: "",
  662. WallTime: 0,
  663. }
  664. mNode.ServiceName = GO_SERVICE_NAME
  665. mNode.ServiceType = APP_SERVICE_TYPE
  666. mNode.MethodName = "Kernel Endpoint()"
  667. mNode.Level = 1
  668. mNode.Pid = 0
  669. mNode.Nid = 1
  670. var code_type int64
  671. // 构建root节点
  672. //traceRoot.RespTime = mNode.PureTimex
  673. //traceRoot.CollTime = mNode.StartTime
  674. for _, attr := range sd.Attributes() {
  675. klog.Debugln("Appmap:", attr.Key, ":", attr.Value.AsInterface())
  676. switch attr.Key {
  677. case "http.uri":
  678. traceRoot.Uri, traceRoot.Parameters, _ = parseURIToParams(attr.Value.AsString())
  679. case "http.method":
  680. traceRoot.HttpMethod = attr.Value.AsString()
  681. case "http.status_code":
  682. traceRoot.HttpCode = attr.Value.AsInt64()
  683. case "net.peer.name":
  684. // TODO 修改 ClientIp sip获取方式
  685. traceRoot.ClientIp = attr.Value.AsString()
  686. traceRoot.Sip = attr.Value.AsString()
  687. traceRoot.Sn = attr.Value.AsString()
  688. case "net.peer.port":
  689. traceRoot.Sport = attr.Value.AsInt64()
  690. traceRoot.LocalPort = attr.Value.AsInt64()
  691. case "server.trace_id_from":
  692. traceRoot.TraceId = attr.Value.AsString()
  693. case "server.called_id":
  694. traceRoot.CalledId = attr.Value.AsInt64()
  695. case "server.instance_id_from":
  696. traceRoot.InstanceIdFrom = attr.Value.AsInt64()
  697. case "server.app_id_from":
  698. traceRoot.AppIdFrom = attr.Value.AsInt64()
  699. case "server.span_id_from":
  700. traceRoot.SpanIdFrom = attr.Value.AsString()
  701. case "server.type_from":
  702. traceRoot.TypeFrom = attr.Value.AsString()
  703. case "time.start_at":
  704. mNode.StartTime, mNode.StartTimeMs = cleanNsTime(attr.Value.AsInt64())
  705. traceRoot.CollTime = mNode.StartTimeMs
  706. case "time.end_at":
  707. mNode.EndTime, mNode.EndTimeMs = cleanNsTime(attr.Value.AsInt64())
  708. case "time.duration":
  709. traceRoot.RespTime = uint64(attr.Value.AsInt64()) / 1e3
  710. mNode.PureTime = traceRoot.RespTime
  711. mNode.WallTime = uint64(attr.Value.AsInt64()) / 1e3
  712. case "server.code_type":
  713. code_type = attr.Value.AsInt64()
  714. case "server.app_name":
  715. traceRoot.AppName = attr.Value.AsString()
  716. case "server.service_name":
  717. traceRoot.ServiceName = attr.Value.AsString()
  718. mNode.ServiceName = attr.Value.AsString()
  719. case "server.app_id":
  720. traceRoot.AppId = attr.Value.AsInt64()
  721. case "server.agent_id":
  722. traceRoot.AgentId = attr.Value.AsInt64()
  723. case "server.instance_id":
  724. traceRoot.InstanceId = attr.Value.AsInt64()
  725. case "server.src_addr":
  726. traceRoot.SrcAddr = attr.Value.AsString()
  727. case "server.dst_addr":
  728. traceRoot.DestinationAddr = attr.Value.AsString()
  729. }
  730. }
  731. traceRoot.Maps = append(traceRoot.Maps, mNode)
  732. return int(code_type)
  733. }
  734. //func buildHttpMap(mNode *MapInfoT, sd apmTraceSpan) {
  735. // mNode.ServiceName = HTTP_SERVICE_NAME
  736. // mNode.ServiceType = HTTP_SERVICE_TYPE
  737. // mNode.Schema = "http"
  738. // mNode.MethodName = "net/http.serverHandler.ServeHTTP()"
  739. // var descAddr string
  740. // for _, attr := range sd.Attributes() {
  741. // //fmt.Println(attr.Key, ":", attr.Value.AsInterface())
  742. // switch attr.Key {
  743. // case "http.ip":
  744. // mNode.Ip = attr.Value.AsString()
  745. // descAddr += mNode.Ip
  746. // case "http.port":
  747. // mNode.Port = attr.Value.AsInt64()
  748. // descAddr += ":" + attr.Value.AsString()
  749. // case "http.uri":
  750. // mNode.Uri = attr.Value.AsString()
  751. // case "http.assumed_app_id":
  752. // mNode.AssumedAppId = attr.Value.AsInt64()
  753. // case "http.span_id":
  754. // mNode.SpanId = attr.Value.AsString()
  755. // }
  756. // }
  757. // //mNode.AssumedAppId = Md5ToInt64(descAddr, 16)
  758. //}
  759. func buildGrpcMapEvent(mNode *MapInfoT, event tracesdk.Event) {
  760. mNode.ServiceName = GRPC_SERVICE_NAME
  761. mNode.ServiceType = RPC_SERVICE_TYPE
  762. mNode.Schema = "grpc"
  763. //mNode.MethodName = "HTTP"
  764. //var descAddr string
  765. // var method string
  766. for _, attr := range event.Attributes {
  767. switch attr.Key {
  768. case "rpc.ip":
  769. mNode.Ip = attr.Value.AsString()
  770. //descAddr += mNode.Ip
  771. case "rpc.port":
  772. mNode.Port = attr.Value.AsInt64()
  773. case "rpc.method":
  774. //mNode.MethodName += " " + attr.Value.AsString()
  775. // method = attr.Value.AsString()
  776. mNode.MethodName = attr.Value.AsString()
  777. //descAddr += ":" + attr.Value.AsString()
  778. case "rpc.uri":
  779. mNode.Uri = attr.Value.AsString()
  780. //mNode.MethodName += " " + attr.Value.AsString()
  781. case "rpc.assumed_app_id":
  782. mNode.AssumedAppId = attr.Value.AsInt64()
  783. case "rpc.span_id":
  784. mNode.SpanId = attr.Value.AsString()
  785. case "time.start_at":
  786. mNode.StartTime = uint64(attr.Value.AsInt64())
  787. case "time.end_at":
  788. mNode.EndTime = uint64(attr.Value.AsInt64())
  789. case "time.duration":
  790. //mNode.PureTime = uint64(attr.Value.AsInt64()) / 1e3
  791. mNode.WallTime = uint64(attr.Value.AsInt64()) / 1e3
  792. }
  793. }
  794. // mNode.MethodName = fmt.Sprintf("%s %s %s:%d%s", "HTTP", method, mNode.Ip, mNode.Port, mNode.Uri)
  795. //mNode.AssumedAppId = Md5ToInt64(descAddr, 16)
  796. }
  797. func buildHttpMapFromEvent(mNode *MapInfoT, event tracesdk.Event) {
  798. mNode.ServiceName = HTTP_SERVICE_NAME
  799. mNode.ServiceType = HTTP_SERVICE_TYPE
  800. mNode.Schema = "http"
  801. //mNode.MethodName = "HTTP"
  802. //var descAddr string
  803. var method string
  804. for _, attr := range event.Attributes {
  805. klog.Debugln("HTTP--->", attr.Key, ":", attr.Value.AsInterface())
  806. switch attr.Key {
  807. case "http.ip":
  808. mNode.Ip = attr.Value.AsString()
  809. //descAddr += mNode.Ip
  810. case "http.port":
  811. mNode.Port = attr.Value.AsInt64()
  812. case "http.method":
  813. //mNode.MethodName += " " + attr.Value.AsString()
  814. method = attr.Value.AsString()
  815. //descAddr += ":" + attr.Value.AsString()
  816. case "http.uri":
  817. mNode.Uri = attr.Value.AsString()
  818. //mNode.MethodName += " " + attr.Value.AsString()
  819. case "http.assumed_app_id":
  820. mNode.AssumedAppId = attr.Value.AsInt64()
  821. case "http.span_id":
  822. mNode.SpanId = attr.Value.AsString()
  823. case "time.start_at":
  824. mNode.StartTime = uint64(attr.Value.AsInt64())
  825. case "time.end_at":
  826. mNode.EndTime = uint64(attr.Value.AsInt64())
  827. case "time.duration":
  828. //mNode.PureTime = uint64(attr.Value.AsInt64()) / 1e3
  829. mNode.WallTime = uint64(attr.Value.AsInt64()) / 1e3
  830. case "http.src_addr":
  831. mNode.SrcAddr = attr.Value.AsString()
  832. case "http.destination_addr":
  833. mNode.DestinationAddr = attr.Value.AsString()
  834. }
  835. }
  836. mNode.MethodName = fmt.Sprintf("%s %s %s:%d%s", "HTTP", method, mNode.Ip, mNode.Port, mNode.Uri)
  837. //mNode.AssumedAppId = Md5ToInt64(descAddr, 16)
  838. }
  839. //func buildMysqlMap(mNode *MapInfoT, sd apmTraceSpan) {
  840. // mNode.Dbn = "unknown"
  841. // mNode.ServiceName = MYSQL_SERVICE_NAME
  842. // mNode.ServiceType = SQL_SERVICE_TYPE
  843. // mNode.MethodName = "database/sql.Query()"
  844. // for _, attr := range sd.Attributes() {
  845. // //fmt.Println(attr.Key, ":", attr.Value.AsInterface())
  846. // switch attr.Key {
  847. // case "net.peer.name":
  848. // mNode.Ip = attr.Value.AsString()
  849. // case "net.peer.port":
  850. // mNode.Port = attr.Value.AsInt64()
  851. // case "db.statement":
  852. // query := attr.Value.AsString()
  853. // mNode.Ps = []string{query}
  854. // words := strings.Fields(query)
  855. // if len(words) > 0 {
  856. // mNode.OperType = strings.ToUpper(words[0])
  857. // }
  858. // }
  859. // }
  860. //}
  861. func buildSQLMapEvent(mNode *MapInfoT, event tracesdk.Event) {
  862. mNode.Dbn = "-"
  863. mNode.ServiceName = l7.Protocol(event.ProtocolType).ServiceNameString()
  864. mNode.ServiceType = SQL_SERVICE_TYPE
  865. //mNode.MethodName = "database/sql.Query()"
  866. for _, attr := range event.Attributes {
  867. //fmt.Println(attr.Key, ":", attr.Value.AsInterface())
  868. switch attr.Key {
  869. case "net.peer.name":
  870. mNode.Ip = attr.Value.AsString()
  871. case "net.peer.port":
  872. mNode.Port = attr.Value.AsInt64()
  873. case "db.statement":
  874. query := attr.Value.AsString()
  875. mNode.MethodName = query
  876. mNode.Ps = []string{query}
  877. //words := strings.Fields(query)
  878. //if len(words) > 0 {
  879. // mNode.OperType = strings.ToUpper(words[0])
  880. //}
  881. case "sql.exception":
  882. if attr.Value.AsBool() {
  883. mNode.Exception = 1
  884. } else {
  885. mNode.Exception = 0
  886. }
  887. case "sql.src_addr":
  888. mNode.SrcAddr = attr.Value.AsString()
  889. case "sql.destination_addr":
  890. mNode.DestinationAddr = attr.Value.AsString()
  891. }
  892. }
  893. }
  894. func buildDNSMapEvent(mNode *MapInfoT, event tracesdk.Event) {
  895. mNode.ServiceName = l7.Protocol(event.ProtocolType).ServiceNameString()
  896. mNode.ServiceType = NET_SERVICE_TYPE
  897. var _type string
  898. var fqdn string
  899. var ips string
  900. var ttl int64
  901. for _, attr := range event.Attributes {
  902. switch attr.Key {
  903. case "dns.type":
  904. _type = attr.Value.AsString()
  905. case "dns.fqdn":
  906. fqdn = attr.Value.AsString()
  907. case "dns.ttl":
  908. ttl = attr.Value.AsInt64()
  909. case "dns.ips":
  910. if attr.Value.AsString() != "" {
  911. ips = "Addr: " + attr.Value.AsString()
  912. }
  913. }
  914. }
  915. mNode.MethodName = fmt.Sprintf("DNS Name: %s Type: %s TTL: %d %s", fqdn, _type, ttl, ips)
  916. }
  917. func buildPostGreSqlMapEvent(mNode *MapInfoT, event tracesdk.Event) {
  918. mNode.Dbn = "-"
  919. mNode.ServiceName = POSTGRESQL_SERVICE_NAME
  920. mNode.ServiceType = SQL_SERVICE_TYPE
  921. //mNode.MethodName = "database/sql.Query()"
  922. for _, attr := range event.Attributes {
  923. //fmt.Println(attr.Key, ":", attr.Value.AsInterface())
  924. switch attr.Key {
  925. case "net.peer.name":
  926. mNode.Ip = attr.Value.AsString()
  927. case "net.peer.port":
  928. mNode.Port = attr.Value.AsInt64()
  929. case "db.statement":
  930. query := attr.Value.AsString()
  931. mNode.Ps = []string{query}
  932. //words := strings.Fields(query)
  933. //if len(words) > 0 {
  934. // mNode.OperType = strings.ToUpper(words[0])
  935. //}
  936. case "sql.exception":
  937. if attr.Value.AsBool() {
  938. mNode.Exception = 1
  939. } else {
  940. mNode.Exception = 0
  941. }
  942. case "sql.src_addr":
  943. mNode.SrcAddr = attr.Value.AsString()
  944. case "sql.destination_addr":
  945. mNode.DestinationAddr = attr.Value.AsString()
  946. }
  947. }
  948. }
  949. func buildMysqlMapEvent(mNode *MapInfoT, event tracesdk.Event) {
  950. mNode.Dbn = "-"
  951. mNode.ServiceName = MYSQL_SERVICE_NAME
  952. mNode.ServiceType = SQL_SERVICE_TYPE
  953. //mNode.MethodName = "database/sql.Query()"
  954. for _, attr := range event.Attributes {
  955. //fmt.Println(attr.Key, ":", attr.Value.AsInterface())
  956. switch attr.Key {
  957. case "net.peer.name":
  958. mNode.Ip = attr.Value.AsString()
  959. case "net.peer.port":
  960. mNode.Port = attr.Value.AsInt64()
  961. case "db.statement":
  962. query := attr.Value.AsString()
  963. mNode.MethodName = query
  964. mNode.Ps = []string{query}
  965. //words := strings.Fields(query)
  966. //if len(words) > 0 {
  967. // mNode.OperType = strings.ToUpper(words[0])
  968. //}
  969. case "sql.exception":
  970. if attr.Value.AsBool() {
  971. mNode.Exception = 1
  972. } else {
  973. mNode.Exception = 0
  974. }
  975. case "sql.src_addr":
  976. mNode.SrcAddr = attr.Value.AsString()
  977. case "sql.destination_addr":
  978. mNode.DestinationAddr = attr.Value.AsString()
  979. }
  980. }
  981. }
  982. func buildDMMapEvent(mNode *MapInfoT, event tracesdk.Event) {
  983. mNode.Dbn = "TEST"
  984. mNode.ServiceName = DM_SERVICE_NAME
  985. mNode.ServiceType = SQL_SERVICE_TYPE
  986. mNode.MethodName = "database/sql.Query()"
  987. for _, attr := range event.Attributes {
  988. //fmt.Println(attr.Key, ":", attr.Value.AsInterface())
  989. switch attr.Key {
  990. case "net.peer.name":
  991. mNode.Ip = attr.Value.AsString()
  992. case "net.peer.port":
  993. mNode.Port = attr.Value.AsInt64()
  994. case "db.statement":
  995. query := attr.Value.AsString()
  996. mNode.Ps = []string{query}
  997. //words := strings.Fields(query)
  998. //if len(words) > 0 {
  999. // mNode.OperType = strings.ToUpper(words[0])
  1000. //}
  1001. case "sql.exception":
  1002. if attr.Value.AsBool() {
  1003. mNode.Exception = 1
  1004. } else {
  1005. mNode.Exception = 0
  1006. }
  1007. case "sql.src_addr":
  1008. mNode.SrcAddr = attr.Value.AsString()
  1009. case "sql.destination_addr":
  1010. mNode.DestinationAddr = attr.Value.AsString()
  1011. }
  1012. }
  1013. }
  1014. func buildRedisMapEvent(mNode *MapInfoT, event tracesdk.Event) {
  1015. mNode.ServiceName = REDIS_SERVICE_NAME
  1016. mNode.ServiceType = NOSQL_SERVICE_TYPE
  1017. //mNode.MethodName = span(sd).Name + " query"
  1018. //mNode.MethodName = "redis.Do()"
  1019. for _, attr := range event.Attributes {
  1020. //fmt.Println(attr.Key, ":", attr.Value.AsInterface())
  1021. switch attr.Key {
  1022. case "net.peer.name":
  1023. mNode.Ip = attr.Value.AsString()
  1024. case "net.peer.port":
  1025. mNode.Port = attr.Value.AsInt64()
  1026. case "db.statement":
  1027. query := attr.Value.AsString()
  1028. mNode.MethodName = query
  1029. mNode.Ps = []string{query}
  1030. //words := strings.Fields(query)
  1031. //if len(words) > 0 {
  1032. // mNode.OperType = strings.ToUpper(words[0])
  1033. //}
  1034. case "nosql.src_addr":
  1035. mNode.SrcAddr = attr.Value.AsString()
  1036. case "nosql.destination_addr":
  1037. mNode.DestinationAddr = attr.Value.AsString()
  1038. }
  1039. }
  1040. }
  1041. func buildMongoMapEvent(mNode *MapInfoT, event tracesdk.Event) {
  1042. mNode.ServiceName = MONGO_SERVICE_NAME
  1043. mNode.ServiceType = NOSQL_SERVICE_TYPE
  1044. for _, attr := range event.Attributes {
  1045. switch attr.Key {
  1046. case "net.peer.name":
  1047. mNode.Ip = attr.Value.AsString()
  1048. case "net.peer.port":
  1049. mNode.Port = attr.Value.AsInt64()
  1050. case "db.statement":
  1051. query := attr.Value.AsString()
  1052. mNode.MethodName = query
  1053. mNode.Ps = []string{query}
  1054. case "nosql.src_addr":
  1055. mNode.SrcAddr = attr.Value.AsString()
  1056. case "nosql.destination_addr":
  1057. mNode.DestinationAddr = attr.Value.AsString()
  1058. }
  1059. }
  1060. }
  1061. func isEnter(_type string) bool {
  1062. if _type == "APPLICATION" {
  1063. return true
  1064. }
  1065. return false
  1066. }
  1067. func span(sd apmTraceSpan) *tracepb.Span {
  1068. if sd == nil {
  1069. return nil
  1070. }
  1071. tid := sd.SpanContext().TraceID()
  1072. sid := sd.SpanContext().SpanID()
  1073. s := &tracepb.Span{
  1074. TraceId: tid[:],
  1075. SpanId: sid[:],
  1076. TraceState: sd.SpanContext().TraceState().String(),
  1077. //Status: status(sd.Status().Code, sd.Status().Description),
  1078. StartTimeUnixNano: uint64(sd.StartTime().UnixNano()),
  1079. EndTimeUnixNano: uint64(sd.EndTime().UnixNano()),
  1080. //Links: links(sd.Links()),
  1081. //Kind: spanKind(sd.SpanKind()),
  1082. Name: sd.Name(),
  1083. Attributes: tracetransform.KeyValues(sd.Attributes()),
  1084. //Events: spanEvents(sd.Events()),
  1085. DroppedAttributesCount: uint32(sd.DroppedAttributes()),
  1086. DroppedEventsCount: uint32(sd.DroppedEvents()),
  1087. DroppedLinksCount: uint32(sd.DroppedLinks()),
  1088. }
  1089. if psid := sd.Parent().SpanID(); psid.IsValid() {
  1090. s.ParentSpanId = psid[:]
  1091. }
  1092. return s
  1093. }
  1094. func Md5ToInt64(strParam string, Len int) int64 {
  1095. sign := md5.Sum([]byte(strParam))
  1096. signStr := fmt.Sprintf("%x", sign)
  1097. charArr := []rune(signStr)
  1098. var intStr string
  1099. for _, value := range charArr {
  1100. intStr += strconv.Itoa(int(value))
  1101. }
  1102. intStr = intStr[:Len]
  1103. int64Data, err := strconv.ParseInt(intStr, 10, 64)
  1104. if err != nil {
  1105. return 0
  1106. }
  1107. return int64Data
  1108. }
  1109. // ns,ms
  1110. func cleanNsTime(time int64) (uint64, uint64) {
  1111. return uint64(time), uint64(math.Round(float64(time) / 1e6))
  1112. }