@@ -16,19 +16,23 @@ package networkscraper
1616
1717import (
1818 "context"
19+ "fmt"
1920 "time"
2021
2122 "github.com/shirou/gopsutil/host"
2223 "github.com/shirou/gopsutil/net"
2324
2425 "go.opentelemetry.io/collector/component/componenterror"
2526 "go.opentelemetry.io/collector/consumer/pdata"
27+ "go.opentelemetry.io/collector/internal/processor/filterset"
2628)
2729
2830// scraper for Network Metrics
2931type scraper struct {
3032 config * Config
3133 startTime pdata.TimestampUnixNano
34+ includeFS filterset.FilterSet
35+ excludeFS filterset.FilterSet
3236
3337 // for mocking
3438 bootTime func () (uint64 , error )
@@ -37,8 +41,26 @@ type scraper struct {
3741}
3842
3943// newNetworkScraper creates a set of Network related metrics
40- func newNetworkScraper (_ context.Context , cfg * Config ) * scraper {
41- return & scraper {config : cfg , bootTime : host .BootTime , ioCounters : net .IOCounters , connections : net .Connections }
44+ func newNetworkScraper (_ context.Context , cfg * Config ) (* scraper , error ) {
45+ scraper := & scraper {config : cfg , bootTime : host .BootTime , ioCounters : net .IOCounters , connections : net .Connections }
46+
47+ var err error
48+
49+ if len (cfg .Include .Interfaces ) > 0 {
50+ scraper .includeFS , err = filterset .CreateFilterSet (cfg .Include .Interfaces , & cfg .Include .Config )
51+ if err != nil {
52+ return nil , fmt .Errorf ("error creating network interface include filters: %w" , err )
53+ }
54+ }
55+
56+ if len (cfg .Exclude .Interfaces ) > 0 {
57+ scraper .excludeFS , err = filterset .CreateFilterSet (cfg .Exclude .Interfaces , & cfg .Exclude .Config )
58+ if err != nil {
59+ return nil , fmt .Errorf ("error creating network interface exclude filters: %w" , err )
60+ }
61+ }
62+
63+ return scraper , nil
4264}
4365
4466// Initialize
@@ -82,33 +104,73 @@ func (s *scraper) ScrapeMetrics(_ context.Context) (pdata.MetricSlice, error) {
82104
83105func (s * scraper ) scrapeAndAppendNetworkCounterMetrics (metrics pdata.MetricSlice , startTime pdata.TimestampUnixNano ) error {
84106 // get total stats only
85- networkStatsSlice , err := s .ioCounters ( /*perNetworkInterfaceController=*/ false )
107+ ioCounters , err := s .ioCounters ( /*perNetworkInterfaceController=*/ true )
86108 if err != nil {
87109 return err
88110 }
89111
90- networkStats := networkStatsSlice [0 ]
112+ // filter network interfaces by name
113+ ioCounters = s .filterByInterface (ioCounters )
114+
115+ if len (ioCounters ) > 0 {
116+ startIdx := metrics .Len ()
117+ metrics .Resize (startIdx + 4 )
118+ initializeNetworkPacketsMetric (metrics .At (startIdx + 0 ), networkPacketsDescriptor , startTime , ioCounters )
119+ initializeNetworkDroppedPacketsMetric (metrics .At (startIdx + 1 ), networkDroppedPacketsDescriptor , startTime , ioCounters )
120+ initializeNetworkErrorsMetric (metrics .At (startIdx + 2 ), networkErrorsDescriptor , startTime , ioCounters )
121+ initializeNetworkIOMetric (metrics .At (startIdx + 3 ), networkIODescriptor , startTime , ioCounters )
122+ }
91123
92- startIdx := metrics .Len ()
93- metrics .Resize (startIdx + 4 )
94- initializeNetworkMetric (metrics .At (startIdx + 0 ), networkPacketsDescriptor , startTime , networkStats .PacketsSent , networkStats .PacketsRecv )
95- initializeNetworkMetric (metrics .At (startIdx + 1 ), networkDroppedPacketsDescriptor , startTime , networkStats .Dropout , networkStats .Dropin )
96- initializeNetworkMetric (metrics .At (startIdx + 2 ), networkErrorsDescriptor , startTime , networkStats .Errout , networkStats .Errin )
97- initializeNetworkMetric (metrics .At (startIdx + 3 ), networkIODescriptor , startTime , networkStats .BytesSent , networkStats .BytesRecv )
98124 return nil
99125}
100126
101- func initializeNetworkMetric (metric pdata.Metric , metricDescriptor pdata.MetricDescriptor , startTime pdata.TimestampUnixNano , transmitValue , receiveValue uint64 ) {
127+ func initializeNetworkPacketsMetric (metric pdata.Metric , metricDescriptor pdata.MetricDescriptor , startTime pdata.TimestampUnixNano , ioCountersSlice []net. IOCountersStat ) {
102128 metricDescriptor .CopyTo (metric .MetricDescriptor ())
103129
104130 idps := metric .Int64DataPoints ()
105- idps .Resize (2 )
106- initializeNetworkDataPoint (idps .At (0 ), startTime , transmitDirectionLabelValue , int64 (transmitValue ))
107- initializeNetworkDataPoint (idps .At (1 ), startTime , receiveDirectionLabelValue , int64 (receiveValue ))
131+ idps .Resize (2 * len (ioCountersSlice ))
132+ for idx , ioCounters := range ioCountersSlice {
133+ initializeNetworkDataPoint (idps .At (2 * idx + 0 ), startTime , ioCounters .Name , transmitDirectionLabelValue , int64 (ioCounters .PacketsSent ))
134+ initializeNetworkDataPoint (idps .At (2 * idx + 1 ), startTime , ioCounters .Name , receiveDirectionLabelValue , int64 (ioCounters .PacketsRecv ))
135+ }
108136}
109137
110- func initializeNetworkDataPoint (dataPoint pdata.Int64DataPoint , startTime pdata.TimestampUnixNano , directionLabel string , value int64 ) {
138+ func initializeNetworkDroppedPacketsMetric (metric pdata.Metric , metricDescriptor pdata.MetricDescriptor , startTime pdata.TimestampUnixNano , ioCountersSlice []net.IOCountersStat ) {
139+ metricDescriptor .CopyTo (metric .MetricDescriptor ())
140+
141+ idps := metric .Int64DataPoints ()
142+ idps .Resize (2 * len (ioCountersSlice ))
143+ for idx , ioCounters := range ioCountersSlice {
144+ initializeNetworkDataPoint (idps .At (2 * idx + 0 ), startTime , ioCounters .Name , transmitDirectionLabelValue , int64 (ioCounters .Dropout ))
145+ initializeNetworkDataPoint (idps .At (2 * idx + 1 ), startTime , ioCounters .Name , receiveDirectionLabelValue , int64 (ioCounters .Dropin ))
146+ }
147+ }
148+
149+ func initializeNetworkErrorsMetric (metric pdata.Metric , metricDescriptor pdata.MetricDescriptor , startTime pdata.TimestampUnixNano , ioCountersSlice []net.IOCountersStat ) {
150+ metricDescriptor .CopyTo (metric .MetricDescriptor ())
151+
152+ idps := metric .Int64DataPoints ()
153+ idps .Resize (2 * len (ioCountersSlice ))
154+ for idx , ioCounters := range ioCountersSlice {
155+ initializeNetworkDataPoint (idps .At (2 * idx + 0 ), startTime , ioCounters .Name , transmitDirectionLabelValue , int64 (ioCounters .Errout ))
156+ initializeNetworkDataPoint (idps .At (2 * idx + 1 ), startTime , ioCounters .Name , receiveDirectionLabelValue , int64 (ioCounters .Errin ))
157+ }
158+ }
159+
160+ func initializeNetworkIOMetric (metric pdata.Metric , metricDescriptor pdata.MetricDescriptor , startTime pdata.TimestampUnixNano , ioCountersSlice []net.IOCountersStat ) {
161+ metricDescriptor .CopyTo (metric .MetricDescriptor ())
162+
163+ idps := metric .Int64DataPoints ()
164+ idps .Resize (2 * len (ioCountersSlice ))
165+ for idx , ioCounters := range ioCountersSlice {
166+ initializeNetworkDataPoint (idps .At (2 * idx + 0 ), startTime , ioCounters .Name , transmitDirectionLabelValue , int64 (ioCounters .BytesSent ))
167+ initializeNetworkDataPoint (idps .At (2 * idx + 1 ), startTime , ioCounters .Name , receiveDirectionLabelValue , int64 (ioCounters .BytesRecv ))
168+ }
169+ }
170+
171+ func initializeNetworkDataPoint (dataPoint pdata.Int64DataPoint , startTime pdata.TimestampUnixNano , interfaceLabel , directionLabel string , value int64 ) {
111172 labelsMap := dataPoint .LabelsMap ()
173+ labelsMap .Insert (interfaceLabelName , interfaceLabel )
112174 labelsMap .Insert (directionLabelName , directionLabel )
113175 dataPoint .SetStartTime (startTime )
114176 dataPoint .SetTimestamp (pdata .TimestampUnixNano (uint64 (time .Now ().UnixNano ())))
@@ -170,3 +232,22 @@ func initializeNetworkTCPConnectionsDataPoint(dataPoint pdata.Int64DataPoint, st
170232 dataPoint .SetTimestamp (pdata .TimestampUnixNano (uint64 (time .Now ().UnixNano ())))
171233 dataPoint .SetValue (value )
172234}
235+
236+ func (s * scraper ) filterByInterface (ioCounters []net.IOCountersStat ) []net.IOCountersStat {
237+ if s .includeFS == nil && s .excludeFS == nil {
238+ return ioCounters
239+ }
240+
241+ filteredIOCounters := make ([]net.IOCountersStat , 0 , len (ioCounters ))
242+ for _ , io := range ioCounters {
243+ if s .includeInterface (io .Name ) {
244+ filteredIOCounters = append (filteredIOCounters , io )
245+ }
246+ }
247+ return filteredIOCounters
248+ }
249+
250+ func (s * scraper ) includeInterface (interfaceName string ) bool {
251+ return (s .includeFS == nil || s .includeFS .Matches (interfaceName )) &&
252+ (s .excludeFS == nil || ! s .excludeFS .Matches (interfaceName ))
253+ }
0 commit comments