github.com/cilium/cilium@v1.16.2/pkg/maps/ctmap/metrics.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package ctmap 5 6 import ( 7 "fmt" 8 9 "github.com/cilium/cilium/pkg/bpf" 10 "github.com/cilium/cilium/pkg/maps/nat" 11 "github.com/cilium/cilium/pkg/metrics" 12 ) 13 14 type gcStats struct { 15 *bpf.DumpStats 16 17 // aliveEntries is the number of scanned entries that are still alive. 18 aliveEntries uint32 19 20 // deleted is the number of keys deleted 21 deleted uint32 22 23 // family is the address family 24 family gcFamily 25 26 // proto is the L4 protocol 27 proto gcProtocol 28 29 // dumpError records any error that occurred during the dump. 30 dumpError error 31 } 32 33 type gcFamily int 34 35 const ( 36 gcFamilyIPv4 gcFamily = iota 37 gcFamilyIPv6 38 ) 39 40 func (g gcFamily) String() string { 41 switch g { 42 case gcFamilyIPv4: 43 return "ipv4" 44 case gcFamilyIPv6: 45 return "ipv6" 46 default: 47 return "unknown" 48 } 49 } 50 51 type gcProtocol int 52 53 const ( 54 gcProtocolAny gcProtocol = iota 55 gcProtocolTCP 56 ) 57 58 func (g gcProtocol) String() string { 59 switch g { 60 case gcProtocolAny: 61 return "non-TCP" 62 case gcProtocolTCP: 63 return "TCP" 64 default: 65 return fmt.Sprintf("unknown (%d)", int(g)) 66 } 67 } 68 69 func statStartGc(m *Map) gcStats { 70 result := gcStats{ 71 DumpStats: bpf.NewDumpStats(&m.Map), 72 } 73 if m.mapType.isIPv6() { 74 result.family = gcFamilyIPv6 75 } else { 76 result.family = gcFamilyIPv4 77 } 78 if m.mapType.isTCP() { 79 result.proto = gcProtocolTCP 80 } else { 81 result.proto = gcProtocolAny 82 } 83 return result 84 } 85 86 func (s *gcStats) finish() { 87 duration := s.Duration() 88 family := s.family.String() 89 switch s.family { 90 case gcFamilyIPv6: 91 metrics.ConntrackDumpResets.With(labelIPv6CTDumpInterrupts).Add(float64(s.Interrupted)) 92 case gcFamilyIPv4: 93 metrics.ConntrackDumpResets.With(labelIPv4CTDumpInterrupts).Add(float64(s.Interrupted)) 94 } 95 proto := s.proto.String() 96 97 var status string 98 if s.Completed { 99 status = "completed" 100 metrics.ConntrackGCSize.WithLabelValues(family, proto, metricsAlive).Set(float64(s.aliveEntries)) 101 metrics.ConntrackGCSize.WithLabelValues(family, proto, metricsDeleted).Set(float64(s.deleted)) 102 } else { 103 status = "uncompleted" 104 scopedLog := log.WithField("interrupted", s.Interrupted) 105 if s.dumpError != nil { 106 scopedLog = scopedLog.WithError(s.dumpError) 107 } 108 scopedLog.Warningf("Garbage collection on %s %s CT map failed to finish", family, proto) 109 } 110 111 metrics.ConntrackGCRuns.WithLabelValues(family, proto, status).Inc() 112 metrics.ConntrackGCDuration.WithLabelValues(family, proto, status).Observe(duration.Seconds()) 113 metrics.ConntrackGCKeyFallbacks.WithLabelValues(family, proto).Add(float64(s.KeyFallback)) 114 } 115 116 type NatGCStats struct { 117 *bpf.DumpStats 118 119 // family is the address family 120 Family gcFamily 121 122 IngressAlive uint32 123 IngressDeleted uint32 124 EgressDeleted uint32 125 EgressAlive uint32 126 } 127 128 func newNatGCStats(m *nat.Map, family gcFamily) NatGCStats { 129 return NatGCStats{ 130 DumpStats: m.DumpStats(), 131 Family: family, 132 } 133 } 134 135 func (s *NatGCStats) finish() { 136 family := s.Family.String() 137 metrics.NatGCSize.WithLabelValues(family, metricsIngress, metricsAlive).Set(float64(s.IngressAlive)) 138 metrics.NatGCSize.WithLabelValues(family, metricsIngress, metricsDeleted).Set(float64(s.IngressDeleted)) 139 metrics.NatGCSize.WithLabelValues(family, metricsEgress, metricsAlive).Set(float64(s.EgressAlive)) 140 metrics.NatGCSize.WithLabelValues(family, metricsEgress, metricsDeleted).Set(float64(s.EgressDeleted)) 141 }