Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues/83 #1205

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions pkg/enricher/enricher.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package enricher

import (
"context"
"fmt"
"reflect"
"sync"

Expand All @@ -14,6 +15,7 @@ import (
"github.com/microsoft/retina/pkg/common"
"github.com/microsoft/retina/pkg/controllers/cache"
"github.com/microsoft/retina/pkg/log"
"github.com/microsoft/retina/pkg/utils"
"go.uber.org/zap"
)

Expand Down Expand Up @@ -182,6 +184,35 @@ func (e *Enricher) getWorkloads(ownerRefs []*common.OwnerReference) []*flow.Work
return workloads
}

func (e *Enricher) GetWindowLabels(ip string) *utils.LabelsInfo {
obj := e.cache.GetObjByIP(ip)
if obj == nil {
e.l.Debug("No object found for IP", zap.String("ip", ip))
return nil
}

switch o := obj.(type) {
case *common.RetinaEndpoint:
var workload *flow.Workload
if workloads := e.getWorkloads(o.OwnerRefs()); len(workloads) > 0 {
fmt.Printf("Workloads Check: \n%+v", workloads)
workload = workloads[0]
} else {
workload = &flow.Workload{Name: "", Kind: ""}
}

return &utils.LabelsInfo{
Namespace: o.Namespace(),
PodName: o.Name(),
Workload: workload,
}

default:
e.l.Debug("received unknown type from cache", zap.Any("obj", obj), zap.Any("type", reflect.TypeOf(obj)))
return nil
}
}

func (e *Enricher) Write(ev *v1.Event) {
e.inputRing.Write(ev)
}
Expand Down
51 changes: 51 additions & 0 deletions pkg/plugin/windows/hnsstats/hnsstats_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@ import (
"github.com/Microsoft/hcsshim/hcn"
v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
kcfg "github.com/microsoft/retina/pkg/config"
"github.com/microsoft/retina/pkg/enricher"
"github.com/microsoft/retina/pkg/exporter"
"github.com/microsoft/retina/pkg/log"
"github.com/microsoft/retina/pkg/metrics"
"github.com/microsoft/retina/pkg/plugin/api"
"github.com/microsoft/retina/pkg/utils"
"github.com/prometheus/client_golang/prometheus"
"go.uber.org/zap"
)

var (
AdvWindowsGauge *prometheus.GaugeVec
)

const (
initialize = iota + 1
start
Expand Down Expand Up @@ -74,6 +81,11 @@ func (h *hnsstats) Init() error {
}
h.endpointQuery.Filter = string(filter)

if h.cfg.EnablePodLevel {
h.l.Info("Creating advanced HNS stats metrics")
initializeAdvMetrics()
}

h.l.Info("Exiting hnsstats Init...")
return nil
}
Expand Down Expand Up @@ -133,6 +145,7 @@ func pullHnsStats(ctx context.Context, h *hnsstats) error {
if vfpcounters, err := parseVfpPortCounters(countersRaw); err == nil {
// Attach VFP port counters
hnsStatsData.vfpCounters = vfpcounters
hnsStatsData.Port = portguid
h.l.Debug("Attached VFP port counters", zap.String(zapPortField, portguid))
// h.l.Info(vfpcounters.String())
} else {
Expand All @@ -143,6 +156,7 @@ func pullHnsStats(ctx context.Context, h *hnsstats) error {
}

notifyHnsStats(h, hnsStatsData)
getAdvancedMetricLabels(h, hnsStatsData)
}
}
}
Expand Down Expand Up @@ -197,6 +211,21 @@ func notifyHnsStats(h *hnsstats, stats *HnsStatsData) {
metrics.TCPFlagGauge.WithLabelValues(egressLabel, utils.RST).Set(float64(stats.vfpCounters.Out.TcpCounters.PacketCounters.RstPacketCount))
}

