github.com/cilium/cilium@v1.16.2/pkg/hubble/metrics/port-distribution/handler.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Hubble 3 4 package portdistribution 5 6 import ( 7 "context" 8 "fmt" 9 10 "github.com/prometheus/client_golang/prometheus" 11 12 flowpb "github.com/cilium/cilium/api/v1/flow" 13 "github.com/cilium/cilium/pkg/hubble/metrics/api" 14 ) 15 16 type portDistributionHandler struct { 17 portDistribution *prometheus.CounterVec 18 context *api.ContextOptions 19 } 20 21 func (h *portDistributionHandler) Init(registry *prometheus.Registry, options api.Options) error { 22 c, err := api.ParseContextOptions(options) 23 if err != nil { 24 return err 25 } 26 h.context = c 27 28 labels := []string{"protocol", "port"} 29 labels = append(labels, h.context.GetLabelNames()...) 30 31 h.portDistribution = prometheus.NewCounterVec(prometheus.CounterOpts{ 32 Namespace: api.DefaultPrometheusNamespace, 33 Name: "port_distribution_total", 34 Help: "Numbers of packets distributed by destination port", 35 }, labels) 36 37 registry.MustRegister(h.portDistribution) 38 return nil 39 } 40 41 func (h *portDistributionHandler) Status() string { 42 return h.context.Status() 43 } 44 45 func (h *portDistributionHandler) Context() *api.ContextOptions { 46 return h.context 47 } 48 49 func (h *portDistributionHandler) ListMetricVec() []*prometheus.MetricVec { 50 return []*prometheus.MetricVec{h.portDistribution.MetricVec} 51 } 52 53 func (h *portDistributionHandler) ProcessFlow(ctx context.Context, flow *flowpb.Flow) error { 54 // if we are not certain if a flow is a reply (i.e. flow.GetIsReply() == nil) 55 // we do not want to consider its destination port for the metric 56 skipReply := flow.GetIsReply() == nil || flow.GetIsReply().GetValue() 57 if (flow.GetVerdict() != flowpb.Verdict_FORWARDED && flow.GetVerdict() != flowpb.Verdict_REDIRECTED) || 58 flow.GetL4() == nil || skipReply { 59 return nil 60 } 61 62 labelValues, err := h.context.GetLabelValues(flow) 63 if err != nil { 64 return err 65 } 66 67 if tcp := flow.GetL4().GetTCP(); tcp != nil { 68 labels := append([]string{"TCP", fmt.Sprintf("%d", tcp.DestinationPort)}, labelValues...) 69 h.portDistribution.WithLabelValues(labels...).Inc() 70 } 71 72 if udp := flow.GetL4().GetUDP(); udp != nil { 73 labels := append([]string{"UDP", fmt.Sprintf("%d", udp.DestinationPort)}, labelValues...) 74 h.portDistribution.WithLabelValues(labels...).Inc() 75 } 76 77 if sctp := flow.GetL4().GetSCTP(); sctp != nil { 78 labels := append([]string{"SCTP", fmt.Sprintf("%d", sctp.DestinationPort)}, labelValues...) 79 h.portDistribution.WithLabelValues(labels...).Inc() 80 } 81 82 if flow.GetL4().GetICMPv4() != nil { 83 labels := append([]string{"ICMPv4", "0"}, labelValues...) 84 h.portDistribution.WithLabelValues(labels...).Inc() 85 } 86 87 if flow.GetL4().GetICMPv6() != nil { 88 labels := append([]string{"ICMPv6", "0"}, labelValues...) 89 h.portDistribution.WithLabelValues(labels...).Inc() 90 } 91 return nil 92 }