process.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package containers
  2. import (
  3. "context"
  4. . "github.com/coroot/coroot-node-agent/utils/modelse"
  5. "os"
  6. "time"
  7. "github.com/jpillora/backoff"
  8. "github.com/cilium/ebpf/link"
  9. "github.com/coroot/coroot-node-agent/proc"
  10. "github.com/mdlayher/taskstats"
  11. )
  12. type Process struct {
  13. Pid uint32
  14. StartedAt time.Time
  15. NetNsId string
  16. ctx context.Context
  17. cancelFunc context.CancelFunc
  18. dotNetMonitor *DotNetMonitor
  19. uprobes []link.Link
  20. goTlsUprobesChecked bool
  21. openSslUprobesChecked bool
  22. jvmUprobesChecked bool
  23. stackUprobesChecked bool
  24. codeType CodeType
  25. cmdline string
  26. }
  27. func NewProcess(pid uint32, stats *taskstats.Stats) *Process {
  28. ns, err := proc.GetNetNs(pid)
  29. if err != nil {
  30. return nil
  31. }
  32. defer ns.Close()
  33. p := &Process{Pid: pid, StartedAt: stats.BeginTime, NetNsId: ns.UniqueId()}
  34. p.ctx, p.cancelFunc = context.WithCancel(context.Background())
  35. go p.instrument()
  36. return p
  37. }
  38. func (p *Process) isHostNs() bool {
  39. return p.NetNsId == hostNetNsId
  40. }
  41. func (p *Process) instrument() {
  42. b := backoff.Backoff{Factor: 2, Min: time.Second, Max: time.Minute}
  43. for {
  44. select {
  45. case <-p.ctx.Done():
  46. return
  47. default:
  48. dest, err := os.Readlink(proc.Path(p.Pid, "exe"))
  49. if err != nil {
  50. return
  51. }
  52. if dest != "/" {
  53. if dotNetAppName, err := dotNetApp(p.Pid); err == nil {
  54. if dotNetAppName != "" {
  55. p.dotNetMonitor = NewDotNetMonitor(p.ctx, p.Pid, dotNetAppName)
  56. }
  57. return
  58. }
  59. }
  60. time.Sleep(b.Duration())
  61. }
  62. }
  63. }
  64. func (p *Process) Close() {
  65. p.cancelFunc()
  66. for _, u := range p.uprobes {
  67. _ = u.Close()
  68. }
  69. }
  70. func (p *Process) DynamicClose() {
  71. for _, u := range p.uprobes {
  72. _ = u.Close()
  73. }
  74. p.goTlsUprobesChecked = false
  75. p.openSslUprobesChecked = false
  76. p.jvmUprobesChecked = false
  77. // TODO 移除 tiny-agent
  78. if p.codeType.IsJvmCode() && p.stackUprobesChecked {
  79. }
  80. p.stackUprobesChecked = false
  81. p.uprobes = []link.Link{}
  82. }
  83. func (p *Process) GetCmdline() string {
  84. return p.cmdline
  85. }