feat(inputs.internet_speed): Introduce packet loss field (#15329)
This commit is contained in:
parent
8284e21e87
commit
afd7f93355
2
go.mod
2
go.mod
|
|
@ -171,7 +171,7 @@ require (
|
||||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
|
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
|
||||||
github.com/sensu/sensu-go/api/core/v2 v2.16.0
|
github.com/sensu/sensu-go/api/core/v2 v2.16.0
|
||||||
github.com/shirou/gopsutil/v3 v3.24.4
|
github.com/shirou/gopsutil/v3 v3.24.4
|
||||||
github.com/showwin/speedtest-go v1.6.10
|
github.com/showwin/speedtest-go v1.7.5
|
||||||
github.com/signalfx/golib/v3 v3.3.53
|
github.com/signalfx/golib/v3 v3.3.53
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/sleepinggenius2/gosmi v0.4.4
|
github.com/sleepinggenius2/gosmi v0.4.4
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -2128,8 +2128,8 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz
|
||||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||||
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
github.com/showwin/speedtest-go v1.6.10 h1:dPxr1gVOu30KvMNl2L8UZD937Ge7zsZW0JulzYpyP48=
|
github.com/showwin/speedtest-go v1.7.5 h1:FQ3EdM2vnfw5BRCRzGCYe8aWu70rr21Az5ZFHiW9CdE=
|
||||||
github.com/showwin/speedtest-go v1.6.10/go.mod h1:uLgdWCNarXxlYsL2E5TOZpCIwpgSWnEANZp7gfHXHu0=
|
github.com/showwin/speedtest-go v1.7.5/go.mod h1:uLgdWCNarXxlYsL2E5TOZpCIwpgSWnEANZp7gfHXHu0=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/signalfx/com_signalfx_metrics_protobuf v0.0.3 h1:32k2QLgsKhcEs55q4REPKyIadvid5FPy2+VMgvbmKJ0=
|
github.com/signalfx/com_signalfx_metrics_protobuf v0.0.3 h1:32k2QLgsKhcEs55q4REPKyIadvid5FPy2+VMgvbmKJ0=
|
||||||
github.com/signalfx/com_signalfx_metrics_protobuf v0.0.3/go.mod h1:gJrXWi7wSGXfiC7+VheQaz+ypdCt5SmZNL+BRxUe7y4=
|
github.com/signalfx/com_signalfx_metrics_protobuf v0.0.3/go.mod h1:gJrXWi7wSGXfiC7+VheQaz+ypdCt5SmZNL+BRxUe7y4=
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||||
## By default, a single sever is used for testing. This may work for most,
|
## By default, a single sever is used for testing. This may work for most,
|
||||||
## however, setting to "multi" will reach out to multiple servers in an
|
## however, setting to "multi" will reach out to multiple servers in an
|
||||||
## attempt to get closer to ideal internet speeds.
|
## attempt to get closer to ideal internet speeds.
|
||||||
|
## And "multi" will use all available servers to calculate average packet loss.
|
||||||
# test_mode = "single"
|
# test_mode = "single"
|
||||||
|
|
||||||
## Server ID exclude filter
|
## Server ID exclude filter
|
||||||
|
|
@ -63,18 +64,21 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||||
|
|
||||||
It collects the following fields:
|
It collects the following fields:
|
||||||
|
|
||||||
| Name | field name | type | Unit |
|
| Name | Field Name | Type | Unit |
|
||||||
|----------------|------------| ------- | ---- |
|
|----------------|-------------|---------|------------|
|
||||||
| Download Speed | download | float64 | Mbps |
|
| Download Speed | download | float64 | Mbps |
|
||||||
| Upload Speed | upload | float64 | Mbps |
|
| Upload Speed | upload | float64 | Mbps |
|
||||||
| Latency | latency | float64 | ms |
|
| Latency | latency | float64 | ms |
|
||||||
| Jitter | jitter | float64 | ms |
|
| Jitter | jitter | float64 | ms |
|
||||||
|
| Packet Loss | packet_loss | float64 | percentage |
|
||||||
| Location | location | string | - |
|
| Location | location | string | - |
|
||||||
|
|
||||||
|
The `packet_loss` will return -1, if packet loss not applicable.
|
||||||
|
|
||||||
And the following tags:
|
And the following tags:
|
||||||
|
|
||||||
| Name | tag name |
|
| Name | tag name |
|
||||||
| --------- | --------- |
|
|-----------|-----------|
|
||||||
| Source | source |
|
| Source | source |
|
||||||
| Server ID | server_id |
|
| Server ID | server_id |
|
||||||
| Test Mode | test_mode |
|
| Test Mode | test_mode |
|
||||||
|
|
@ -82,5 +86,6 @@ And the following tags:
|
||||||
## Example Output
|
## Example Output
|
||||||
|
|
||||||
```text
|
```text
|
||||||
internet_speed,source=speedtest02.z4internet.com:8080,server_id=54619,test_mode=single download=318.37580265897725,upload=30.444407341274385,latency=37.73174,jitter=1.99810,location="Somewhere, TX" 1675458921000000000
|
internet_speed,source=speedtest02.z4internet.com:8080,server_id=54619,test_mode=single download=318.37580265897725,upload=30.444407341274385,latency=37.73174,jitter=1.99810,packet_loss=0.05377,location="Somewhere, TX" 1675458921000000000
|
||||||
|
internet_speed,source=speedtest02.z4internet.com:8080,server_id=54619,test_mode=multi download=318.37580265897725,upload=30.444407341274385,latency=37.73174,jitter=1.99810,packet_loss=-1,location="Somewhere, TX" 1675458921000000000
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/showwin/speedtest-go/speedtest"
|
"github.com/showwin/speedtest-go/speedtest"
|
||||||
|
"github.com/showwin/speedtest-go/speedtest/transport"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
"github.com/influxdata/telegraf/filter"
|
"github.com/influxdata/telegraf/filter"
|
||||||
|
|
@ -83,6 +84,13 @@ func (is *InternetSpeed) Gather(acc telegraf.Accumulator) error {
|
||||||
return fmt.Errorf("ping test failed: %w", err)
|
return fmt.Errorf("ping test failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analyzer := speedtest.NewPacketLossAnalyzer(&speedtest.PacketLossAnalyzerOptions{
|
||||||
|
PacketSendingInterval: time.Millisecond * 100,
|
||||||
|
SamplingDuration: time.Second * 15,
|
||||||
|
})
|
||||||
|
|
||||||
|
pLoss := -1.0
|
||||||
|
|
||||||
if is.TestMode == testModeMulti {
|
if is.TestMode == testModeMulti {
|
||||||
err = is.server.MultiDownloadTestContext(context.Background(), is.servers)
|
err = is.server.MultiDownloadTestContext(context.Background(), is.servers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -90,7 +98,13 @@ func (is *InternetSpeed) Gather(acc telegraf.Accumulator) error {
|
||||||
}
|
}
|
||||||
err = is.server.MultiUploadTestContext(context.Background(), is.servers)
|
err = is.server.MultiUploadTestContext(context.Background(), is.servers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("upload test failed failed: %w", err)
|
return fmt.Errorf("upload test failed: %w", err)
|
||||||
|
}
|
||||||
|
// Not all servers are applicable for packet loss testing.
|
||||||
|
// If err != nil, we skip it and just report a warning.
|
||||||
|
pLoss, err = analyzer.RunMulti(is.servers.Hosts())
|
||||||
|
if err != nil {
|
||||||
|
is.Log.Warnf("packet loss test failed: %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = is.server.DownloadTest()
|
err = is.server.DownloadTest()
|
||||||
|
|
@ -99,15 +113,34 @@ func (is *InternetSpeed) Gather(acc telegraf.Accumulator) error {
|
||||||
}
|
}
|
||||||
err = is.server.UploadTest()
|
err = is.server.UploadTest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("upload test failed failed: %w", err)
|
return fmt.Errorf("upload test failed: %w", err)
|
||||||
|
}
|
||||||
|
// Not all servers are applicable for packet loss testing.
|
||||||
|
// If err != nil, we skip it and just report a warning.
|
||||||
|
err = analyzer.Run(is.server.Host, func(packetLoss *transport.PLoss) {
|
||||||
|
if packetLoss != nil && packetLoss.Sent != 0 {
|
||||||
|
pLoss = packetLoss.Loss()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
is.Log.Warnf("packet loss test failed: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lossPercent := 0.0
|
||||||
|
if pLoss == -1 {
|
||||||
|
// If all servers are not applicable, returned -1.
|
||||||
|
lossPercent = -1
|
||||||
|
} else {
|
||||||
|
lossPercent = pLoss * 100.0
|
||||||
|
}
|
||||||
|
|
||||||
fields := map[string]any{
|
fields := map[string]any{
|
||||||
"download": is.server.DLSpeed,
|
"download": is.server.DLSpeed.Mbps(),
|
||||||
"upload": is.server.ULSpeed,
|
"upload": is.server.ULSpeed.Mbps(),
|
||||||
"latency": timeDurationMillisecondToFloat64(is.server.Latency),
|
"latency": timeDurationMillisecondToFloat64(is.server.Latency),
|
||||||
"jitter": timeDurationMillisecondToFloat64(is.server.Jitter),
|
"jitter": timeDurationMillisecondToFloat64(is.server.Jitter),
|
||||||
|
"packet_loss": lossPercent,
|
||||||
"location": is.server.Name,
|
"location": is.server.Name,
|
||||||
}
|
}
|
||||||
tags := map[string]string{
|
tags := map[string]string{
|
||||||
|
|
@ -148,7 +181,7 @@ func (is *InternetSpeed) findClosestServer() error {
|
||||||
|
|
||||||
// Return the first match or the server with the lowest latency
|
// Return the first match or the server with the lowest latency
|
||||||
// when filter mismatch all servers.
|
// when filter mismatch all servers.
|
||||||
var min int64 = math.MaxInt64
|
var minLatency int64 = math.MaxInt64
|
||||||
selectIndex := -1
|
selectIndex := -1
|
||||||
for index, server := range is.servers {
|
for index, server := range is.servers {
|
||||||
if is.serverFilter.Match(server.ID) {
|
if is.serverFilter.Match(server.ID) {
|
||||||
|
|
@ -156,8 +189,8 @@ func (is *InternetSpeed) findClosestServer() error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if server.Latency > 0 {
|
if server.Latency > 0 {
|
||||||
if min > server.Latency.Milliseconds() {
|
if minLatency > server.Latency.Milliseconds() {
|
||||||
min = server.Latency.Milliseconds()
|
minLatency = server.Latency.Milliseconds()
|
||||||
selectIndex = index
|
selectIndex = index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
## By default, a single sever is used for testing. This may work for most,
|
## By default, a single sever is used for testing. This may work for most,
|
||||||
## however, setting to "multi" will reach out to multiple servers in an
|
## however, setting to "multi" will reach out to multiple servers in an
|
||||||
## attempt to get closer to ideal internet speeds.
|
## attempt to get closer to ideal internet speeds.
|
||||||
|
## And "multi" will use all available servers to calculate average packet loss.
|
||||||
# test_mode = "single"
|
# test_mode = "single"
|
||||||
|
|
||||||
## Server ID exclude filter
|
## Server ID exclude filter
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue