From 00cff18e9687bacaa7948845ed5cec985fae5aa3 Mon Sep 17 00:00:00 2001 From: Alex K <8418476+fearful-symmetry@users.noreply.github.com> Date: Mon, 13 Jan 2020 13:09:19 -0800 Subject: [PATCH] [Metricbeat] add a network_summary metricset (#15196) * commit of system/network_summary (cherry picked from commit 8b9ffbd583d8e3d7416142e94813a1c479313419) --- CHANGELOG.next.asciidoc | 1 + NOTICE.txt | 4 +- metricbeat/docs/fields.asciidoc | 57 ++++ metricbeat/docs/modules/system.asciidoc | 4 + .../modules/system/network_summary.asciidoc | 23 ++ metricbeat/docs/modules_list.asciidoc | 3 +- metricbeat/include/list_common.go | 1 + metricbeat/module/system/fields.go | 4 + .../system/network_summary/_meta/data.json | 245 ++++++++++++++++++ .../network_summary/_meta/docs.asciidoc | 6 + .../system/network_summary/_meta/fields.yml | 26 ++ .../module/system/network_summary/data.go | 64 +++++ .../system/network_summary/network_summary.go | 95 +++++++ .../network_summary/network_summary_test.go | 70 +++++ .../elastic/go-sysinfo/CHANGELOG.md | 15 +- .../go-sysinfo/providers/linux/procnet.go | 32 ++- .../elastic/go-sysinfo/types/host.go | 17 +- vendor/vendor.json | 62 ++--- 18 files changed, 671 insertions(+), 58 deletions(-) create mode 100644 metricbeat/docs/modules/system/network_summary.asciidoc create mode 100644 metricbeat/module/system/network_summary/_meta/data.json create mode 100644 metricbeat/module/system/network_summary/_meta/docs.asciidoc create mode 100644 metricbeat/module/system/network_summary/_meta/fields.yml create mode 100644 metricbeat/module/system/network_summary/data.go create mode 100644 metricbeat/module/system/network_summary/network_summary.go create mode 100644 metricbeat/module/system/network_summary/network_summary_test.go diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index d766a794127..210c5a09d5c 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -143,6 +143,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add cost warnings for the azure module. {pull}15356[15356] - Release elb module as GA. {pull}15485[15485] +- Add a `system/network_summary` metricset {pull}15196[15196] *Packetbeat* diff --git a/NOTICE.txt b/NOTICE.txt index eac5d7479f4..3ed3de2a5c0 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1399,8 +1399,8 @@ Apache License 2.0 -------------------------------------------------------------------- Dependency: github.com/elastic/go-sysinfo -Version: v1.2.1 -Revision: cee67141de1bdfb666367301f44e559e58b16734 +Version: v1.3.0 +Revision: b719bc42e40963c707571af208683a049e61f07f License type (autodetected): Apache-2.0 ./vendor/github.com/elastic/go-sysinfo/LICENSE.txt: -------------------------------------------------------------------- diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index 1f33f2848b4..a86d842987d 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -30621,6 +30621,63 @@ type: long -- +[float] +=== network_summary + +Metrics relating to global network activity + + + +*`system.network_summary.ip.*`*:: ++ +-- +IP counters + + +type: object + +-- + +*`system.network_summary.tcp.*`*:: ++ +-- +TCP counters + + +type: object + +-- + +*`system.network_summary.udp.*`*:: ++ +-- +UDP counters + + +type: object + +-- + +*`system.network_summary.udp_lite.*`*:: ++ +-- +UDP Lite counters + + +type: object + +-- + +*`system.network_summary.icmp.*`*:: ++ +-- +ICMP counters + + +type: object + +-- + [float] === process diff --git a/metricbeat/docs/modules/system.asciidoc b/metricbeat/docs/modules/system.asciidoc index 99ec1f338f8..5a9da32636d 100644 --- a/metricbeat/docs/modules/system.asciidoc +++ b/metricbeat/docs/modules/system.asciidoc @@ -254,6 +254,8 @@ The following metricsets are available: * <> +* <> + * <> * <> @@ -286,6 +288,8 @@ include::system/memory.asciidoc[] include::system/network.asciidoc[] +include::system/network_summary.asciidoc[] + include::system/process.asciidoc[] include::system/process_summary.asciidoc[] diff --git a/metricbeat/docs/modules/system/network_summary.asciidoc b/metricbeat/docs/modules/system/network_summary.asciidoc new file mode 100644 index 00000000000..fd68d6b7bc5 --- /dev/null +++ b/metricbeat/docs/modules/system/network_summary.asciidoc @@ -0,0 +1,23 @@ +//// +This file is generated! See scripts/mage/docs_collector.go +//// + +[[metricbeat-metricset-system-network_summary]] +=== System network_summary metricset + +beta[] + +include::../../../module/system/network_summary/_meta/docs.asciidoc[] + + +==== Fields + +For a description of each field in the metricset, see the +<> section. + +Here is an example document generated by this metricset: + +[source,json] +---- +include::../../../module/system/network_summary/_meta/data.json[] +---- diff --git a/metricbeat/docs/modules_list.asciidoc b/metricbeat/docs/modules_list.asciidoc index 700a493a8a9..0d55f0fdb4b 100644 --- a/metricbeat/docs/modules_list.asciidoc +++ b/metricbeat/docs/modules_list.asciidoc @@ -187,7 +187,7 @@ This file is generated! See scripts/mage/docs_collector.go |<> beta[] |image:./images/icon-no.png[No prebuilt dashboards] | .1+| .1+| |<> beta[] |<> |image:./images/icon-yes.png[Prebuilt dashboards are available] | -.16+| .16+| |<> +.17+| .17+| |<> |<> |<> |<> @@ -196,6 +196,7 @@ This file is generated! See scripts/mage/docs_collector.go |<> |<> |<> +|<> beta[] |<> |<> |<> diff --git a/metricbeat/include/list_common.go b/metricbeat/include/list_common.go index 26db25d5744..17318c683e8 100644 --- a/metricbeat/include/list_common.go +++ b/metricbeat/include/list_common.go @@ -138,6 +138,7 @@ import ( _ "github.com/elastic/beats/metricbeat/module/system/load" _ "github.com/elastic/beats/metricbeat/module/system/memory" _ "github.com/elastic/beats/metricbeat/module/system/network" + _ "github.com/elastic/beats/metricbeat/module/system/network_summary" _ "github.com/elastic/beats/metricbeat/module/system/process" _ "github.com/elastic/beats/metricbeat/module/system/process_summary" _ "github.com/elastic/beats/metricbeat/module/system/raid" diff --git a/metricbeat/module/system/fields.go b/metricbeat/module/system/fields.go index bcd142d3536..c722870285e 100644 --- a/metricbeat/module/system/fields.go +++ b/metricbeat/module/system/fields.go @@ -32,5 +32,9 @@ func init() { // AssetSystem returns asset data. // This is the base64 encoded gzipped contents of ../metricbeat/module/system. func AssetSystem() string { +<<<<<<< HEAD return "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" +======= + return "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" +>>>>>>> 8b9ffbd58... [Metricbeat] add a network_summary metricset (#15196) } diff --git a/metricbeat/module/system/network_summary/_meta/data.json b/metricbeat/module/system/network_summary/_meta/data.json new file mode 100644 index 00000000000..905e26ac4be --- /dev/null +++ b/metricbeat/module/system/network_summary/_meta/data.json @@ -0,0 +1,245 @@ +{ + "@timestamp": "2017-10-12T08:05:34.853Z", + "event": { + "dataset": "system.network_summary", + "duration": 115000, + "module": "system" + }, + "metricset": { + "name": "network_summary", + "period": 10000 + }, + "service": { + "type": "system" + }, + "system": { + "network_summary": { + "icmp": { + "InAddrMaskReps": 0, + "InAddrMasks": 0, + "InCsumErrors": 0, + "InDestUnreachs": 835, + "InEchoReps": 0, + "InEchos": 1, + "InErrors": 20, + "InMsgs": 836, + "InParmProbs": 0, + "InRedirects": 0, + "InSrcQuenchs": 0, + "InTimeExcds": 0, + "InTimestampReps": 0, + "InTimestamps": 0, + "InType3": 835, + "InType8": 1, + "OutAddrMaskReps": 0, + "OutAddrMasks": 0, + "OutDestUnreachs": 940, + "OutEchoReps": 1, + "OutEchos": 0, + "OutErrors": 0, + "OutMsgs": 941, + "OutParmProbs": 0, + "OutRedirects": 0, + "OutSrcQuenchs": 0, + "OutTimeExcds": 0, + "OutTimestampReps": 0, + "OutTimestamps": 0, + "OutType0": 1, + "OutType3": 940 + }, + "ip": { + "DefaultTTL": 64, + "ForwDatagrams": 33389, + "Forwarding": 1, + "FragCreates": 0, + "FragFails": 0, + "FragOKs": 0, + "InAddrErrors": 19, + "InBcastOctets": 431773621, + "InBcastPkts": 1686995, + "InCEPkts": 0, + "InCsumErrors": 0, + "InDelivers": 38037698, + "InDiscards": 0, + "InECT0Pkts": 3160941, + "InECT1Pkts": 0, + "InHdrErrors": 0, + "InMcastOctets": 0, + "InMcastPkts": 0, + "InNoECTPkts": 129521210, + "InNoRoutes": 0, + "InOctets": 167733588581, + "InReceives": 41266648, + "InTruncatedPkts": 0, + "InUnknownProtos": 0, + "OutBcastOctets": 0, + "OutBcastPkts": 0, + "OutDiscards": 1, + "OutMcastOctets": 0, + "OutMcastPkts": 0, + "OutNoRoutes": 4, + "OutOctets": 75001958794, + "OutRequests": 29261852, + "ReasmFails": 0, + "ReasmOKs": 0, + "ReasmOverlaps": 0, + "ReasmReqds": 0, + "ReasmTimeout": 0 + }, + "tcp": { + "ActiveOpens": 6172, + "ArpFilter": 0, + "AttemptFails": 1488, + "BusyPollRxPackets": 0, + "CurrEstab": 9, + "DelayedACKLocked": 111, + "DelayedACKLost": 1587, + "DelayedACKs": 516004, + "EmbryonicRsts": 2, + "EstabResets": 404, + "IPReversePathFilter": 0, + "InCsumErrors": 0, + "InErrs": 4, + "InSegs": 38005498, + "ListenDrops": 0, + "ListenOverflows": 0, + "LockDroppedIcmps": 0, + "MaxConn": -1, + "OfoPruned": 0, + "OutOfWindowIcmps": 39, + "OutRsts": 10739, + "OutSegs": 66991971, + "PAWSActive": 0, + "PAWSEstab": 19, + "PFMemallocDrop": 0, + "PassiveOpens": 1411, + "PruneCalled": 0, + "RcvPruned": 0, + "RetransSegs": 15996, + "RtoAlgorithm": 1, + "RtoMax": 120000, + "RtoMin": 200, + "SyncookiesFailed": 2, + "SyncookiesRecv": 0, + "SyncookiesSent": 0, + "TCPACKSkippedChallenge": 2, + "TCPACKSkippedFinWait2": 0, + "TCPACKSkippedPAWS": 1, + "TCPACKSkippedSeq": 4, + "TCPACKSkippedSynRecv": 8, + "TCPACKSkippedTimeWait": 0, + "TCPAbortFailed": 0, + "TCPAbortOnClose": 321, + "TCPAbortOnData": 2613, + "TCPAbortOnLinger": 0, + "TCPAbortOnMemory": 0, + "TCPAbortOnTimeout": 84, + "TCPAckCompressed": 232116, + "TCPAutoCorking": 162, + "TCPBacklogCoalesce": 509441, + "TCPBacklogDrop": 0, + "TCPChallengeACK": 2, + "TCPDSACKIgnoredNoUndo": 4623, + "TCPDSACKIgnoredOld": 242, + "TCPDSACKOfoRecv": 2, + "TCPDSACKOfoSent": 15, + "TCPDSACKOldSent": 1668, + "TCPDSACKRecv": 8205, + "TCPDSACKUndo": 36, + "TCPDeferAcceptDrop": 0, + "TCPDelivered": 54733743, + "TCPDeliveredCE": 0, + "TCPFastOpenActive": 0, + "TCPFastOpenActiveFail": 0, + "TCPFastOpenBlackhole": 0, + "TCPFastOpenCookieReqd": 0, + "TCPFastOpenListenOverflow": 0, + "TCPFastOpenPassive": 0, + "TCPFastOpenPassiveFail": 0, + "TCPFastRetrans": 5324, + "TCPFromZeroWindowAdv": 977, + "TCPFullUndo": 3, + "TCPHPAcks": 4648338, + "TCPHPHits": 22005367, + "TCPHystartDelayCwnd": 3535, + "TCPHystartDelayDetect": 24, + "TCPHystartTrainCwnd": 4609, + "TCPHystartTrainDetect": 205, + "TCPKeepAlive": 312560, + "TCPLossFailures": 1, + "TCPLossProbeRecovery": 387, + "TCPLossProbes": 12748, + "TCPLossUndo": 437, + "TCPLostRetransmit": 1499, + "TCPMD5Failure": 0, + "TCPMD5NotFound": 0, + "TCPMD5Unexpected": 0, + "TCPMTUPFail": 0, + "TCPMTUPSuccess": 0, + "TCPMemoryPressures": 0, + "TCPMemoryPressuresChrono": 0, + "TCPMinTTLDrop": 0, + "TCPOFODrop": 0, + "TCPOFOMerge": 13, + "TCPOFOQueue": 266342, + "TCPOrigDataSent": 54724129, + "TCPPartialUndo": 145, + "TCPPureAcks": 6490261, + "TCPRcvCoalesce": 5762438, + "TCPRcvCollapsed": 0, + "TCPRcvQDrop": 0, + "TCPRenoFailures": 0, + "TCPRenoRecovery": 0, + "TCPRenoRecoveryFail": 0, + "TCPRenoReorder": 0, + "TCPReqQFullDoCookies": 0, + "TCPReqQFullDrop": 0, + "TCPRetransFail": 0, + "TCPSACKDiscard": 123, + "TCPSACKReneging": 0, + "TCPSACKReorder": 2707, + "TCPSYNChallenge": 4, + "TCPSackFailures": 5, + "TCPSackMerged": 13758, + "TCPSackRecovery": 241, + "TCPSackRecoveryFail": 3, + "TCPSackShiftFallback": 1455, + "TCPSackShifted": 37107, + "TCPSlowStartRetrans": 2, + "TCPSpuriousRTOs": 3, + "TCPSpuriousRtxHostQueues": 16, + "TCPSynRetrans": 346, + "TCPTSReorder": 732, + "TCPTimeWaitOverflow": 0, + "TCPTimeouts": 2178, + "TCPToZeroWindowAdv": 977, + "TCPWantZeroWindowAdv": 109048, + "TCPWinProbe": 0, + "TCPZeroWindowDrop": 0, + "TW": 1443, + "TWKilled": 0, + "TWRecycled": 0 + }, + "udp": { + "IgnoredMulti": 0, + "InCsumErrors": 0, + "InDatagrams": 31359, + "InErrors": 0, + "NoPorts": 61, + "OutDatagrams": 31756, + "RcvbufErrors": 0, + "SndbufErrors": 0 + }, + "udpLite": { + "IgnoredMulti": 0, + "InCsumErrors": 0, + "InDatagrams": 0, + "InErrors": 0, + "NoPorts": 0, + "OutDatagrams": 0, + "RcvbufErrors": 0, + "SndbufErrors": 0 + } + } + } +} \ No newline at end of file diff --git a/metricbeat/module/system/network_summary/_meta/docs.asciidoc b/metricbeat/module/system/network_summary/_meta/docs.asciidoc new file mode 100644 index 00000000000..854a377dc6b --- /dev/null +++ b/metricbeat/module/system/network_summary/_meta/docs.asciidoc @@ -0,0 +1,6 @@ +The System `network_summary` metricset provides network IO metrics collected from the +operating system. These events are global and sorted by protocol. + +This metricset is available on: + +- Linux diff --git a/metricbeat/module/system/network_summary/_meta/fields.yml b/metricbeat/module/system/network_summary/_meta/fields.yml new file mode 100644 index 00000000000..afbfc2cb147 --- /dev/null +++ b/metricbeat/module/system/network_summary/_meta/fields.yml @@ -0,0 +1,26 @@ +- name: network_summary + type: group + release: beta + description: > + Metrics relating to global network activity + fields: + - name: ip.* + type: object + description: > + IP counters + - name: tcp.* + type: object + description: > + TCP counters + - name: udp.* + type: object + description: > + UDP counters + - name: udp_lite.* + type: object + description: > + UDP Lite counters + - name: icmp.* + type: object + description: > + ICMP counters diff --git a/metricbeat/module/system/network_summary/data.go b/metricbeat/module/system/network_summary/data.go new file mode 100644 index 00000000000..883f0c0d317 --- /dev/null +++ b/metricbeat/module/system/network_summary/data.go @@ -0,0 +1,64 @@ +// 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_summary + +import ( + "github.com/elastic/beats/libbeat/common" + sysinfotypes "github.com/elastic/go-sysinfo/types" +) + +// eventMapping maps the network counters to a MapStr that wil be sent to report.Event +func eventMapping(raw *sysinfotypes.NetworkCountersInfo) common.MapStr { + + eventByProto := common.MapStr{ + "ip": combineMap(raw.Netstat.IPExt, raw.SNMP.IP), + "tcp": combineMap(raw.Netstat.TCPExt, raw.SNMP.TCP), + "udp": raw.SNMP.UDP, + "udp_lite": raw.SNMP.UDPLite, + "icmp": combineMap(raw.SNMP.ICMPMsg, raw.SNMP.ICMP), + } + + // if value, ok := raw.SNMP.TCP["MaxConn"]; ok && value != 0 { + // eventByProto["tcp"].(map) + // } + + return eventByProto +} + +// combineMap concatinates two given maps +func combineMap(map1, map2 map[string]uint64) map[string]interface{} { + var compMap = make(map[string]interface{}) + + for k, v := range map1 { + compMap[k] = checkMaxConn(k, v) + } + for k, v := range map2 { + compMap[k] = checkMaxConn(k, v) + } + return compMap +} + +// checkMaxConn deals with the "oddball" MaxConn value, which is defined by RFC2012 as a integer +// while the other values are going to be unsigned counters +func checkMaxConn(inKey string, in uint64) interface{} { + + if inKey == "MaxConn" { + return int64(in) + } + return in +} diff --git a/metricbeat/module/system/network_summary/network_summary.go b/metricbeat/module/system/network_summary/network_summary.go new file mode 100644 index 00000000000..ff2c7e163bf --- /dev/null +++ b/metricbeat/module/system/network_summary/network_summary.go @@ -0,0 +1,95 @@ +// 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_summary + +import ( + "github.com/pkg/errors" + + "github.com/elastic/beats/libbeat/common/cfgwarn" + "github.com/elastic/beats/metricbeat/mb" + sysinfo "github.com/elastic/go-sysinfo" + sysinfotypes "github.com/elastic/go-sysinfo/types" +) + +// init registers the MetricSet with the central registry as soon as the program +// starts. The New function will be called later to instantiate an instance of +// the MetricSet for each host defined in the module's configuration. After the +// MetricSet has been created then Fetch will begin to be called periodically. +func init() { + mb.Registry.MustAddMetricSet("system", "network_summary", New) +} + +// MetricSet holds any configuration or state information. It must implement +// the mb.MetricSet interface. And this is best achieved by embedding +// mb.BaseMetricSet because it implements all of the required mb.MetricSet +// interface methods except for Fetch. +type MetricSet struct { + mb.BaseMetricSet +} + +// New creates a new instance of the MetricSet. New is responsible for unpacking +// any MetricSet specific configuration options if there are any. +func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + cfgwarn.Beta("The system network_summary metricset is beta.") + + config := struct{}{} + if err := base.Module().UnpackConfig(&config); err != nil { + return nil, err + } + + return &MetricSet{ + BaseMetricSet: base, + }, nil +} + +// Fetch implements the data gathering and data conversion to the right +// format. It publishes the event which is then forwarded to the output. In case +// of an error set the Error field of mb.Event or simply call report.Error(). +func (m *MetricSet) Fetch(report mb.ReporterV2) error { + counterInfo, err := fetchNetStats() + if err != nil { + return errors.Wrap(err, "Error fetching stats") + } + if counterInfo == nil { + return errors.New("NetworkCounters not available on this platform") + } + + report.Event(mb.Event{ + MetricSetFields: eventMapping(counterInfo), + }) + + return nil +} + +// fetchNetStats wraps the go-sysinfo commands, and returns a NetworkCountersInfo struct if one is available +func fetchNetStats() (*sysinfotypes.NetworkCountersInfo, error) { + h, err := sysinfo.Host() + if err != nil { + return nil, errors.Wrap(err, "failed to read self process information") + } + + if vmstatHandle, ok := h.(sysinfotypes.NetworkCounters); ok { + info, err := vmstatHandle.NetworkCounters() + if err != nil { + return nil, errors.Wrap(err, "error getting network counters") + } + return info, nil + } + + return nil, nil +} diff --git a/metricbeat/module/system/network_summary/network_summary_test.go b/metricbeat/module/system/network_summary/network_summary_test.go new file mode 100644 index 00000000000..85eef635b7c --- /dev/null +++ b/metricbeat/module/system/network_summary/network_summary_test.go @@ -0,0 +1,70 @@ +// 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_summary + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/libbeat/common" + mbtest "github.com/elastic/beats/metricbeat/mb/testing" + "github.com/elastic/go-sysinfo/types" +) + +func TestMapping(t *testing.T) { + example := &types.NetworkCountersInfo{ + SNMP: types.SNMP{ + IP: map[string]uint64{"DefaultTTL": 64}, + ICMP: map[string]uint64{"InAddrMaskReps": 5}, + ICMPMsg: map[string]uint64{"InType3": 835}, + TCP: map[string]uint64{"MaxConn": 0xffffffffffffffff}, + UDP: map[string]uint64{"IgnoredMulti": 10}, + UDPLite: map[string]uint64{"IgnoredMulti": 0}, + }, + Netstat: types.Netstat{ + TCPExt: map[string]uint64{"DelayedACKLocked": 111, "DelayedACKLost": 1587, "DelayedACKs": 516004}, + IPExt: map[string]uint64{"InBcastOctets": 431773621, "InBcastPkts": 1686995, "InCEPkts": 0}, + }, + } + + exampleOut := common.MapStr{ + "icmp": map[string]interface{}{"InAddrMaskReps": uint64(5), "InType3": uint64(835)}, + "ip": map[string]interface{}{"DefaultTTL": uint64(64), "InBcastOctets": uint64(431773621), "InBcastPkts": uint64(1686995), "InCEPkts": uint64(0)}, + "tcp": map[string]interface{}{"DelayedACKLocked": uint64(111), "DelayedACKLost": uint64(1587), "DelayedACKs": uint64(516004), "MaxConn": int64(-1)}, + "udp": map[string]uint64{"IgnoredMulti": 10}, + "udp_lite": map[string]uint64{"IgnoredMulti": 0}} + + out := eventMapping(example) + assert.Equal(t, exampleOut, out) +} + +func TestData(t *testing.T) { + f := mbtest.NewReportingMetricSetV2Error(t, getConfig()) + err := mbtest.WriteEventsReporterV2Error(f, t, ".") + if err != nil { + t.Fatal("write", err) + } +} + +func getConfig() map[string]interface{} { + return map[string]interface{}{ + "module": "system", + "metricsets": []string{"network_summary"}, + } +} diff --git a/vendor/github.com/elastic/go-sysinfo/CHANGELOG.md b/vendor/github.com/elastic/go-sysinfo/CHANGELOG.md index 1ba5110496b..32a2db7b4f9 100644 --- a/vendor/github.com/elastic/go-sysinfo/CHANGELOG.md +++ b/vendor/github.com/elastic/go-sysinfo/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [unreleased] +## [Unreleased] ### Added @@ -16,19 +16,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -## [1.2.1] - 2020-1-3 - -### Added +## [1.3.0] - 2020-01-13 ### Changed -### Deprecated +- Convert NetworkCountersInfo maps to uint64 [#75](https://github.com/elastic/go-sysinfo/pull/75) -### Removed +## [1.2.1] - 2020-01-03 ### Fixed -- create a sidToString function to deal with API changes in various versions of golang.org/x/sys/windows [#74](https://github.com/elastic/go-sysinfo/pull/74) +- Create a `sidToString` function to deal with API changes in various versions of golang.org/x/sys/windows. [#74](https://github.com/elastic/go-sysinfo/pull/74) ## [1.2.0] - 2019-12-09 @@ -82,7 +80,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Changed the host containerized check to reduce false positives. [#42](https://github.com/elastic/go-sysinfo/pull/42) [#43](https://github.com/elastic/go-sysinfo/pull/43) -[Unreleased]: https://github.com/elastic/go-sysinfo/compare/v1.2.1...HEAD +[Unreleased]: https://github.com/elastic/go-sysinfo/compare/v1.3.0...HEAD +[1.3.0]: https://github.com/elastic/go-sysinfo/releases/tag/v1.3.0 [1.2.1]: https://github.com/elastic/go-sysinfo/releases/tag/v1.2.1 [1.2.0]: https://github.com/elastic/go-sysinfo/releases/tag/v1.2.0 [1.1.1]: https://github.com/elastic/go-sysinfo/releases/tag/v1.1.0 diff --git a/vendor/github.com/elastic/go-sysinfo/providers/linux/procnet.go b/vendor/github.com/elastic/go-sysinfo/providers/linux/procnet.go index 685d780497e..a2cc286752a 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/linux/procnet.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/linux/procnet.go @@ -29,7 +29,7 @@ import ( ) // fillStruct is some reflection work that can dynamically fill one of our tagged `netstat` structs with netstat data -func fillStruct(str interface{}, data map[string]map[string]int64) { +func fillStruct(str interface{}, data map[string]map[string]uint64) { val := reflect.ValueOf(str).Elem() typ := reflect.TypeOf(str).Elem() @@ -44,7 +44,7 @@ func fillStruct(str interface{}, data map[string]map[string]int64) { } // parseEntry parses two lines from the net files, the first line being keys, the second being values -func parseEntry(line1, line2 string) (map[string]int64, error) { +func parseEntry(line1, line2 string) (map[string]uint64, error) { keyArr := strings.Split(strings.TrimSpace(line1), " ") valueArr := strings.Split(strings.TrimSpace(line2), " ") @@ -52,20 +52,36 @@ func parseEntry(line1, line2 string) (map[string]int64, error) { return nil, errors.New("key and value lines are mismatched") } - counters := make(map[string]int64, len(valueArr)) + counters := make(map[string]uint64, len(valueArr)) for iter, value := range valueArr { - parsed, err := strconv.ParseInt(value, 10, 64) - if err != nil { - return nil, errors.Wrapf(err, "error parsing string to int in line: %#v", valueArr) + + // This if-else block is to deal with the MaxConn value in SNMP, + // which is a signed value according to RFC2012. + // This library emulates the behavior of the kernel: store all values as a uint, then cast to a signed value for printing + // Users of this library need to be aware that this value should be printed as a signed int or hex value to make it useful. + var parsed uint64 + var err error + if strings.Contains(value, "-") { + signedParsed, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return nil, errors.Wrapf(err, "error parsing string to int in line: %#v", valueArr) + } + parsed = uint64(signedParsed) + } else { + parsed, err = strconv.ParseUint(value, 10, 64) + if err != nil { + return nil, errors.Wrapf(err, "error parsing string to int in line: %#v", valueArr) + } } + counters[keyArr[iter]] = parsed } return counters, nil } // parseNetFile parses an entire file, and returns a 2D map, representing how files are sorted by protocol -func parseNetFile(body string) (map[string]map[string]int64, error) { - fileMetrics := make(map[string]map[string]int64) +func parseNetFile(body string) (map[string]map[string]uint64, error) { + fileMetrics := make(map[string]map[string]uint64) bodySplit := strings.Split(strings.TrimSpace(body), "\n") // There should be an even number of lines. If not, something is wrong. if len(bodySplit)%2 != 0 { diff --git a/vendor/github.com/elastic/go-sysinfo/types/host.go b/vendor/github.com/elastic/go-sysinfo/types/host.go index 80db2c8a629..b7472fe6807 100644 --- a/vendor/github.com/elastic/go-sysinfo/types/host.go +++ b/vendor/github.com/elastic/go-sysinfo/types/host.go @@ -32,19 +32,20 @@ type NetworkCounters interface { } // SNMP represents the data from /proc/net/snmp +// Note that according to RFC 2012,TCP.MaxConn, if present, is a signed value and should be cast to int64 type SNMP struct { - IP map[string]int64 `json:"ip" netstat:"Ip"` - ICMP map[string]int64 `json:"icmp" netstat:"Icmp"` - ICMPMsg map[string]int64 `json:"icmp_msg" netstat:"IcmpMsg"` - TCP map[string]int64 `json:"tcp" netstat:"Tcp"` - UDP map[string]int64 `json:"udp" netstat:"Udp"` - UDPLite map[string]int64 `json:"udp_lite" netstat:"UdpLite"` + IP map[string]uint64 `json:"ip" netstat:"Ip"` + ICMP map[string]uint64 `json:"icmp" netstat:"Icmp"` + ICMPMsg map[string]uint64 `json:"icmp_msg" netstat:"IcmpMsg"` + TCP map[string]uint64 `json:"tcp" netstat:"Tcp"` + UDP map[string]uint64 `json:"udp" netstat:"Udp"` + UDPLite map[string]uint64 `json:"udp_lite" netstat:"UdpLite"` } // Netstat represents the data from /proc/net/netstat type Netstat struct { - TCPExt map[string]int64 `json:"tcp_ext" netstat:"TcpExt"` - IPExt map[string]int64 `json:"ip_ext" netstat:"IpExt"` + TCPExt map[string]uint64 `json:"tcp_ext" netstat:"TcpExt"` + IPExt map[string]uint64 `json:"ip_ext" netstat:"IpExt"` } // NetworkCountersInfo represents available network counters from /proc/net diff --git a/vendor/vendor.json b/vendor/vendor.json index e32413fd32c..89ccbcd9517 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -3029,60 +3029,60 @@ "versionExact": "v0.0.6" }, { - "checksumSHA1": "s37l3najJFu22RNPP9udnam+YnU=", + "checksumSHA1": "eV7V/y/SW5Slvn07K1VH0mZmKmg=", "path": "github.com/elastic/go-sysinfo", - "revision": "cee67141de1bdfb666367301f44e559e58b16734", - "revisionTime": "2020-01-03T17:30:45Z", - "version": "v1.2.1", - "versionExact": "v1.2.1" + "revision": "b719bc42e40963c707571af208683a049e61f07f", + "revisionTime": "2020-01-13T16:32:57Z", + "version": "v1.3.0", + "versionExact": "v1.3.0" }, { "checksumSHA1": "GiZCjX17K265TtamGZZw4R2Jwbk=", "path": "github.com/elastic/go-sysinfo/internal/registry", - "revision": "cee67141de1bdfb666367301f44e559e58b16734", - "revisionTime": "2020-01-03T17:30:45Z", - "version": "v1.2.1", - "versionExact": "v1.2.1" + "revision": "b719bc42e40963c707571af208683a049e61f07f", + "revisionTime": "2020-01-13T16:32:57Z", + "version": "v1.3.0", + "versionExact": "v1.3.0" }, { "checksumSHA1": "dVSTUnZHCLNd0tYIENqdj05RyI8=", "path": "github.com/elastic/go-sysinfo/providers/darwin", - "revision": "cee67141de1bdfb666367301f44e559e58b16734", - "revisionTime": "2020-01-03T17:30:45Z", - "version": "v1.2.1", - "versionExact": "v1.2.1" + "revision": "b719bc42e40963c707571af208683a049e61f07f", + "revisionTime": "2020-01-13T16:32:57Z", + "version": "v1.3.0", + "versionExact": "v1.3.0" }, { - "checksumSHA1": "Kc5GlAf7iwLd/d1X68JFM8b12GM=", + "checksumSHA1": "VXUC6tRsvez0VUvpby3AKoS+LVE=", "path": "github.com/elastic/go-sysinfo/providers/linux", - "revision": "cee67141de1bdfb666367301f44e559e58b16734", - "revisionTime": "2020-01-03T17:30:45Z", - "version": "v1.2.1", - "versionExact": "v1.2.1" + "revision": "b719bc42e40963c707571af208683a049e61f07f", + "revisionTime": "2020-01-13T16:32:57Z", + "version": "v1.3.0", + "versionExact": "v1.3.0" }, { "checksumSHA1": "RWLvcP1w9ynKbuCqiW6prwd+EDU=", "path": "github.com/elastic/go-sysinfo/providers/shared", - "revision": "cee67141de1bdfb666367301f44e559e58b16734", - "revisionTime": "2020-01-03T17:30:45Z", - "version": "v1.2.1", - "versionExact": "v1.2.1" + "revision": "b719bc42e40963c707571af208683a049e61f07f", + "revisionTime": "2020-01-13T16:32:57Z", + "version": "v1.3.0", + "versionExact": "v1.3.0" }, { "checksumSHA1": "SI4WoiEzBJFS73GRQV6EsfA90RI=", "path": "github.com/elastic/go-sysinfo/providers/windows", - "revision": "cee67141de1bdfb666367301f44e559e58b16734", - "revisionTime": "2020-01-03T17:30:45Z", - "version": "v1.2.1", - "versionExact": "v1.2.1" + "revision": "b719bc42e40963c707571af208683a049e61f07f", + "revisionTime": "2020-01-13T16:32:57Z", + "version": "v1.3.0", + "versionExact": "v1.3.0" }, { - "checksumSHA1": "dtxTdCkTAMgGmJS7Bn5jDXsQ8nA=", + "checksumSHA1": "MCYCYQjbvgi5ddkf20pp4SqWnBA=", "path": "github.com/elastic/go-sysinfo/types", - "revision": "cee67141de1bdfb666367301f44e559e58b16734", - "revisionTime": "2020-01-03T17:30:45Z", - "version": "v1.2.1", - "versionExact": "v1.2.1" + "revision": "b719bc42e40963c707571af208683a049e61f07f", + "revisionTime": "2020-01-13T16:32:57Z", + "version": "v1.3.0", + "versionExact": "v1.3.0" }, { "checksumSHA1": "rdM+Flia4oo089kLcUUmogtO444=",