chore: Fix linter findings for Windows (part4) (#13246)

Co-authored-by: Pawel Zak <Pawel Zak>
Co-authored-by: pzak <pzak>
This commit is contained in:
Paweł Żak 2023-06-09 10:24:43 +02:00 committed by GitHub
parent 8b815cb193
commit a2f65d5728
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 275 additions and 242 deletions

View File

@ -4,10 +4,10 @@ package agent
import "os" import "os"
func watchForFlushSignal(flushRequested chan os.Signal) { func watchForFlushSignal(_ chan os.Signal) {
// not supported // not supported
} }
func stopListeningForFlushSignal(flushRequested chan os.Signal) { func stopListeningForFlushSignal(_ chan os.Signal) {
// not supported // not supported
} }

View File

@ -75,7 +75,7 @@ type program struct {
*Telegraf *Telegraf
} }
func (p *program) Start(s service.Service) error { func (p *program) Start(_ service.Service) error {
go func() { go func() {
stop = make(chan struct{}) stop = make(chan struct{})
err := p.reloadLoop() err := p.reloadLoop()
@ -87,14 +87,7 @@ func (p *program) Start(s service.Service) error {
return nil return nil
} }
func (p *program) run(errChan chan error) { func (p *program) Stop(_ service.Service) error {
stop = make(chan struct{})
err := p.reloadLoop()
errChan <- err
close(stop)
}
func (p *program) Stop(s service.Service) error {
var empty struct{} var empty struct{}
stop <- empty // signal reloadLoop to finish (context cancel) stop <- empty // signal reloadLoop to finish (context cancel)
<-stop // wait for reloadLoop to finish and close channel <-stop // wait for reloadLoop to finish and close channel

View File

@ -48,7 +48,7 @@ type eventLoggerCreator struct {
logger *eventlog.Log logger *eventlog.Log
} }
func (e *eventLoggerCreator) CreateLogger(config LogConfig) (io.Writer, error) { func (e *eventLoggerCreator) CreateLogger(_ LogConfig) (io.Writer, error) {
return wlog.NewWriter(&eventLogger{logger: e.logger}), nil return wlog.NewWriter(&eventLogger{logger: e.logger}), nil
} }

View File

@ -15,7 +15,6 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
```toml @sample.conf ```toml @sample.conf
# Read metrics about disk IO by device # Read metrics about disk IO by device
# This plugin ONLY supports Linux
[[inputs.diskio]] [[inputs.diskio]]
## By default, telegraf will gather stats for all devices including ## By default, telegraf will gather stats for all devices including
## disk partitions. ## disk partitions.

View File

@ -1,5 +1,4 @@
# Read metrics about disk IO by device # Read metrics about disk IO by device
# This plugin ONLY supports Linux
[[inputs.diskio]] [[inputs.diskio]]
## By default, telegraf will gather stats for all devices including ## By default, telegraf will gather stats for all devices including
## disk partitions. ## disk partitions.

View File

@ -12,7 +12,7 @@ import (
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
) )
func (e *Execd) Gather(acc telegraf.Accumulator) error { func (e *Execd) Gather(_ telegraf.Accumulator) error {
if e.process == nil { if e.process == nil {
return nil return nil
} }

View File

@ -1,15 +1,13 @@
package filecount package filecount
import ( import (
"errors"
"io" "io"
"os" "os"
"time"
) )
/* /*
The code below is lifted from numerous articles and originates from Andrew Gerrand's 10 things you (probably) don't know about Go. The code below is lifted from numerous articles and originates from Andrew Gerrand's 10 things you (probably) don't know about Go.
it allows for mocking a filesystem; this allows for consistent testing of this code across platforms (directory sizes reported It allows for mocking a filesystem; this allows for consistent testing of this code across platforms (directory sizes reported
differently by different platforms, for example), while preserving the rest of the functionality as-is, without modification. differently by different platforms, for example), while preserving the rest of the functionality as-is, without modification.
*/ */
@ -31,42 +29,3 @@ type osFS struct{}
func (osFS) Open(name string) (file, error) { return os.Open(name) } func (osFS) Open(name string) (file, error) { return os.Open(name) }
func (osFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) } func (osFS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) }
/*
The following are for mocking the filesystem - this allows us to mock Stat() files. This means that we can set file attributes, and know that they
will be the same regardless of the platform sitting underneath our tests (directory sizes vary see https://github.com/influxdata/telegraf/issues/6011)
NOTE: still need the on-disk file structure to mirror this because the 3rd party library ("github.com/karrick/godirwalk") uses its own
walk functions, that we cannot mock from here.
*/
type fakeFileSystem struct {
files map[string]fakeFileInfo
}
type fakeFileInfo struct {
name string
size int64
filemode uint32
modtime time.Time
isdir bool
sys interface{}
}
func (f fakeFileInfo) Name() string { return f.name }
func (f fakeFileInfo) Size() int64 { return f.size }
func (f fakeFileInfo) Mode() os.FileMode { return os.FileMode(f.filemode) }
func (f fakeFileInfo) ModTime() time.Time { return f.modtime }
func (f fakeFileInfo) IsDir() bool { return f.isdir }
func (f fakeFileInfo) Sys() interface{} { return f.sys }
func (f fakeFileSystem) Open(name string) (file, error) {
return nil, &os.PathError{Op: "Open", Path: name, Err: errors.New("Not implemented by fake filesystem")}
}
func (f fakeFileSystem) Stat(name string) (os.FileInfo, error) {
if fakeInfo, found := f.files[name]; found {
return fakeInfo, nil
}
return nil, &os.PathError{Op: "Stat", Path: name, Err: errors.New("No such file or directory")}
}

View File

@ -0,0 +1,52 @@
//go:build !windows
// TODO: These types are not used in Windows tests because they are disabled for Windows.
// They can be moved to filesystem_helpers.go when following bug is fixed:
// https://github.com/influxdata/telegraf/issues/6248
package filecount
import (
"errors"
"os"
"time"
)
/*
The following are for mocking the filesystem - this allows us to mock Stat() files. This means that we can set file attributes, and know that they
will be the same regardless of the platform sitting underneath our tests (directory sizes vary see https://github.com/influxdata/telegraf/issues/6011)
NOTE: still need the on-disk file structure to mirror this because the 3rd party library ("github.com/karrick/godirwalk") uses its own
walk functions, that we cannot mock from here.
*/
type fakeFileSystem struct {
files map[string]fakeFileInfo
}
type fakeFileInfo struct {
name string
size int64
filemode uint32
modtime time.Time
isdir bool
sys interface{}
}
func (f fakeFileInfo) Name() string { return f.name }
func (f fakeFileInfo) Size() int64 { return f.size }
func (f fakeFileInfo) Mode() os.FileMode { return os.FileMode(f.filemode) }
func (f fakeFileInfo) ModTime() time.Time { return f.modtime }
func (f fakeFileInfo) IsDir() bool { return f.isdir }
func (f fakeFileInfo) Sys() interface{} { return f.sys }
func (f fakeFileSystem) Open(name string) (file, error) {
return nil, &os.PathError{Op: "Open", Path: name, Err: errors.New("not implemented by fake filesystem")}
}
func (f fakeFileSystem) Stat(name string) (os.FileInfo, error) {
if fakeInfo, found := f.files[name]; found {
return fakeInfo, nil
}
return nil, &os.PathError{Op: "Stat", Path: name, Err: errors.New("no such file or directory")}
}

View File

@ -70,7 +70,7 @@ type Ping struct {
Binary string Binary string
// Arguments for ping command. When arguments is not empty, system binary will be used and // Arguments for ping command. When arguments is not empty, system binary will be used and
// other options (ping_interval, timeout, etc) will be ignored // other options (ping_interval, timeout, etc.) will be ignored
Arguments []string Arguments []string
// Whether to resolve addresses using ipv6 or not. // Whether to resolve addresses using ipv6 or not.
@ -88,20 +88,6 @@ type Ping struct {
Size *int Size *int
} }
type roundTripTimeStats struct {
min float64
avg float64
max float64
stddev float64
}
type stats struct {
trans int
recv int
ttl int
roundTripTimeStats
}
func (*Ping) SampleConfig() string { func (*Ping) SampleConfig() string {
return sampleConfig return sampleConfig
} }

View File

@ -15,6 +15,20 @@ import (
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
) )
type roundTripTimeStats struct {
min float64
avg float64
max float64
stddev float64
}
type statistics struct {
packetsTransmitted int
packetsReceived int
ttl int
roundTripTimeStats
}
func (p *Ping) pingToURL(u string, acc telegraf.Accumulator) { func (p *Ping) pingToURL(u string, acc telegraf.Accumulator) {
tags := map[string]string{"url": u} tags := map[string]string{"url": u}
fields := map[string]interface{}{"result_code": 0} fields := map[string]interface{}{"result_code": 0}
@ -67,11 +81,11 @@ func (p *Ping) pingToURL(u string, acc telegraf.Accumulator) {
} }
// Calculate packet loss percentage // Calculate packet loss percentage
loss := float64(stats.trans-stats.recv) / float64(stats.trans) * 100.0 percentPacketLoss := float64(stats.packetsTransmitted-stats.packetsReceived) / float64(stats.packetsTransmitted) * 100.0
fields["packets_transmitted"] = stats.trans fields["packets_transmitted"] = stats.packetsTransmitted
fields["packets_received"] = stats.recv fields["packets_received"] = stats.packetsReceived
fields["percent_packet_loss"] = loss fields["percent_packet_loss"] = percentPacketLoss
if stats.ttl >= 0 { if stats.ttl >= 0 {
fields["ttl"] = stats.ttl fields["ttl"] = stats.ttl
} }
@ -165,10 +179,10 @@ func (p *Ping) args(url string, system string) []string {
// round-trip min/avg/max/stddev = 34.843/43.508/52.172/8.664 ms // round-trip min/avg/max/stddev = 34.843/43.508/52.172/8.664 ms
// //
// It returns (<transmitted packets>, <received packets>, <average response>) // It returns (<transmitted packets>, <received packets>, <average response>)
func processPingOutput(out string) (stats, error) { func processPingOutput(out string) (statistics, error) {
stats := stats{ stats := statistics{
trans: 0, packetsTransmitted: 0,
recv: 0, packetsReceived: 0,
ttl: -1, ttl: -1,
roundTripTimeStats: roundTripTimeStats{ roundTripTimeStats: roundTripTimeStats{
min: -1.0, min: -1.0,
@ -186,7 +200,7 @@ func processPingOutput(out string) (stats, error) {
if stats.ttl == -1 && (strings.Contains(line, "ttl=") || strings.Contains(line, "hlim=")) { if stats.ttl == -1 && (strings.Contains(line, "ttl=") || strings.Contains(line, "hlim=")) {
stats.ttl, err = getTTL(line) stats.ttl, err = getTTL(line)
} else if strings.Contains(line, "transmitted") && strings.Contains(line, "received") { } else if strings.Contains(line, "transmitted") && strings.Contains(line, "received") {
stats.trans, stats.recv, err = getPacketStats(line) stats.packetsTransmitted, stats.packetsReceived, err = getPacketStats(line)
if err != nil { if err != nil {
return stats, err return stats, err
} }

View File

@ -82,8 +82,8 @@ func TestProcessPingOutput(t *testing.T) {
stats, err := processPingOutput(bsdPingOutput) stats, err := processPingOutput(bsdPingOutput)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 55, stats.ttl, "ttl value is 55") require.Equal(t, 55, stats.ttl, "ttl value is 55")
require.Equal(t, 5, stats.trans, "5 packets were transmitted") require.Equal(t, 5, stats.packetsTransmitted, "5 packets were transmitted")
require.Equal(t, 5, stats.recv, "5 packets were received") require.Equal(t, 5, stats.packetsReceived, "5 packets were received")
require.InDelta(t, 15.087, stats.min, 0.001) require.InDelta(t, 15.087, stats.min, 0.001)
require.InDelta(t, 20.224, stats.avg, 0.001) require.InDelta(t, 20.224, stats.avg, 0.001)
require.InDelta(t, 27.263, stats.max, 0.001) require.InDelta(t, 27.263, stats.max, 0.001)
@ -92,8 +92,8 @@ func TestProcessPingOutput(t *testing.T) {
stats, err = processPingOutput(freebsdPing6Output) stats, err = processPingOutput(freebsdPing6Output)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 117, stats.ttl, "ttl value is 117") require.Equal(t, 117, stats.ttl, "ttl value is 117")
require.Equal(t, 5, stats.trans, "5 packets were transmitted") require.Equal(t, 5, stats.packetsTransmitted, "5 packets were transmitted")
require.Equal(t, 5, stats.recv, "5 packets were received") require.Equal(t, 5, stats.packetsReceived, "5 packets were received")
require.InDelta(t, 35.727, stats.min, 0.001) require.InDelta(t, 35.727, stats.min, 0.001)
require.InDelta(t, 53.211, stats.avg, 0.001) require.InDelta(t, 53.211, stats.avg, 0.001)
require.InDelta(t, 93.870, stats.max, 0.001) require.InDelta(t, 93.870, stats.max, 0.001)
@ -102,8 +102,8 @@ func TestProcessPingOutput(t *testing.T) {
stats, err = processPingOutput(linuxPingOutput) stats, err = processPingOutput(linuxPingOutput)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 63, stats.ttl, "ttl value is 63") require.Equal(t, 63, stats.ttl, "ttl value is 63")
require.Equal(t, 5, stats.trans, "5 packets were transmitted") require.Equal(t, 5, stats.packetsTransmitted, "5 packets were transmitted")
require.Equal(t, 5, stats.recv, "5 packets were received") require.Equal(t, 5, stats.packetsReceived, "5 packets were received")
require.InDelta(t, 35.225, stats.min, 0.001) require.InDelta(t, 35.225, stats.min, 0.001)
require.InDelta(t, 43.628, stats.avg, 0.001) require.InDelta(t, 43.628, stats.avg, 0.001)
require.InDelta(t, 51.806, stats.max, 0.001) require.InDelta(t, 51.806, stats.max, 0.001)
@ -112,8 +112,8 @@ func TestProcessPingOutput(t *testing.T) {
stats, err = processPingOutput(busyBoxPingOutput) stats, err = processPingOutput(busyBoxPingOutput)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 56, stats.ttl, "ttl value is 56") require.Equal(t, 56, stats.ttl, "ttl value is 56")
require.Equal(t, 4, stats.trans, "4 packets were transmitted") require.Equal(t, 4, stats.packetsTransmitted, "4 packets were transmitted")
require.Equal(t, 4, stats.recv, "4 packets were received") require.Equal(t, 4, stats.packetsReceived, "4 packets were received")
require.InDelta(t, 15.810, stats.min, 0.001) require.InDelta(t, 15.810, stats.min, 0.001)
require.InDelta(t, 17.611, stats.avg, 0.001) require.InDelta(t, 17.611, stats.avg, 0.001)
require.InDelta(t, 22.559, stats.max, 0.001) require.InDelta(t, 22.559, stats.max, 0.001)
@ -139,8 +139,8 @@ func TestProcessPingOutputWithVaryingTTL(t *testing.T) {
stats, err := processPingOutput(linuxPingOutputWithVaryingTTL) stats, err := processPingOutput(linuxPingOutputWithVaryingTTL)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 63, stats.ttl, "ttl value is 63") require.Equal(t, 63, stats.ttl, "ttl value is 63")
require.Equal(t, 5, stats.trans, "5 packets were transmitted") require.Equal(t, 5, stats.packetsTransmitted, "5 packets were transmitted")
require.Equal(t, 5, stats.recv, "5 packets were transmitted") require.Equal(t, 5, stats.packetsReceived, "5 packets were transmitted")
require.InDelta(t, 35.225, stats.min, 0.001) require.InDelta(t, 35.225, stats.min, 0.001)
require.InDelta(t, 43.628, stats.avg, 0.001) require.InDelta(t, 43.628, stats.avg, 0.001)
require.InDelta(t, 51.806, stats.max, 0.001) require.InDelta(t, 51.806, stats.max, 0.001)

View File

@ -12,6 +12,19 @@ import (
"github.com/influxdata/telegraf" "github.com/influxdata/telegraf"
) )
type roundTripTimeStats struct {
min int
avg int
max int
}
type statistics struct {
packetsTransmitted int
replyReceived int
packetsReceived int
roundTripTimeStats
}
func (p *Ping) pingToURL(host string, acc telegraf.Accumulator) { func (p *Ping) pingToURL(host string, acc telegraf.Accumulator) {
tags := map[string]string{"url": host} tags := map[string]string{"url": host}
fields := map[string]interface{}{"result_code": 0} fields := map[string]interface{}{"result_code": 0}
@ -23,14 +36,13 @@ func (p *Ping) pingToURL(host string, acc telegraf.Accumulator) {
} }
out, err := p.pingHost(p.Binary, totalTimeout, args...) out, err := p.pingHost(p.Binary, totalTimeout, args...)
// ping host return exitcode != 0 also when there was no response from host // ping host return exitcode != 0 also when there was no response from host but command was executed successfully
// but command was execute successfully
var pendingError error var pendingError error
if err != nil { if err != nil {
// Combine go err + stderr output // Combine go err + stderr output
pendingError = errors.New(strings.TrimSpace(out) + ", " + err.Error()) pendingError = errors.New(strings.TrimSpace(out) + ", " + err.Error())
} }
trans, recReply, receivePacket, avg, min, max, err := processPingOutput(out) stats, err := processPingOutput(out)
if err != nil { if err != nil {
// fatal error // fatal error
if pendingError != nil { if pendingError != nil {
@ -45,22 +57,22 @@ func (p *Ping) pingToURL(host string, acc telegraf.Accumulator) {
return return
} }
// Calculate packet loss percentage // Calculate packet loss percentage
lossReply := float64(trans-recReply) / float64(trans) * 100.0 lossReply := float64(stats.packetsTransmitted-stats.replyReceived) / float64(stats.packetsTransmitted) * 100.0
lossPackets := float64(trans-receivePacket) / float64(trans) * 100.0 lossPackets := float64(stats.packetsTransmitted-stats.packetsReceived) / float64(stats.packetsTransmitted) * 100.0
fields["packets_transmitted"] = trans fields["packets_transmitted"] = stats.packetsTransmitted
fields["reply_received"] = recReply fields["reply_received"] = stats.replyReceived
fields["packets_received"] = receivePacket fields["packets_received"] = stats.packetsReceived
fields["percent_packet_loss"] = lossPackets fields["percent_packet_loss"] = lossPackets
fields["percent_reply_loss"] = lossReply fields["percent_reply_loss"] = lossReply
if avg >= 0 { if stats.avg >= 0 {
fields["average_response_ms"] = float64(avg) fields["average_response_ms"] = float64(stats.avg)
} }
if min >= 0 { if stats.min >= 0 {
fields["minimum_response_ms"] = float64(min) fields["minimum_response_ms"] = float64(stats.min)
} }
if max >= 0 { if stats.max >= 0 {
fields["maximum_response_ms"] = float64(max) fields["maximum_response_ms"] = float64(stats.max)
} }
acc.AddFields("ping", fields, tags) acc.AddFields("ping", fields, tags)
} }
@ -83,61 +95,80 @@ func (p *Ping) args(url string) []string {
} }
// processPingOutput takes in a string output from the ping command // processPingOutput takes in a string output from the ping command
// based on linux implementation but using regex ( multilanguage support ) // based on linux implementation but using regex (multi-language support)
// It returns (<transmitted packets>, <received reply>, <received packet>, <average response>, <min response>, <max response>) // It returns (<transmitted packets>, <received reply>, <received packet>, <average response>, <min response>, <max response>)
func processPingOutput(out string) (int, int, int, int, int, int, error) { func processPingOutput(out string) (statistics, error) {
// So find a line contain 3 numbers except reply lines // So find a line contain 3 numbers except reply lines
var stats, aproxs []string = nil, nil var statsLine, aproxs []string = nil, nil
err := errors.New("fatal error processing ping output") err := errors.New("fatal error processing ping output")
stat := regexp.MustCompile(`=\W*(\d+)\D*=\W*(\d+)\D*=\W*(\d+)`) stat := regexp.MustCompile(`=\W*(\d+)\D*=\W*(\d+)\D*=\W*(\d+)`)
aprox := regexp.MustCompile(`=\W*(\d+)\D*ms\D*=\W*(\d+)\D*ms\D*=\W*(\d+)\D*ms`) aprox := regexp.MustCompile(`=\W*(\d+)\D*ms\D*=\W*(\d+)\D*ms\D*=\W*(\d+)\D*ms`)
tttLine := regexp.MustCompile(`TTL=\d+`) tttLine := regexp.MustCompile(`TTL=\d+`)
lines := strings.Split(out, "\n") lines := strings.Split(out, "\n")
var receivedReply int = 0 var replyReceived = 0
for _, line := range lines { for _, line := range lines {
if tttLine.MatchString(line) { if tttLine.MatchString(line) {
receivedReply++ replyReceived++
} else { } else {
if stats == nil { if statsLine == nil {
stats = stat.FindStringSubmatch(line) statsLine = stat.FindStringSubmatch(line)
} }
if stats != nil && aproxs == nil { if statsLine != nil && aproxs == nil {
aproxs = aprox.FindStringSubmatch(line) aproxs = aprox.FindStringSubmatch(line)
} }
} }
} }
// stats data should contain 4 members: entireExpression + ( Send, Receive, Lost ) stats := statistics{
if len(stats) != 4 { packetsTransmitted: 0,
return 0, 0, 0, -1, -1, -1, err replyReceived: 0,
packetsReceived: 0,
roundTripTimeStats: roundTripTimeStats{
min: -1,
avg: -1,
max: -1,
},
} }
trans, err := strconv.Atoi(stats[1])
// statsLine data should contain 4 members: entireExpression + ( Send, Receive, Lost )
if len(statsLine) != 4 {
return stats, err
}
packetsTransmitted, err := strconv.Atoi(statsLine[1])
if err != nil { if err != nil {
return 0, 0, 0, -1, -1, -1, err return stats, err
} }
receivedPacket, err := strconv.Atoi(stats[2]) packetsReceived, err := strconv.Atoi(statsLine[2])
if err != nil { if err != nil {
return 0, 0, 0, -1, -1, -1, err return stats, err
} }
stats.packetsTransmitted = packetsTransmitted
stats.replyReceived = replyReceived
stats.packetsReceived = packetsReceived
// aproxs data should contain 4 members: entireExpression + ( min, max, avg ) // aproxs data should contain 4 members: entireExpression + ( min, max, avg )
if len(aproxs) != 4 { if len(aproxs) != 4 {
return trans, receivedReply, receivedPacket, -1, -1, -1, err return stats, err
} }
min, err := strconv.Atoi(aproxs[1]) min, err := strconv.Atoi(aproxs[1])
if err != nil { if err != nil {
return trans, receivedReply, receivedPacket, -1, -1, -1, err return stats, err
} }
max, err := strconv.Atoi(aproxs[2]) max, err := strconv.Atoi(aproxs[2])
if err != nil { if err != nil {
return trans, receivedReply, receivedPacket, -1, -1, -1, err return stats, err
} }
avg, err := strconv.Atoi(aproxs[3]) avg, err := strconv.Atoi(aproxs[3])
if err != nil { if err != nil {
return 0, 0, 0, -1, -1, -1, err return statistics{}, err
} }
return trans, receivedReply, receivedPacket, avg, min, max, err stats.avg = avg
stats.min = min
stats.max = max
return stats, err
} }
func (p *Ping) timeout() float64 { func (p *Ping) timeout() float64 {

View File

@ -42,26 +42,26 @@ Approximate round trip times in milli-seconds:
` `
func TestHost(t *testing.T) { func TestHost(t *testing.T) {
trans, recReply, recPacket, avg, min, max, err := processPingOutput(winPLPingOutput) stats, err := processPingOutput(winPLPingOutput)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 4, trans, "4 packets were transmitted") require.Equal(t, 4, stats.packetsTransmitted, "4 packets were transmitted")
require.Equal(t, 4, recReply, "4 packets were reply") require.Equal(t, 4, stats.replyReceived, "4 packets were reply")
require.Equal(t, 4, recPacket, "4 packets were received") require.Equal(t, 4, stats.packetsReceived, "4 packets were received")
require.Equal(t, 50, avg, "Average 50") require.Equal(t, 50, stats.avg, "Average 50")
require.Equal(t, 46, min, "Min 46") require.Equal(t, 46, stats.min, "Min 46")
require.Equal(t, 57, max, "max 57") require.Equal(t, 57, stats.max, "max 57")
trans, recReply, recPacket, avg, min, max, err = processPingOutput(winENPingOutput) stats, err = processPingOutput(winENPingOutput)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 4, trans, "4 packets were transmitted") require.Equal(t, 4, stats.packetsTransmitted, "4 packets were transmitted")
require.Equal(t, 4, recReply, "4 packets were reply") require.Equal(t, 4, stats.replyReceived, "4 packets were reply")
require.Equal(t, 4, recPacket, "4 packets were received") require.Equal(t, 4, stats.packetsReceived, "4 packets were received")
require.Equal(t, 50, avg, "Average 50") require.Equal(t, 50, stats.avg, "Average 50")
require.Equal(t, 50, min, "Min 50") require.Equal(t, 50, stats.min, "Min 50")
require.Equal(t, 52, max, "Max 52") require.Equal(t, 52, stats.max, "Max 52")
} }
func mockHostPinger(binary string, timeout float64, args ...string) (string, error) { func mockHostPinger(_ string, _ float64, _ ...string) (string, error) {
return winENPingOutput, nil return winENPingOutput, nil
} }
@ -104,7 +104,7 @@ Statystyka badania ping dla 195.187.242.157:
(100% straty), (100% straty),
` `
func mockErrorHostPinger(binary string, timeout float64, args ...string) (string, error) { func mockErrorHostPinger(_ string, _ float64, _ ...string) (string, error) {
return errorPingOutput, errors.New("No packets received") return errorPingOutput, errors.New("No packets received")
} }
@ -165,7 +165,7 @@ Szacunkowy czas błądzenia pakietów w millisekundach:
Minimum = 114 ms, Maksimum = 119 ms, Czas średni = 115 ms Minimum = 114 ms, Maksimum = 119 ms, Czas średni = 115 ms
` `
func mockLossyHostPinger(binary string, timeout float64, args ...string) (string, error) { func mockLossyHostPinger(_ string, _ float64, _ ...string) (string, error) {
return lossyPingOutput, nil return lossyPingOutput, nil
} }
@ -228,7 +228,7 @@ Options:
` `
func mockFatalHostPinger(binary string, timeout float64, args ...string) (string, error) { func mockFatalHostPinger(_ string, _ float64, _ ...string) (string, error) {
return fatalPingOutput, errors.New("So very bad") return fatalPingOutput, errors.New("So very bad")
} }
@ -273,7 +273,7 @@ Ping statistics for 8.8.8.8:
Packets: Sent = 4, Received = 1, Lost = 3 (75% loss), Packets: Sent = 4, Received = 1, Lost = 3 (75% loss),
` `
func mockUnreachableHostPinger(binary string, timeout float64, args ...string) (string, error) { func mockUnreachableHostPinger(_ string, _ float64, _ ...string) (string, error) {
return UnreachablePingOutput, errors.New("So very bad") return UnreachablePingOutput, errors.New("So very bad")
} }
@ -324,7 +324,7 @@ Ping statistics for 8.8.8.8:
Packets: Sent = 4, Received = 1, Lost = 3 (75% loss), Packets: Sent = 4, Received = 1, Lost = 3 (75% loss),
` `
func mockTTLExpiredPinger(binary string, timeout float64, args ...string) (string, error) { func mockTTLExpiredPinger(_ string, _ float64, _ ...string) (string, error) {
return TTLExpiredPingOutput, errors.New("So very bad") return TTLExpiredPingOutput, errors.New("So very bad")
} }

View File

@ -1,11 +0,0 @@
//go:build !dragonfly && !linux && !netbsd && !openbsd && !solaris && !darwin && !freebsd
package postfix
import (
"time"
)
func statCTime(_ interface{}) time.Time {
return time.Time{}
}

View File

@ -16,7 +16,7 @@ func (e *Processes) Init() error {
return nil return nil
} }
func (e *Processes) Gather(acc telegraf.Accumulator) error { func (e *Processes) Gather(_ telegraf.Accumulator) error {
return nil return nil
} }

View File

@ -36,11 +36,11 @@ func TestGather_RealUserIntegration(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("Skipping integration test in short mode") t.Skip("Skipping integration test in short mode")
} }
user, err := user.Current() currentUser, err := user.Current()
require.NoError(t, err) require.NoError(t, err)
pg, err := NewNativeFinder() pg, err := NewNativeFinder()
require.NoError(t, err) require.NoError(t, err)
pids, err := pg.UID(user.Username) pids, err := pg.UID(currentUser.Username)
require.NoError(t, err) require.NoError(t, err)
fmt.Println(pids) fmt.Println(pids)
require.Equal(t, len(pids) > 0, true) require.Equal(t, len(pids) > 0, true)

View File

@ -34,9 +34,8 @@ type EvtRenderFlag uint32
// EVT_RENDER_FLAGS enumeration // EVT_RENDER_FLAGS enumeration
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa385563(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/windows/desktop/aa385563(v=vs.85).aspx
const ( const (
// Render the event as an XML string. For details on the contents of the // Render the event as an XML string. For details on the contents of the XML string, see the Event schema.
// XML string, see the Event schema. EvtRenderEventXML EvtRenderFlag = 1
EvtRenderEventXml EvtRenderFlag = 1
// Render bookmark // Render bookmark
EvtRenderBookmark EvtRenderFlag = 2 EvtRenderBookmark EvtRenderFlag = 2
) )

View File

@ -19,7 +19,6 @@ import (
// DecodeUTF16 to UTF8 bytes // DecodeUTF16 to UTF8 bytes
func DecodeUTF16(b []byte) ([]byte, error) { func DecodeUTF16(b []byte) ([]byte, error) {
if len(b)%2 != 0 { if len(b)%2 != 0 {
return nil, fmt.Errorf("must have even length byte slice") return nil, fmt.Errorf("must have even length byte slice")
} }
@ -42,28 +41,28 @@ func DecodeUTF16(b []byte) ([]byte, error) {
} }
// GetFromSnapProcess finds information about process by the given pid // GetFromSnapProcess finds information about process by the given pid
// Returns process parent pid, threads info handle and process name // Returns process name
func GetFromSnapProcess(pid uint32) (uint32, uint32, string, error) { func GetFromSnapProcess(pid uint32) (string, error) {
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, pid) snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, pid)
if err != nil { if err != nil {
return 0, 0, "", err return "", err
} }
defer windows.CloseHandle(snap) defer windows.CloseHandle(snap)
var pe32 windows.ProcessEntry32 var pe32 windows.ProcessEntry32
pe32.Size = uint32(unsafe.Sizeof(pe32)) //nolint:gosec // G103: Valid use of unsafe call to determine the size of the struct pe32.Size = uint32(unsafe.Sizeof(pe32)) //nolint:gosec // G103: Valid use of unsafe call to determine the size of the struct
if err = windows.Process32First(snap, &pe32); err != nil { if err = windows.Process32First(snap, &pe32); err != nil {
return 0, 0, "", err return "", err
} }
for { for {
if pe32.ProcessID == pid { if pe32.ProcessID == pid {
szexe := windows.UTF16ToString(pe32.ExeFile[:]) szexe := windows.UTF16ToString(pe32.ExeFile[:])
return pe32.ParentProcessID, pe32.Threads, szexe, nil return szexe, nil
} }
if err = windows.Process32Next(snap, &pe32); err != nil { if err = windows.Process32Next(snap, &pe32); err != nil {
break break
} }
} }
return 0, 0, "", fmt.Errorf("couldn't find pid: %d", pid) return "", fmt.Errorf("couldn't find pid: %d", pid)
} }
type xmlnode struct { type xmlnode struct {

View File

@ -153,7 +153,7 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error {
fieldName = "ProcessID" fieldName = "ProcessID"
// Look up Process Name from pid // Look up Process Name from pid
if should, _ := w.shouldProcessField("ProcessName"); should { if should, _ := w.shouldProcessField("ProcessName"); should {
_, _, processName, err := GetFromSnapProcess(fieldValue) processName, err := GetFromSnapProcess(fieldValue)
if err == nil { if err == nil {
computedValues["ProcessName"] = processName computedValues["ProcessName"] = processName
} }
@ -395,7 +395,7 @@ func (w *WinEventLog) renderEvent(eventHandle EvtHandle) (Event, error) {
buf := make([]byte, bufferSize) buf := make([]byte, bufferSize)
event := Event{} event := Event{}
err := _EvtRender(0, eventHandle, EvtRenderEventXml, uint32(len(buf)), &buf[0], &bufferUsed, &propertyCount) err := _EvtRender(0, eventHandle, EvtRenderEventXML, uint32(len(buf)), &buf[0], &bufferUsed, &propertyCount)
if err != nil { if err != nil {
return event, err return event, err
} }

View File

@ -76,6 +76,7 @@ var (
procEvtUpdateBookmark = modwevtapi.NewProc("EvtUpdateBookmark") procEvtUpdateBookmark = modwevtapi.NewProc("EvtUpdateBookmark")
) )
//nolint:revive //argument-limit conditionally more arguments allowed
func _EvtSubscribe( func _EvtSubscribe(
session EvtHandle, session EvtHandle,
signalEvent uintptr, signalEvent uintptr,
@ -110,6 +111,7 @@ func _EvtSubscribe(
return handle, err return handle, err
} }
//nolint:revive //argument-limit conditionally more arguments allowed
func _EvtRender( func _EvtRender(
context EvtHandle, context EvtHandle,
fragment EvtHandle, fragment EvtHandle,
@ -176,6 +178,7 @@ func _EvtNext(resultSet EvtHandle, eventArraySize uint32, eventArray *EvtHandle,
return err return err
} }
//nolint:revive //argument-limit conditionally more arguments allowed
func _EvtFormatMessage( func _EvtFormatMessage(
publisherMetadata EvtHandle, publisherMetadata EvtHandle,
event EvtHandle, event EvtHandle,

View File

@ -81,9 +81,8 @@ func (rmr *MgProvider) Connect() (WinServiceManager, error) {
scmgr, err := mgr.Connect() scmgr, err := mgr.Connect()
if err != nil { if err != nil {
return nil, err return nil, err
} else {
return &WinSvcMgr{scmgr}, nil
} }
return &WinSvcMgr{scmgr}, nil
} }
// WinServices is an implementation if telegraf.Input interface, providing info about Windows Services // WinServices is an implementation if telegraf.Input interface, providing info about Windows Services

View File

@ -48,9 +48,8 @@ func (m *FakeSvcMgr) OpenService(name string) (WinService, error) {
if s.serviceName == name { if s.serviceName == name {
if s.serviceOpenError != nil { if s.serviceOpenError != nil {
return nil, s.serviceOpenError return nil, s.serviceOpenError
} else {
return &FakeWinSvc{s}, nil
} }
return &FakeWinSvc{s}, nil
} }
} }
return nil, fmt.Errorf("cannot find service %q", name) return nil, fmt.Errorf("cannot find service %q", name)
@ -59,9 +58,8 @@ func (m *FakeSvcMgr) OpenService(name string) (WinService, error) {
func (m *FakeSvcMgr) ListServices() ([]string, error) { func (m *FakeSvcMgr) ListServices() ([]string, error) {
if m.testData.mgrListServicesError != nil { if m.testData.mgrListServicesError != nil {
return nil, m.testData.mgrListServicesError return nil, m.testData.mgrListServicesError
} else {
return m.testData.queryServiceList, nil
} }
return m.testData.queryServiceList, nil
} }
type FakeMgProvider struct { type FakeMgProvider struct {
@ -71,9 +69,8 @@ type FakeMgProvider struct {
func (m *FakeMgProvider) Connect() (WinServiceManager, error) { func (m *FakeMgProvider) Connect() (WinServiceManager, error) {
if m.testData.mgrConnectError != nil { if m.testData.mgrConnectError != nil {
return nil, m.testData.mgrConnectError return nil, m.testData.mgrConnectError
} else {
return &FakeSvcMgr{m.testData}, nil
} }
return &FakeSvcMgr{m.testData}, nil
} }
type FakeWinSvc struct { type FakeWinSvc struct {
@ -86,7 +83,7 @@ func (m *FakeWinSvc) Close() error {
func (m *FakeWinSvc) Config() (mgr.Config, error) { func (m *FakeWinSvc) Config() (mgr.Config, error) {
if m.testData.serviceConfigError != nil { if m.testData.serviceConfigError != nil {
return mgr.Config{}, m.testData.serviceConfigError return mgr.Config{}, m.testData.serviceConfigError
} else { }
return mgr.Config{ return mgr.Config{
ServiceType: 0, ServiceType: 0,
StartType: uint32(m.testData.startUpMode), StartType: uint32(m.testData.startUpMode),
@ -101,11 +98,10 @@ func (m *FakeWinSvc) Config() (mgr.Config, error) {
Description: "", Description: "",
}, nil }, nil
} }
}
func (m *FakeWinSvc) Query() (svc.Status, error) { func (m *FakeWinSvc) Query() (svc.Status, error) {
if m.testData.serviceQueryError != nil { if m.testData.serviceQueryError != nil {
return svc.Status{}, m.testData.serviceQueryError return svc.Status{}, m.testData.serviceQueryError
} else { }
return svc.Status{ return svc.Status{
State: svc.State(m.testData.state), State: svc.State(m.testData.state),
Accepts: 0, Accepts: 0,
@ -113,7 +109,6 @@ func (m *FakeWinSvc) Query() (svc.Status, error) {
WaitHint: 0, WaitHint: 0,
}, nil }, nil
} }
}
var testErrors = []testData{ var testErrors = []testData{
{nil, errors.New("fake mgr connect error"), nil, nil}, {nil, errors.New("fake mgr connect error"), nil, nil},

View File

@ -106,9 +106,6 @@ func (q *Query) doQuery(acc telegraf.Accumulator) error {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
tags := map[string]string{}
fields := map[string]interface{}{}
// init COM // init COM
if err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil { if err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil {
var oleCode *ole.OleError var oleCode *ole.OleError
@ -161,25 +158,35 @@ func (q *Query) doQuery(acc telegraf.Accumulator) error {
return fmt.Errorf("failed calling method ItemIndex: %w", err) return fmt.Errorf("failed calling method ItemIndex: %w", err)
} }
err = q.extractProperties(itemRaw, acc)
if err != nil {
return err
}
}
return nil
}
func (q *Query) extractProperties(itemRaw *ole.VARIANT, acc telegraf.Accumulator) error {
tags, fields := map[string]string{}, map[string]interface{}{}
item := itemRaw.ToIDispatch() item := itemRaw.ToIDispatch()
defer item.Release() defer item.Release()
for _, wmiProperty := range q.Properties { for _, wmiProperty := range q.Properties {
prop, err := oleutil.GetProperty(item, wmiProperty) propertyValue, err := getPropertyValue(item, wmiProperty)
if err != nil { if err != nil {
return fmt.Errorf("failed GetProperty: %w", err) return err
} }
defer prop.Clear()
if q.tagFilter.Match(wmiProperty) { if q.tagFilter.Match(wmiProperty) {
valStr, err := internal.ToString(prop.Value()) valStr, err := internal.ToString(propertyValue)
if err != nil { if err != nil {
return fmt.Errorf("converting property %q failed: %w", wmiProperty, err) return fmt.Errorf("converting property %q failed: %w", wmiProperty, err)
} }
tags[wmiProperty] = valStr tags[wmiProperty] = valStr
} else { } else {
var fieldValue interface{} var fieldValue interface{}
switch v := prop.Value().(type) { switch v := propertyValue.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64: case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64:
fieldValue = v fieldValue = v
case string: case string:
@ -199,10 +206,19 @@ func (q *Query) doQuery(acc telegraf.Accumulator) error {
} }
} }
acc.AddFields(q.ClassName, fields, tags) acc.AddFields(q.ClassName, fields, tags)
}
return nil return nil
} }
func getPropertyValue(item *ole.IDispatch, wmiProperty string) (interface{}, error) {
prop, err := oleutil.GetProperty(item, wmiProperty)
if err != nil {
return nil, fmt.Errorf("failed GetProperty: %w", err)
}
defer prop.Clear()
return prop.Value(), nil
}
// Gather function // Gather function
func (s *Wmi) Gather(acc telegraf.Accumulator) error { func (s *Wmi) Gather(acc telegraf.Accumulator) error {
var wg sync.WaitGroup var wg sync.WaitGroup

View File

@ -17,7 +17,7 @@ import (
var sysDrive = fmt.Sprintf(`%s\`, os.Getenv("SystemDrive")) // C:\ var sysDrive = fmt.Sprintf(`%s\`, os.Getenv("SystemDrive")) // C:\
// include Name as a tag, FreeSpace as a field, and Purpose as a known-null class property // include Name as a tag, FreeSpace as a field, and Purpose as a known-null class property
var testQuery Query = Query{ var testQuery = Query{
Namespace: "ROOT\\cimv2", Namespace: "ROOT\\cimv2",
ClassName: "Win32_Volume", ClassName: "Win32_Volume",
Properties: []string{"Name", "FreeSpace", "Purpose"}, Properties: []string{"Name", "FreeSpace", "Purpose"},