github.com/cilium/cilium@v1.16.2/pkg/hubble/metrics/tcp/handler.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Hubble
     3  
     4  package tcp
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/prometheus/client_golang/prometheus"
    10  
    11  	flowpb "github.com/cilium/cilium/api/v1/flow"
    12  	"github.com/cilium/cilium/pkg/hubble/metrics/api"
    13  )
    14  
    15  type tcpHandler struct {
    16  	tcpFlags *prometheus.CounterVec
    17  	context  *api.ContextOptions
    18  }
    19  
    20  func (h *tcpHandler) Init(registry *prometheus.Registry, options api.Options) error {
    21  	c, err := api.ParseContextOptions(options)
    22  	if err != nil {
    23  		return err
    24  	}
    25  	h.context = c
    26  	labels := []string{"flag", "family"}
    27  	labels = append(labels, h.context.GetLabelNames()...)
    28  
    29  	h.tcpFlags = prometheus.NewCounterVec(prometheus.CounterOpts{
    30  		Namespace: api.DefaultPrometheusNamespace,
    31  		Name:      "tcp_flags_total",
    32  		Help:      "TCP flag occurrences",
    33  	}, labels)
    34  
    35  	registry.MustRegister(h.tcpFlags)
    36  	return nil
    37  }
    38  
    39  func (h *tcpHandler) Status() string {
    40  	return h.context.Status()
    41  }
    42  
    43  func (h *tcpHandler) Context() *api.ContextOptions {
    44  	return h.context
    45  }
    46  
    47  func (h *tcpHandler) ListMetricVec() []*prometheus.MetricVec {
    48  	return []*prometheus.MetricVec{h.tcpFlags.MetricVec}
    49  }
    50  
    51  func (h *tcpHandler) ProcessFlow(ctx context.Context, flow *flowpb.Flow) error {
    52  	if (flow.GetVerdict() != flowpb.Verdict_FORWARDED && flow.GetVerdict() != flowpb.Verdict_REDIRECTED) ||
    53  		flow.GetL4() == nil {
    54  		return nil
    55  	}
    56  
    57  	ip := flow.GetIP()
    58  	tcp := flow.GetL4().GetTCP()
    59  	if ip == nil || tcp == nil || tcp.Flags == nil {
    60  		return nil
    61  	}
    62  
    63  	contextLabels, err := h.context.GetLabelValues(flow)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	labels := append([]string{"", ip.IpVersion.String()}, contextLabels...)
    68  
    69  	if tcp.Flags.FIN {
    70  		labels[0] = "FIN"
    71  		h.tcpFlags.WithLabelValues(labels...).Inc()
    72  	}
    73  
    74  	if tcp.Flags.SYN {
    75  		if tcp.Flags.ACK {
    76  			labels[0] = "SYN-ACK"
    77  			h.tcpFlags.WithLabelValues(labels...).Inc()
    78  		} else {
    79  			labels[0] = "SYN"
    80  			h.tcpFlags.WithLabelValues(labels...).Inc()
    81  		}
    82  	}
    83  
    84  	if tcp.Flags.RST {
    85  		labels[0] = "RST"
    86  		h.tcpFlags.WithLabelValues(labels...).Inc()
    87  	}
    88  
    89  	return nil
    90  }