l7.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package containers
  2. import (
  3. "github.com/coroot/coroot-node-agent/ebpftracer/l7"
  4. "github.com/prometheus/client_golang/prometheus"
  5. "inet.af/netaddr"
  6. "k8s.io/klog/v2"
  7. "time"
  8. )
  9. type L7Metrics struct {
  10. Requests *prometheus.CounterVec
  11. Latency prometheus.Histogram
  12. }
  13. func (m *L7Metrics) observe(status, method string, duration time.Duration) {
  14. if m.Requests != nil {
  15. var err error
  16. var c prometheus.Counter
  17. if method != "" {
  18. c, err = m.Requests.GetMetricWithLabelValues(status, method)
  19. } else {
  20. c, err = m.Requests.GetMetricWithLabelValues(status)
  21. }
  22. if err != nil {
  23. klog.Warningln(err)
  24. } else {
  25. c.Inc()
  26. }
  27. }
  28. if m.Latency != nil && duration != 0 {
  29. m.Latency.Observe(duration.Seconds())
  30. }
  31. }
  32. type L7Stats map[l7.Protocol]map[AddrPair]*L7Metrics // protocol -> dst:actual_dst -> metrics
  33. func (s L7Stats) get(protocol l7.Protocol, destination, actualDestination netaddr.IPPort) *L7Metrics {
  34. if protocol == l7.ProtocolHTTP2 {
  35. protocol = l7.ProtocolHTTP
  36. }
  37. protoStats := s[protocol]
  38. if protoStats == nil {
  39. protoStats = map[AddrPair]*L7Metrics{}
  40. s[protocol] = protoStats
  41. }
  42. dest := AddrPair{src: destination, dst: actualDestination}
  43. m := protoStats[dest]
  44. if m == nil {
  45. m = &L7Metrics{}
  46. protoStats[dest] = m
  47. constLabels := map[string]string{"destination": destination.String(), "actual_destination": actualDestination.String()}
  48. labels := []string{"status"}
  49. switch protocol {
  50. case l7.ProtocolRabbitmq, l7.ProtocolNats:
  51. labels = append(labels, "method")
  52. default:
  53. hOpts := L7Latency[protocol]
  54. m.Latency = prometheus.NewHistogram(
  55. prometheus.HistogramOpts{Name: hOpts.Name, Help: hOpts.Help, ConstLabels: constLabels},
  56. )
  57. }
  58. cOpts := L7Requests[protocol]
  59. m.Requests = prometheus.NewCounterVec(
  60. prometheus.CounterOpts{Name: cOpts.Name, Help: cOpts.Help, ConstLabels: constLabels}, labels,
  61. )
  62. }
  63. return m
  64. }
  65. func (s L7Stats) collect(ch chan<- prometheus.Metric) {
  66. for _, protoStats := range s {
  67. for _, m := range protoStats {
  68. if m.Requests != nil {
  69. m.Requests.Collect(ch)
  70. }
  71. if m.Latency != nil {
  72. m.Latency.Collect(ch)
  73. }
  74. }
  75. }
  76. }
  77. func (s L7Stats) delete(dst netaddr.IPPort) {
  78. for _, protoStats := range s {
  79. for d := range protoStats {
  80. if d.src == dst {
  81. delete(protoStats, d)
  82. }
  83. }
  84. }
  85. }