func getAdvancedMetricLabels(h *hnsstats, stats *HnsStatsData) {
if AdvWindowsGauge == nil {
h.l.Warn("Advanced windows metric is not initialized")
return
}
// if port is populated, vfp data exists
labels := enricher.Instance().GetWindowLabels(stats.IPAddress)

if labels != nil {
AdvWindowsGauge.WithLabelValues(PacketsReceived, stats.IPAddress, stats.Port, labels.Namespace, labels.PodName, labels.Workload.Kind, labels.Workload.Name).Set(float64(stats.hnscounters.PacketsReceived))
AdvWindowsGauge.WithLabelValues(PacketsSent, stats.IPAddress, stats.Port, labels.Namespace, labels.PodName, labels.Workload.Kind, labels.Workload.Name).Set(float64(stats.hnscounters.PacketsSent))
h.l.Info("updating advanced HNS stats metric", zap.String(PodName, labels.PodName), zap.String(Namespace, labels.Namespace), zap.String(labels.Workload.Kind, labels.Workload.Name))
}
}

func (h *hnsstats) Start(ctx context.Context) error {
h.l.Info("Start hnsstats plugin...")
h.state = start
Expand All @@ -223,3 +252,25 @@ func New(cfg *kcfg.Config) api.Plugin {
l: log.Logger().Named(string(Name)),
}
}

func cleanAdvMetrics() {
exporter.UnregisterMetric(exporter.AdvancedRegistry, metrics.ToPrometheusType(AdvWindowsGauge))
}

func initializeAdvMetrics() {
if AdvWindowsGauge != nil {
cleanAdvMetrics()
}
AdvWindowsGauge = exporter.CreatePrometheusGaugeVecForMetric(
exporter.AdvancedRegistry,
AdvHNSStatsName,
AdvHNSStatsDescription,
utils.Direction,
Ip,
Port,
Namespace,
PodName,
WorkloadKind,
WorkloadName,
)
}
16 changes: 16 additions & 0 deletions pkg/plugin/windows/hnsstats/types_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/Microsoft/hcsshim"
"github.com/Microsoft/hcsshim/hcn"
kcfg "github.com/microsoft/retina/pkg/config"
"github.com/microsoft/retina/pkg/enricher"
"github.com/microsoft/retina/pkg/log"
"github.com/microsoft/retina/pkg/plugin/api"
"go.opentelemetry.io/otel/attribute"
Expand All @@ -21,6 +22,19 @@ import (
const (
Name api.PluginName = "hnsstats"
HnsStatsEvent string = "hnsstatscount"

// Advanced metric
AdvHNSStatsName string = "adv_windows_hns_stats"
AdvHNSStatsDescription string = "Include many different metrics from packets sent/received to closed connections"

// Advanced metric labels
Ip string = "ip"
Port string = "port"
Namespace string = "namespace"
PodName string = "podname"
WorkloadKind string = "workload_kind"
WorkloadName string = "workload_name"

// From HNSStats API
PacketsReceived string = "win_packets_recv_count"
PacketsSent string = "win_packets_sent_count"
Expand Down Expand Up @@ -74,12 +88,14 @@ type hnsstats struct {
state int
l *log.ZapLogger
endpointQuery hcn.HostComputeQuery
enricher enricher.EnricherInterface
}

type HnsStatsData struct {
hnscounters *hcsshim.HNSEndpointStats
IPAddress string
vfpCounters *VfpPortStatsData
Port string
}

// handles event signals such as incrementing a metric counter
Expand Down
7 changes: 7 additions & 0 deletions pkg/utils/attr_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package utils

import (
"github.com/cilium/cilium/api/v1/flow"
"go.opentelemetry.io/otel/attribute"
)

Expand Down Expand Up @@ -86,6 +87,12 @@ var (
DNSResponseLabels = []string{"return_code", "query_type", "query", "response", "num_response"}
)

type LabelsInfo struct {
Namespace string
PodName string
Workload *flow.Workload
}

func GetPluginEventAttributes(attrs []attribute.KeyValue, pluginName, eventName, timestamp string) []attribute.KeyValue {
return append(attrs,
pluginKey.String(pluginName),
Expand Down