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

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Hubble
     3  
     4  package flow
     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  	v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
    14  	"github.com/cilium/cilium/pkg/hubble/metrics/api"
    15  	monitorAPI "github.com/cilium/cilium/pkg/monitor/api"
    16  )
    17  
    18  type flowHandler struct {
    19  	flows   *prometheus.CounterVec
    20  	context *api.ContextOptions
    21  }
    22  
    23  func (h *flowHandler) Init(registry *prometheus.Registry, options api.Options) error {
    24  	c, err := api.ParseContextOptions(options)
    25  	if err != nil {
    26  		return err
    27  	}
    28  	h.context = c
    29  
    30  	labels := []string{"protocol", "type", "subtype", "verdict"}
    31  	labels = append(labels, h.context.GetLabelNames()...)
    32  
    33  	h.flows = prometheus.NewCounterVec(prometheus.CounterOpts{
    34  		Namespace: api.DefaultPrometheusNamespace,
    35  		Name:      "flows_processed_total",
    36  		Help:      "Total number of flows processed",
    37  	}, labels)
    38  
    39  	registry.MustRegister(h.flows)
    40  	return nil
    41  }
    42  
    43  func (h *flowHandler) Status() string {
    44  	return h.context.Status()
    45  }
    46  
    47  func (h *flowHandler) Context() *api.ContextOptions {
    48  	return h.context
    49  }
    50  
    51  func (h *flowHandler) ListMetricVec() []*prometheus.MetricVec {
    52  	return []*prometheus.MetricVec{h.flows.MetricVec}
    53  }
    54  
    55  func (h *flowHandler) ProcessFlow(ctx context.Context, flow *flowpb.Flow) error {
    56  	labelValues, err := h.context.GetLabelValues(flow)
    57  	if err != nil {
    58  		return err
    59  	}
    60  	var typeName, subType string
    61  	eventType := flow.GetEventType().GetType()
    62  	switch eventType {
    63  	case monitorAPI.MessageTypeAccessLog:
    64  		typeName = "L7"
    65  		if l7 := flow.GetL7(); l7 != nil {
    66  			switch {
    67  			case l7.GetDns() != nil:
    68  				subType = "DNS"
    69  			case l7.GetHttp() != nil:
    70  				subType = "HTTP"
    71  			case l7.GetKafka() != nil:
    72  				subType = "Kafka"
    73  			}
    74  		}
    75  	case monitorAPI.MessageTypeDrop:
    76  		typeName = "Drop"
    77  	case monitorAPI.MessageTypeCapture:
    78  		typeName = "Capture"
    79  	case monitorAPI.MessageTypeTrace:
    80  		typeName = "Trace"
    81  		subType = monitorAPI.TraceObservationPoints[uint8(flow.GetEventType().SubType)]
    82  	case monitorAPI.MessageTypePolicyVerdict:
    83  		typeName = "PolicyVerdict"
    84  	default:
    85  		typeName = "Unknown"
    86  		subType = fmt.Sprintf("%d", eventType)
    87  	}
    88  
    89  	labels := []string{v1.FlowProtocol(flow), typeName, subType, flow.GetVerdict().String()}
    90  	labels = append(labels, labelValues...)
    91  
    92  	h.flows.WithLabelValues(labels...).Inc()
    93  	return nil
    94  }