process.go 1.5 KB

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