apm_fusing.go 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package containers
  2. import (
  3. "fmt"
  4. "github.com/coroot/coroot-node-agent/flags"
  5. log "github.com/sirupsen/logrus"
  6. "os"
  7. "time"
  8. )
  9. func (r *Registry) DoFusing() error {
  10. log.Infof("-----DoFusing will to execute fuse operates -----\n")
  11. var (
  12. lastErr error
  13. err error
  14. )
  15. //先处于熔断状态 (应用层的uprobes\stackUprobes将进行Detach操作)
  16. r.isFusing = true
  17. for tryLeft := *flags.FuseTryMax; tryLeft > 0; tryLeft-- {
  18. lastErr = nil
  19. //再停止数据发送
  20. if err = os.Setenv("SEND", ""); err != nil {
  21. lastErr = fmt.Errorf("failed to set SEND env: %w", err)
  22. log.Warnf("DoFusing,FuseTryMax[%d],tryLeft[%d] set SEND env occurs error:%s", *flags.FuseTryMax, tryLeft-1, err.Error())
  23. } else {
  24. log.Infof("DoFusing,FuseTryMax[%d],tryLeft[%d] set SEND env OK", *flags.FuseTryMax, tryLeft-1)
  25. }
  26. //最后关闭内核层的tracepoint、kprobe
  27. if err = r.tracer.UnlinkEbpfProg(); err != nil {
  28. lastErr = fmt.Errorf("failed to unlink eBPF program: %w", err)
  29. log.Warnf("DoFusing,FuseTryMax[%d],tryLeft[%d] UnlinkEbpfProg occurs error:%s", *flags.FuseTryMax, tryLeft-1, err.Error())
  30. } else {
  31. log.Infof("DoFusing,FuseTryMax[%d],tryLeft[%d] UnlinkEbpfProg OK", *flags.FuseTryMax, tryLeft-1)
  32. }
  33. if lastErr == nil {
  34. break
  35. }
  36. time.Sleep(time.Duration(100) * time.Millisecond)
  37. }
  38. if lastErr != nil {
  39. //重试N次后,仍然失败 设置熔断机制异常标识 (后续就不进行恢复操作了)
  40. r.IsFuseException = true
  41. log.Warnf("DoFusing,lastErr is not nil, set IsFuseException = true. error: %s", lastErr.Error())
  42. }
  43. return lastErr
  44. }
  45. func (r *Registry) DoResume() error {
  46. log.Infof("-----DoResume will to execute resume operates -----\n")
  47. var (
  48. lastErr error
  49. err error
  50. )
  51. for tryLeft := *flags.FuseTryMax; tryLeft > 0; tryLeft-- {
  52. //先开启内核层的tracepoint、kprobe
  53. if err = r.tracer.LinkEbpfProg(); err != nil {
  54. lastErr = fmt.Errorf("failed to link eBPF program: %w", err)
  55. log.Warnf("DoResume,FuseTryMax[%d],tryLeft[%d] LinkEbpfProg occurs error:%s", *flags.FuseTryMax, tryLeft-1, err.Error())
  56. } else {
  57. log.Infof("DoResume,FuseTryMax[%d],tryLeft[%d] LinkEbpfProg OK", *flags.FuseTryMax, tryLeft-1)
  58. }
  59. //再开启数据发送
  60. if err = os.Setenv("SEND", "1"); err != nil {
  61. lastErr = fmt.Errorf("failed to set SEND env: %w", err)
  62. log.Warnf("DoResume,FuseTryMax[%d],tryLeft[%d] set SEND env occurs error:%s", *flags.FuseTryMax, tryLeft-1, err.Error())
  63. } else {
  64. log.Infof("DoResume,FuseTryMax[%d],tryLeft[%d] set SEND env OK", *flags.FuseTryMax, tryLeft-1)
  65. }
  66. if lastErr == nil {
  67. break
  68. }
  69. time.Sleep(time.Duration(100) * time.Millisecond)
  70. }
  71. if lastErr != nil {
  72. //重试N次后,仍然失败 将状态设置为熔断,设置熔断机制异常标识 (后续就不进行熔断操作了)
  73. r.IsFuseException = true
  74. r.isFusing = true
  75. log.Warnf("DoResume,lastErr is not nil, set IsFuseException = true. error: %s", lastErr.Error())
  76. } else {
  77. //最后处于非熔断状态 (应用层的uprobes\stackUprobes将进行Attach操作)
  78. r.isFusing = false
  79. }
  80. return lastErr
  81. }