Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(inputs.internet_speed): support packet loss #15329

Merged
merged 8 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ require (
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/sensu/sensu-go/api/core/v2 v2.16.0
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/sirupsen/logrus v1.9.3
github.com/sleepinggenius2/gosmi v0.4.4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
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.6.10/go.mod h1:uLgdWCNarXxlYsL2E5TOZpCIwpgSWnEANZp7gfHXHu0=
github.com/showwin/speedtest-go v1.7.5 h1:FQ3EdM2vnfw5BRCRzGCYe8aWu70rr21Az5ZFHiW9CdE=
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/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=
Expand Down
20 changes: 11 additions & 9 deletions plugins/inputs/internet_speed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
## however, setting to "multi" will reach out to multiple servers in an
## attempt to get closer to ideal internet speeds.
## And "multi" will use all available servers to calculate average packet loss.
# test_mode = "single"

## Server ID exclude filter
Expand All @@ -63,24 +64,25 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.

It collects the following fields:

| Name | field name | type | Unit |
|----------------|------------| ------- | ---- |
| Download Speed | download | float64 | Mbps |
| Upload Speed | upload | float64 | Mbps |
| Latency | latency | float64 | ms |
| Jitter | jitter | float64 | ms |
| Location | location | string | - |
| Name | Field Name | Type | Unit |
|----------------|-------------|---------|------------|
| Download Speed | download | float64 | Mbps |
| Upload Speed | upload | float64 | Mbps |
| Latency | latency | float64 | ms |
| Jitter | jitter | float64 | ms |
| Packet Loss | packet_loss | float64 | percentage |
| Location | location | string | - |

And the following tags:

| Name | tag name |
| --------- | --------- |
|-----------|-----------|
| Source | source |
| Server ID | server_id |
| Test Mode | test_mode |

## Example Output

```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
```
38 changes: 30 additions & 8 deletions plugins/inputs/internet_speed/internet_speed.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/showwin/speedtest-go/speedtest"
"github.com/showwin/speedtest-go/speedtest/transport"

"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/filter"
Expand Down Expand Up @@ -83,6 +84,13 @@ func (is *InternetSpeed) Gather(acc telegraf.Accumulator) error {
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 {
err = is.server.MultiDownloadTestContext(context.Background(), is.servers)
if err != nil {
Expand All @@ -92,6 +100,7 @@ func (is *InternetSpeed) Gather(acc telegraf.Accumulator) error {
if err != nil {
return fmt.Errorf("upload test failed failed: %w", err)
}
pLoss, _ = analyzer.RunMulti(is.servers.Hosts())
r3inbowari marked this conversation as resolved.
Show resolved Hide resolved
} else {
err = is.server.DownloadTest()
if err != nil {
Expand All @@ -101,14 +110,27 @@ func (is *InternetSpeed) Gather(acc telegraf.Accumulator) error {
if err != nil {
return fmt.Errorf("upload test failed failed: %w", err)
}
_ = analyzer.Run(is.server.Host, func(packetLoss *transport.PLoss) {
r3inbowari marked this conversation as resolved.
Show resolved Hide resolved
if packetLoss != nil && packetLoss.Sent != 0 {
pLoss = packetLoss.Loss()
}
})
}

lossPercent := 0.0
if pLoss == -1 {
lossPercent = -1
} else {
lossPercent = pLoss * 100.0
}

fields := map[string]any{
"download": is.server.DLSpeed,
"upload": is.server.ULSpeed,
"latency": timeDurationMillisecondToFloat64(is.server.Latency),
"jitter": timeDurationMillisecondToFloat64(is.server.Jitter),
"location": is.server.Name,
"download": is.server.DLSpeed.Mbps(),
"upload": is.server.ULSpeed.Mbps(),
"latency": timeDurationMillisecondToFloat64(is.server.Latency),
"jitter": timeDurationMillisecondToFloat64(is.server.Jitter),
"packet_loss": lossPercent,
"location": is.server.Name,
}
tags := map[string]string{
"server_id": is.server.ID,
Expand Down Expand Up @@ -148,16 +170,16 @@ func (is *InternetSpeed) findClosestServer() error {

// Return the first match or the server with the lowest latency
// when filter mismatch all servers.
var min int64 = math.MaxInt64
var minLatency int64 = math.MaxInt64
selectIndex := -1
for index, server := range is.servers {
if is.serverFilter.Match(server.ID) {
selectIndex = index
break
}
if server.Latency > 0 {
if min > server.Latency.Milliseconds() {
min = server.Latency.Milliseconds()
if minLatency > server.Latency.Milliseconds() {
minLatency = server.Latency.Milliseconds()
selectIndex = index
}
}
Expand Down
1 change: 1 addition & 0 deletions plugins/inputs/internet_speed/sample.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
## 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
## attempt to get closer to ideal internet speeds.
## And "multi" will use all available servers to calculate average packet loss.
# test_mode = "single"

## Server ID exclude filter
Expand Down
Loading