1
0
mirror of https://github.com/netsampler/goflow2.git synced 2024-05-06 15:54:52 +00:00
2023-08-09 19:47:20 -07:00

152 lines
3.3 KiB
Go

package metrics
import (
"net/netip"
"github.com/netsampler/goflow2/v2/decoders/netflow"
"github.com/netsampler/goflow2/v2/decoders/netflowlegacy"
"github.com/netsampler/goflow2/v2/decoders/sflow"
flowmessage "github.com/netsampler/goflow2/v2/pb"
"github.com/netsampler/goflow2/v2/producer"
"github.com/prometheus/client_golang/prometheus"
)
type PromProducerWrapper struct {
wrapped producer.ProducerInterface
}
func (p *PromProducerWrapper) Produce(msg interface{}, args *producer.ProduceArgs) ([]producer.ProducerMessage, error) {
flowMessageSet, err := p.wrapped.Produce(msg, args)
if err != nil {
return flowMessageSet, err
}
key := args.Src.Addr().Unmap().String()
var nfvariant bool
var versionStr string
switch packet := msg.(type) {
case *sflow.Packet:
agentStr := "unk"
agentIp, ok := netip.AddrFromSlice(packet.AgentIP)
if ok {
agentStr = agentIp.String()
}
SFlowStats.With(
prometheus.Labels{
"router": key,
"agent": agentStr,
"version": "5",
}).
Inc()
for _, samples := range packet.Samples {
typeStr := "unknown"
countRec := 0
switch samplesConv := samples.(type) {
case sflow.FlowSample:
typeStr = "FlowSample"
countRec = len(samplesConv.Records)
case sflow.CounterSample:
typeStr = "CounterSample"
if samplesConv.Header.Format == 4 {
typeStr = "Expanded" + typeStr
}
countRec = len(samplesConv.Records)
case sflow.ExpandedFlowSample:
typeStr = "ExpandedFlowSample"
countRec = len(samplesConv.Records)
}
SFlowSampleStatsSum.With(
prometheus.Labels{
"router": key,
"agent": agentStr,
"version": "5",
"type": typeStr,
}).
Inc()
SFlowSampleRecordsStatsSum.With(
prometheus.Labels{
"router": key,
"agent": agentStr,
"version": "5",
"type": typeStr,
}).
Add(float64(countRec))
}
case *netflowlegacy.PacketNetFlowV5:
NetFlowStats.With(
prometheus.Labels{
"router": key,
"version": "5",
}).
Inc()
NetFlowSetStatsSum.With(
prometheus.Labels{
"router": key,
"version": "5",
"type": "DataFlowSet",
}).
Add(float64(packet.Count))
case *netflow.NFv9Packet:
NetFlowStats.With(
prometheus.Labels{
"router": key,
"version": "9",
}).
Inc()
recordCommonNetFlowMetrics(9, key, packet.FlowSets)
nfvariant = true
versionStr = "9"
case *netflow.IPFIXPacket:
NetFlowStats.With(
prometheus.Labels{
"router": key,
"version": "10",
}).
Inc()
recordCommonNetFlowMetrics(10, key, packet.FlowSets)
nfvariant = true
versionStr = "10"
}
if nfvariant {
for _, msg := range flowMessageSet {
fmsg, ok := msg.(*flowmessage.FlowMessage)
if !ok {
continue
}
timeDiff := fmsg.TimeReceivedNs - fmsg.TimeFlowEndNs
NetFlowTimeStatsSum.With(
prometheus.Labels{
"router": key,
"version": versionStr,
}).
Observe(float64(timeDiff))
}
}
return flowMessageSet, err
}
func (p *PromProducerWrapper) Close() {
p.wrapped.Close()
}
func (p *PromProducerWrapper) Commit(flowMessageSet []producer.ProducerMessage) {
p.wrapped.Commit(flowMessageSet)
}
// Wraps a producer with metrics
func WrapPromProducer(wrapped producer.ProducerInterface) producer.ProducerInterface {
return &PromProducerWrapper{
wrapped: wrapped,
}
}
// metrics template system