apm_exporter.go 31 KB

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