skywalking.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package trace
  2. import (
  3. "errors"
  4. "fmt"
  5. "path/filepath"
  6. "runtime"
  7. "sync/atomic"
  8. "time"
  9. "git.shuncheng.lu/bigthing/gocommon/pkg/conf"
  10. "git.shuncheng.lu/bigthing/gocommon/pkg/internal/util"
  11. "github.com/SkyAPM/go2sky"
  12. "github.com/SkyAPM/go2sky/reporter"
  13. )
  14. var (
  15. //skyWalkingTracer *go2sky.Tracer
  16. // 防止并发 race问题
  17. skyWalkingTracer atomic.Value
  18. )
  19. const (
  20. MysqlComponentID int32 = 5
  21. HttpClientComponentID int32 = 2
  22. HttpServerComponentID int32 = 49
  23. )
  24. /**
  25. main方法手动调用
  26. */
  27. func Init() error {
  28. healthInit()
  29. return nil
  30. }
  31. func loadTracer() {
  32. // 防止不必要的错误
  33. defer func() {
  34. if err := recover(); err != nil {
  35. fmt.Printf("\033[31m[ERROR]\033[0m init skywaling panic, err=%v\n", err)
  36. }
  37. }()
  38. walkingTracer, err := newSkyWalkingTracer()
  39. if err != nil {
  40. fmt.Printf("\033[31m[ERROR]\033[0m init skywaling err, err=%v\n", err.Error())
  41. return
  42. }
  43. fmt.Printf("\033[32m[INFO]\033[0m init skywaling success\n")
  44. skyWalkingTracer.Store(walkingTracer)
  45. }
  46. func GetSkyWalkingTracer() *go2sky.Tracer {
  47. tracer, _ := skyWalkingTracer.Load().(*go2sky.Tracer)
  48. return tracer
  49. }
  50. func getConfig(section, key string, defaultValue ...string) string {
  51. return conf.GetString(section, key, defaultValue...)
  52. }
  53. /**
  54. 创建 tracer
  55. */
  56. func newSkyWalkingTracer() (*go2sky.Tracer, error) {
  57. serverAddr := getConfig("trace", "sky_walking_host", "")
  58. if serverAddr == "" {
  59. return nil, errors.New("trace.sky_walking_host config not found")
  60. }
  61. serverName := getConfig("trace", "application_name", "")
  62. if serverName == "" {
  63. return nil, errors.New("trace.application_name config not found")
  64. }
  65. /**
  66. 这里就算连接异常,也不会抛出error,因为grcp默认是后台不断重新连接
  67. */
  68. r, err := reporter.NewGRPCReporter(serverAddr)
  69. if err != nil {
  70. return nil, err
  71. }
  72. currentServerHostName := util.CurrentServerHostName()
  73. tracer, err := go2sky.NewTracer(serverName, go2sky.WithReporter(r), go2sky.WithInstance(currentServerHostName))
  74. if err != nil {
  75. defer func() {
  76. r.Close() // 防止泄漏连接
  77. }()
  78. return nil, err
  79. }
  80. fmt.Printf("\033[32m[INFO]\033[0m init skywalking, skywalking_host=%s, application_name=%s\n", serverAddr, serverName)
  81. return tracer, nil
  82. }
  83. /**
  84. 获取 调用 的 方法.line
  85. */
  86. func GetCallLine(num int) string {
  87. pc, file, line, ok := runtime.Caller(num)
  88. if !ok {
  89. return ""
  90. }
  91. pcName := runtime.FuncForPC(pc).Name()
  92. file, _ = filepath.Abs(file)
  93. return fmt.Sprintf("[%s.%d] ", pcName, line)
  94. }
  95. /**
  96. 健康启动
  97. 1、启动成功继续
  98. 2、启动失败,定期1分钟重新连接
  99. */
  100. func healthInit() {
  101. // 初始化一次
  102. loadTracer()
  103. // 如果为空,则定期去连接
  104. if GetSkyWalkingTracer() == nil {
  105. go func() {
  106. retryTime := func() time.Duration {
  107. return time.Second * 60
  108. }
  109. retry := time.NewTimer(retryTime())
  110. for {
  111. <-retry.C
  112. loadTracer() // 初始化
  113. if GetSkyWalkingTracer() != nil {
  114. retry.Stop()
  115. break
  116. }
  117. retry.Reset(retryTime())
  118. }
  119. }()
  120. }
  121. }