// +build windows package collector import ( "errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/log" ) func init() { registerCollector("tcp", NewTCPCollector, "TCPv4") } // A TCPCollector is a Prometheus collector for WMI Win32_PerfRawData_Tcpip_TCPv4 metrics type TCPCollector struct { ConnectionFailures *prometheus.Desc ConnectionsActive *prometheus.Desc ConnectionsEstablished *prometheus.Desc ConnectionsPassive *prometheus.Desc ConnectionsReset *prometheus.Desc SegmentsTotal *prometheus.Desc SegmentsReceivedTotal *prometheus.Desc SegmentsRetransmittedTotal *prometheus.Desc SegmentsSentTotal *prometheus.Desc } // NewTCPCollector ... func NewTCPCollector() (Collector, error) { const subsystem = "tcp" return &TCPCollector{ ConnectionFailures: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "connection_failures"), "(TCP.ConnectionFailures)", nil, nil, ), ConnectionsActive: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "connections_active"), "(TCP.ConnectionsActive)", nil, nil, ), ConnectionsEstablished: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "connections_established"), "(TCP.ConnectionsEstablished)", nil, nil, ), ConnectionsPassive: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "connections_passive"), "(TCP.ConnectionsPassive)", nil, nil, ), ConnectionsReset: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "connections_reset"), "(TCP.ConnectionsReset)", nil, nil, ), SegmentsTotal: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "segments_total"), "(TCP.SegmentsTotal)", nil, nil, ), SegmentsReceivedTotal: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "segments_received_total"), "(TCP.SegmentsReceivedTotal)", nil, nil, ), SegmentsRetransmittedTotal: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "segments_retransmitted_total"), "(TCP.SegmentsRetransmittedTotal)", nil, nil, ), SegmentsSentTotal: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "segments_sent_total"), "(TCP.SegmentsSentTotal)", nil, nil, ), }, nil } // Collect sends the metric values for each metric // to the provided prometheus Metric channel. func (c *TCPCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error { if desc, err := c.collect(ctx, ch); err != nil { log.Error("failed collecting tcp metrics:", desc, err) return err } return nil } // Win32_PerfRawData_Tcpip_TCPv4 docs // - https://msdn.microsoft.com/en-us/library/aa394341(v=vs.85).aspx type tcp struct { ConnectionFailures float64 `perflib:"Connection Failures"` ConnectionsActive float64 `perflib:"Connections Active"` ConnectionsEstablished float64 `perflib:"Connections Established"` ConnectionsPassive float64 `perflib:"Connections Passive"` ConnectionsReset float64 `perflib:"Connections Reset"` SegmentsPersec float64 `perflib:"Segments/sec"` SegmentsReceivedPersec float64 `perflib:"Segments Received/sec"` SegmentsRetransmittedPersec float64 `perflib:"Segments Retransmitted/sec"` SegmentsSentPersec float64 `perflib:"Segments Sent/sec"` } func (c *TCPCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) { var dst []tcp if err := unmarshalObject(ctx.perfObjects["TCPv4"], &dst); err != nil { return nil, err } if len(dst) == 0 { return nil, errors.New("TCPv4 performance object not available") } // Counters ch <- prometheus.MustNewConstMetric( c.ConnectionFailures, prometheus.CounterValue, dst[0].ConnectionFailures, ) ch <- prometheus.MustNewConstMetric( c.ConnectionsActive, prometheus.CounterValue, dst[0].ConnectionsActive, ) ch <- prometheus.MustNewConstMetric( c.ConnectionsEstablished, prometheus.GaugeValue, dst[0].ConnectionsEstablished, ) ch <- prometheus.MustNewConstMetric( c.ConnectionsPassive, prometheus.CounterValue, dst[0].ConnectionsPassive, ) ch <- prometheus.MustNewConstMetric( c.ConnectionsReset, prometheus.CounterValue, dst[0].ConnectionsReset, ) ch <- prometheus.MustNewConstMetric( c.SegmentsTotal, prometheus.CounterValue, dst[0].SegmentsPersec, ) ch <- prometheus.MustNewConstMetric( c.SegmentsReceivedTotal, prometheus.CounterValue, dst[0].SegmentsReceivedPersec, ) ch <- prometheus.MustNewConstMetric( c.SegmentsRetransmittedTotal, prometheus.CounterValue, dst[0].SegmentsRetransmittedPersec, ) ch <- prometheus.MustNewConstMetric( c.SegmentsSentTotal, prometheus.CounterValue, dst[0].SegmentsSentPersec, ) return nil, nil }