metricbeat/module/docker/network/helper.go (131 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package network import ( "time" "github.com/docker/docker/api/types/container" "github.com/elastic/beats/v7/metricbeat/module/docker" ) type NetService struct { NetworkStatPerContainer map[string]map[string]NetRaw } type NetworkCalculator interface { getRxBytesPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 getRxDroppedPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 getRxErrorsPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 getRxPacketsPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 getTxBytesPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 getTxDroppedPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 getTxErrorsPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 getTxPacketsPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 } type NetRaw struct { Time time.Time RxBytes uint64 RxDropped uint64 RxErrors uint64 RxPackets uint64 TxBytes uint64 TxDropped uint64 TxErrors uint64 TxPackets uint64 } type NetStats struct { Time time.Time Container *docker.Container NameInterface string RxBytes float64 RxDropped float64 RxErrors float64 RxPackets float64 TxBytes float64 TxDropped float64 TxErrors float64 TxPackets float64 Total *container.NetworkStats } func (n *NetService) getNetworkStatsPerContainer(rawStats []docker.Stat, dedot bool) []NetStats { formattedStats := []NetStats{} for _, myStats := range rawStats { for nameInterface, rawnNetStats := range myStats.Stats.Networks { formattedStats = append(formattedStats, n.getNetworkStats(nameInterface, rawnNetStats, myStats, dedot)) } } return formattedStats } func (n *NetService) getNetworkStats(nameInterface string, rawNetStats container.NetworkStats, myRawstats docker.Stat, dedot bool) NetStats { newNetworkStats := createNetRaw(myRawstats.Stats.Read, &rawNetStats) oldNetworkStat, exist := n.NetworkStatPerContainer[myRawstats.Container.ID][nameInterface] netStats := NetStats{ Container: docker.NewContainer(myRawstats.Container, dedot), Time: myRawstats.Stats.Read, NameInterface: nameInterface, Total: &rawNetStats, } if exist { netStats.RxBytes = n.getRxBytesPerSecond(&newNetworkStats, &oldNetworkStat) netStats.RxDropped = n.getRxDroppedPerSecond(&newNetworkStats, &oldNetworkStat) netStats.RxErrors = n.getRxErrorsPerSecond(&newNetworkStats, &oldNetworkStat) netStats.RxPackets = n.getRxPacketsPerSecond(&newNetworkStats, &oldNetworkStat) netStats.TxBytes = n.getTxBytesPerSecond(&newNetworkStats, &oldNetworkStat) netStats.TxDropped = n.getTxDroppedPerSecond(&newNetworkStats, &oldNetworkStat) netStats.TxErrors = n.getTxErrorsPerSecond(&newNetworkStats, &oldNetworkStat) netStats.TxPackets = n.getTxPacketsPerSecond(&newNetworkStats, &oldNetworkStat) } else { if _, conExists := n.NetworkStatPerContainer[myRawstats.Container.ID]; !conExists { n.NetworkStatPerContainer[myRawstats.Container.ID] = make(map[string]NetRaw) } } n.NetworkStatPerContainer[myRawstats.Container.ID][nameInterface] = newNetworkStats return netStats } func createNetRaw(time time.Time, stats *container.NetworkStats) NetRaw { return NetRaw{ Time: time, RxBytes: stats.RxBytes, RxDropped: stats.RxDropped, RxErrors: stats.RxErrors, RxPackets: stats.RxPackets, TxBytes: stats.TxBytes, TxDropped: stats.TxDropped, TxErrors: stats.TxErrors, TxPackets: stats.TxPackets, } } func (n *NetService) getRxBytesPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 { duration := newStats.Time.Sub(oldStats.Time) return n.calculatePerSecond(duration, oldStats.RxBytes, newStats.RxBytes) } func (n *NetService) getRxDroppedPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 { duration := newStats.Time.Sub(oldStats.Time) return n.calculatePerSecond(duration, oldStats.RxDropped, newStats.RxDropped) } func (n *NetService) getRxErrorsPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 { duration := newStats.Time.Sub(oldStats.Time) return n.calculatePerSecond(duration, oldStats.RxErrors, newStats.RxErrors) } func (n *NetService) getRxPacketsPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 { duration := newStats.Time.Sub(oldStats.Time) return n.calculatePerSecond(duration, oldStats.RxPackets, newStats.RxPackets) } func (n *NetService) getTxBytesPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 { duration := newStats.Time.Sub(oldStats.Time) return n.calculatePerSecond(duration, oldStats.TxBytes, newStats.TxBytes) } func (n *NetService) getTxDroppedPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 { duration := newStats.Time.Sub(oldStats.Time) return n.calculatePerSecond(duration, oldStats.TxDropped, newStats.TxDropped) } func (n *NetService) getTxErrorsPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 { duration := newStats.Time.Sub(oldStats.Time) return n.calculatePerSecond(duration, oldStats.TxErrors, newStats.TxErrors) } func (n *NetService) getTxPacketsPerSecond(newStats *NetRaw, oldStats *NetRaw) float64 { duration := newStats.Time.Sub(oldStats.Time) return n.calculatePerSecond(duration, oldStats.TxPackets, newStats.TxPackets) } func (n *NetService) calculatePerSecond(duration time.Duration, oldValue uint64, newValue uint64) float64 { value := float64(newValue) - float64(oldValue) if value < 0 { value = 0 } return value / duration.Seconds() }