chore: Fix linter findings for Windows (part2) (#13096)

Co-authored-by: pzak <pzak>
This commit is contained in:
Paweł Żak 2023-04-25 11:29:23 +02:00 committed by GitHub
parent 1d3afd469f
commit 4d4bed4ec4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 158 additions and 121 deletions

View File

@ -22,9 +22,11 @@ type eventLogger struct {
logger *eventlog.Log
}
func (t *eventLogger) Write(b []byte) (n int, err error) {
func (t *eventLogger) Write(b []byte) (int, error) {
var err error
loc := prefixRegex.FindIndex(b)
n = len(b)
n := len(b)
if loc == nil {
err = t.logger.Info(1, string(b))
} else if n > 2 { //skip empty log messages
@ -39,7 +41,7 @@ func (t *eventLogger) Write(b []byte) (n int, err error) {
}
}
return
return n, err
}
type eventLoggerCreator struct {

View File

@ -5,6 +5,7 @@ package logger
import (
"bytes"
"encoding/xml"
"fmt"
"log"
"os/exec"
"testing"
@ -30,7 +31,12 @@ type Event struct {
func getEventLog(t *testing.T, since time.Time) []Event {
timeStr := since.UTC().Format(time.RFC3339)
timeStr = timeStr[:19]
cmd := exec.Command("wevtutil", "qe", "Application", "/rd:true", "/q:Event[System[TimeCreated[@SystemTime >= '"+timeStr+"'] and Provider[@Name='telegraf']]]")
args := []string{
"qe",
"Application",
"/rd:true",
fmt.Sprintf("/q:Event[System[TimeCreated[@SystemTime >= %q] and Provider[@Name='telegraf']]]", timeStr)}
cmd := exec.Command("wevtutil", args...)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()

View File

@ -45,7 +45,7 @@ func DecodeUTF16(b []byte) ([]byte, error) {
// GetFromSnapProcess finds information about process by the given pid
// Returns process parent pid, threads info handle and process name
func GetFromSnapProcess(pid uint32) (uint32, uint32, string, error) {
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, uint32(pid))
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, pid)
if err != nil {
return 0, 0, "", err
}
@ -56,9 +56,9 @@ func GetFromSnapProcess(pid uint32) (uint32, uint32, string, error) {
return 0, 0, "", err
}
for {
if pe32.ProcessID == uint32(pid) {
if pe32.ProcessID == pid {
szexe := windows.UTF16ToString(pe32.ExeFile[:])
return uint32(pe32.ParentProcessID), uint32(pe32.Threads), szexe, nil
return pe32.ParentProcessID, pe32.Threads, szexe, nil
}
if err = windows.Process32Next(snap, &pe32); err != nil {
break
@ -139,7 +139,7 @@ func walkXML(nodes []xmlnode, parents []string, separator string, f func(xmlnode
// by adding _<num> if there are several of them
func UniqueFieldNames(fields []EventField, fieldsUsage map[string]int, separator string) []EventField {
var fieldsCounter = map[string]int{}
var fieldsUnique []EventField
fieldsUnique := make([]EventField, 0, len(fields))
for _, field := range fields {
fieldName := field.Name
if fieldsUsage[field.Name] > 1 {

View File

@ -127,12 +127,13 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error {
return err
}
for _, event := range events {
for i := range events {
// Prepare fields names usage counter
var fieldsUsage = map[string]int{}
tags := map[string]string{}
fields := map[string]interface{}{}
event := events[i]
evt := reflect.ValueOf(&event).Elem()
timeStamp := time.Now()
// Walk through all fields of Event struct to process System tags or fields
@ -403,17 +404,16 @@ func (w *WinEventLog) renderEvent(eventHandle EvtHandle) (Event, error) {
return event, err
}
err = xml.Unmarshal([]byte(eventXML), &event)
err = xml.Unmarshal(eventXML, &event)
if err != nil {
// We can return event without most text values,
// that way we will not loose information
//nolint:nilerr // We can return event without most text values, that way we will not lose information
// This can happen when processing Forwarded Events
return event, nil
}
// Do resolve local messages the usual way, while using built-in information for events forwarded by WEC.
// This is a safety measure as the underlying Windows-internal EvtFormatMessage might segfault in cases
// where the publisher (i.e. the remote machine which forwared the event) is unavailable e.g. due to
// where the publisher (i.e. the remote machine which forwarded the event) is unavailable e.g. due to
// a reboot. See https://github.com/influxdata/telegraf/issues/12328 for the full story.
if event.RenderingInfo == nil {
return w.renderLocalMessage(event, eventHandle)
@ -426,7 +426,7 @@ func (w *WinEventLog) renderEvent(eventHandle EvtHandle) (Event, error) {
func (w *WinEventLog) renderLocalMessage(event Event, eventHandle EvtHandle) (Event, error) {
publisherHandle, err := openPublisherMetadata(0, event.Source.Name, w.Locale)
if err != nil {
return event, nil
return event, nil //nolint:nilerr // We can return event without most values
}
defer _EvtClose(publisherHandle)

View File

@ -36,21 +36,18 @@ type EvtFormatMessageFlag uint32
// EVT_FORMAT_MESSAGE_FLAGS enumeration
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa385525(v=vs.85).aspx
const (
//revive:disable:var-naming
// Format the event's message string.
// EvtFormatMessageEvent - Format the event's message string.
EvtFormatMessageEvent EvtFormatMessageFlag = iota + 1
// Format the message string of the level specified in the event.
// EvtFormatMessageLevel - Format the message string of the level specified in the event.
EvtFormatMessageLevel
// Format the message string of the task specified in the event.
// EvtFormatMessageTask - Format the message string of the task specified in the event.
EvtFormatMessageTask
// Format the message string of the task specified in the event.
// EvtFormatMessageOpcode - Format the message string of the task specified in the event.
EvtFormatMessageOpcode
// Format the message string of the keywords specified in the event. If the
// event specifies multiple keywords, the formatted string is a list of
// null-terminated strings. Increment through the strings until your pointer
// points past the end of the used buffer.
// EvtFormatMessageKeyword - Format the message string of the keywords specified in the event. If the
// event specifies multiple keywords, the formatted string is a list of null-terminated strings.
// Increment through the strings until your pointer points past the end of the used buffer.
EvtFormatMessageKeyword
//revive:enable:var-naming
)
// errnoErr returns common boxed Errno values, to prevent
@ -88,21 +85,21 @@ func _EvtSubscribe(
context uintptr,
callback syscall.Handle,
flags EvtSubscribeFlag,
) (handle EvtHandle, err error) {
r0, _, e1 := syscall.Syscall9(
) (EvtHandle, error) {
r0, _, e1 := syscall.SyscallN(
procEvtSubscribe.Addr(),
8,
uintptr(session),
uintptr(signalEvent),
signalEvent,
uintptr(unsafe.Pointer(channelPath)), //nolint:gosec // G103: Valid use of unsafe call to pass channelPath
uintptr(unsafe.Pointer(query)), //nolint:gosec // G103: Valid use of unsafe call to pass query
uintptr(bookmark),
uintptr(context),
context,
uintptr(callback),
uintptr(flags),
0,
)
handle = EvtHandle(r0)
var err error
handle := EvtHandle(r0)
if handle == 0 {
if e1 != 0 {
err = errnoErr(e1)
@ -110,7 +107,7 @@ func _EvtSubscribe(
err = syscall.EINVAL
}
}
return
return handle, err
}
func _EvtRender(
@ -121,10 +118,9 @@ func _EvtRender(
buffer *byte,
bufferUsed *uint32,
propertyCount *uint32,
) (err error) {
r1, _, e1 := syscall.Syscall9(
) error {
r1, _, e1 := syscall.SyscallN(
procEvtRender.Addr(),
7,
uintptr(context),
uintptr(fragment),
uintptr(flags),
@ -132,9 +128,9 @@ func _EvtRender(
uintptr(unsafe.Pointer(buffer)), //nolint:gosec // G103: Valid use of unsafe call to pass buffer
uintptr(unsafe.Pointer(bufferUsed)), //nolint:gosec // G103: Valid use of unsafe call to pass bufferUsed
uintptr(unsafe.Pointer(propertyCount)), //nolint:gosec // G103: Valid use of unsafe call to pass propertyCount
0,
0,
)
var err error
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
@ -142,11 +138,12 @@ func _EvtRender(
err = syscall.EINVAL
}
}
return
return err
}
func _EvtClose(object EvtHandle) (err error) {
r1, _, e1 := syscall.Syscall(procEvtClose.Addr(), 1, uintptr(object), 0, 0)
func _EvtClose(object EvtHandle) error {
r1, _, e1 := syscall.SyscallN(procEvtClose.Addr(), uintptr(object))
var err error
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
@ -154,13 +151,12 @@ func _EvtClose(object EvtHandle) (err error) {
err = syscall.EINVAL
}
}
return
return err
}
func _EvtNext(resultSet EvtHandle, eventArraySize uint32, eventArray *EvtHandle, timeout uint32, flags uint32, numReturned *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(
func _EvtNext(resultSet EvtHandle, eventArraySize uint32, eventArray *EvtHandle, timeout uint32, flags uint32, numReturned *uint32) error {
r1, _, e1 := syscall.SyscallN(
procEvtNext.Addr(),
6,
uintptr(resultSet),
uintptr(eventArraySize),
uintptr(unsafe.Pointer(eventArray)), //nolint:gosec // G103: Valid use of unsafe call to pass eventArray
@ -168,6 +164,8 @@ func _EvtNext(resultSet EvtHandle, eventArraySize uint32, eventArray *EvtHandle,
uintptr(flags),
uintptr(unsafe.Pointer(numReturned)), //nolint:gosec // G103: Valid use of unsafe call to pass numReturned
)
var err error
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
@ -175,7 +173,7 @@ func _EvtNext(resultSet EvtHandle, eventArraySize uint32, eventArray *EvtHandle,
err = syscall.EINVAL
}
}
return
return err
}
func _EvtFormatMessage(
@ -188,20 +186,21 @@ func _EvtFormatMessage(
bufferSize uint32,
buffer *byte,
bufferUsed *uint32,
) (err error) {
r1, _, e1 := syscall.Syscall9(
) error {
r1, _, e1 := syscall.SyscallN(
procEvtFormatMessage.Addr(),
9,
uintptr(publisherMetadata),
uintptr(event),
uintptr(messageID),
uintptr(valueCount),
uintptr(values),
values,
uintptr(flags),
uintptr(bufferSize),
uintptr(unsafe.Pointer(buffer)), //nolint:gosec // G103: Valid use of unsafe call to pass buffer
uintptr(unsafe.Pointer(bufferUsed)), //nolint:gosec // G103: Valid use of unsafe call to pass bufferUsed
)
var err error
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
@ -209,21 +208,21 @@ func _EvtFormatMessage(
err = syscall.EINVAL
}
}
return
return err
}
func _EvtOpenPublisherMetadata(session EvtHandle, publisherIdentity *uint16, logFilePath *uint16, locale uint32, flags uint32) (handle EvtHandle, err error) {
r0, _, e1 := syscall.Syscall6(
func _EvtOpenPublisherMetadata(session EvtHandle, publisherIdentity *uint16, logFilePath *uint16, locale uint32, flags uint32) (EvtHandle, error) {
r0, _, e1 := syscall.SyscallN(
procEvtOpenPublisherMetadata.Addr(),
5,
uintptr(session),
uintptr(unsafe.Pointer(publisherIdentity)), //nolint:gosec // G103: Valid use of unsafe call to pass publisherIdentity
uintptr(unsafe.Pointer(logFilePath)), //nolint:gosec // G103: Valid use of unsafe call to pass logFilePath
uintptr(locale),
uintptr(flags),
0,
)
handle = EvtHandle(r0)
var err error
handle := EvtHandle(r0)
if handle == 0 {
if e1 != 0 {
err = errnoErr(e1)
@ -231,12 +230,12 @@ func _EvtOpenPublisherMetadata(session EvtHandle, publisherIdentity *uint16, log
err = syscall.EINVAL
}
}
return
return handle, err
}
func _EvtCreateBookmark(bookmarkXML *uint16) (EvtHandle, error) {
//nolint:gosec // G103: Valid use of unsafe call to pass bookmarkXML
r0, _, e1 := syscall.Syscall(procEvtCreateBookmark.Addr(), 1, uintptr(unsafe.Pointer(bookmarkXML)), 0, 0)
r0, _, e1 := syscall.SyscallN(procEvtCreateBookmark.Addr(), uintptr(unsafe.Pointer(bookmarkXML)))
handle := EvtHandle(r0)
if handle != 0 {
return handle, nil
@ -248,7 +247,7 @@ func _EvtCreateBookmark(bookmarkXML *uint16) (EvtHandle, error) {
}
func _EvtUpdateBookmark(bookmark, event EvtHandle) error {
r0, _, e1 := syscall.Syscall(procEvtUpdateBookmark.Addr(), 2, uintptr(bookmark), uintptr(event), 0)
r0, _, e1 := syscall.SyscallN(procEvtUpdateBookmark.Addr(), uintptr(bookmark), uintptr(event))
if r0 != 0 {
return nil
}

View File

@ -308,7 +308,7 @@ func init() {
// \\LogicalDisk(C:)\% Free Space
//
// To view all (internationalized...) counters on a system, there are three non-programmatic ways: perfmon utility,
// the typeperf command, and the the registry editor. perfmon.exe is perhaps the easiest way, because it's basically a
// the typeperf command, and the registry editor. perfmon.exe is perhaps the easiest way, because it's basically a
// full implementation of the pdh.dll API, except with a GUI and all that. The registry setting also provides an
// interface to the available counters, and can be found at the following key:
//
@ -376,7 +376,7 @@ func PdhCloseQuery(hQuery PDH_HQUERY) uint32 {
return uint32(ret)
}
// Collects the current raw data value for all counters in the specified query and updates the status
// PdhCollectQueryData collects the current raw data value for all counters in the specified query and updates the status
// code of each counter. With some counters, this function needs to be repeatedly called before the value
// of the counter can be extracted with PdhGetFormattedCounterValue(). For example, the following code
// requires at least two calls:
@ -510,13 +510,13 @@ func PdhOpenQuery(szDataSource uintptr, dwUserData uintptr, phQuery *PDH_HQUERY)
return uint32(ret)
}
// PdhExpandWildCardPath examines the specified computer or log file and returns those counter paths that match the given counter path which contains wildcard characters.
// The general counter path format is as follows:
// PdhExpandWildCardPath examines the specified computer or log file and returns those counter paths that match the given counter path
// which contains wildcard characters. The general counter path format is as follows:
//
// \\computer\object(parent/instance#index)\counter
//
// The parent, instance, index, and counter components of the counter path may contain either a valid name or a wildcard character. The computer, parent, instance,
// and index components are not necessary for all counters.
// The parent, instance, index, and counter components of the counter path may contain either a valid name or a wildcard character.
// The computer, parent, instance, and index components are not necessary for all counters.
//
// The following is a list of the possible formats:
//
@ -532,11 +532,13 @@ func PdhOpenQuery(szDataSource uintptr, dwUserData uintptr, phQuery *PDH_HQUERY)
// \object\counter
// Use an asterisk (*) as the wildcard character, for example, \object(*)\counter.
//
// If a wildcard character is specified in the parent name, all instances of the specified object that match the specified instance and counter fields will be returned.
// If a wildcard character is specified in the parent name, all instances of the specified object
// that match the specified instance and counter fields will be returned.
// For example, \object(*/instance)\counter.
//
// If a wildcard character is specified in the instance name, all instances of the specified object and parent object will be returned if all instance names
// corresponding to the specified index match the wildcard character. For example, \object(parent/*)\counter. If the object does not contain an instance, an error occurs.
// corresponding to the specified index match the wildcard character. For example, \object(parent/*)\counter.
// If the object does not contain an instance, an error occurs.
//
// If a wildcard character is specified in the counter name, all counters of the specified object are returned.
//
@ -572,18 +574,23 @@ func PdhFormatError(msgId uint32) string {
return fmt.Sprintf("(pdhErr=%d) %s", msgId, err.Error())
}
// Retrieves information about a counter, such as data size, counter type, path, and user-supplied data values
// PdhGetCounterInfo retrieves information about a counter, such as data size, counter type, path, and user-supplied data values
// hCounter [in]
// Handle of the counter from which you want to retrieve information. The PdhAddCounter function returns this handle.
//
// bRetrieveExplainText [in]
// Determines whether explain text is retrieved. If you set this parameter to TRUE, the explain text for the counter is retrieved. If you set this parameter to FALSE, the field in the returned buffer is NULL.
// Determines whether explain text is retrieved. If you set this parameter to TRUE, the explain text for the counter is retrieved.
// If you set this parameter to FALSE, the field in the returned buffer is NULL.
//
// pdwBufferSize [in, out]
// Size of the lpBuffer buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned size to reallocate the buffer.
// Size of the lpBuffer buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter to the required buffer size.
// If the buffer is larger than the required size, the function sets this parameter to the actual size of the buffer that was used.
// If the specified size on input is greater than zero but less than the required size, you should not rely on the returned size to reallocate the buffer.
//
// lpBuffer [out]
// Caller-allocated buffer that receives a PDH_COUNTER_INFO structure. The structure is variable-length, because the string data is appended to the end of the fixed-format portion of the structure. This is done so that all data is returned in a single buffer allocated by the caller. Set to NULL if pdwBufferSize is zero.
// Caller-allocated buffer that receives a PDH_COUNTER_INFO structure.
// The structure is variable-length, because the string data is appended to the end of the fixed-format portion of the structure.
// This is done so that all data is returned in a single buffer allocated by the caller. Set to NULL if pdwBufferSize is zero.
func PdhGetCounterInfo(hCounter PDH_HCOUNTER, bRetrieveExplainText int, pdwBufferSize *uint32, lpBuffer *byte) uint32 {
ret, _, _ := pdh_GetCounterInfoW.Call(
uintptr(hCounter),
@ -594,7 +601,7 @@ func PdhGetCounterInfo(hCounter PDH_HCOUNTER, bRetrieveExplainText int, pdwBuffe
return uint32(ret)
}
// Returns the current raw value of the counter.
// PdhGetRawCounterValue returns the current raw value of the counter.
// If the specified counter instance does not exist, this function will return ERROR_SUCCESS
// and the CStatus member of the PDH_RAW_COUNTER structure will contain PDH_CSTATUS_NO_INSTANCE.
//
@ -616,7 +623,7 @@ func PdhGetRawCounterValue(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_
return uint32(ret)
}
// Returns an array of raw values from the specified counter. Use this function when you want to retrieve the raw counter values
// PdhGetRawCounterArray returns an array of raw values from the specified counter. Use this function when you want to retrieve the raw counter values
// of a counter that contains a wildcard character for the instance name.
// hCounter
// Handle of the counter for whose current raw instance values you want to retrieve. The PdhAddCounter function returns this handle.

View File

@ -32,37 +32,38 @@
package win_perf_counters
// Union specialization for double values
// PDH_FMT_COUNTERVALUE_DOUBLE is an union specialization for double values
type PDH_FMT_COUNTERVALUE_DOUBLE struct {
CStatus uint32
DoubleValue float64
}
// Union specialization for 64 bit integer values
// PDH_FMT_COUNTERVALUE_LARGE is a union specialization for 64-bit integer values
type PDH_FMT_COUNTERVALUE_LARGE struct {
CStatus uint32
LargeValue int64
}
// Union specialization for long values
// PDH_FMT_COUNTERVALUE_LONG is a union specialization for long values
type PDH_FMT_COUNTERVALUE_LONG struct {
CStatus uint32
LongValue int32
padding [4]byte
}
// PDH_FMT_COUNTERVALUE_ITEM_DOUBLE is a union specialization for double values, used by PdhGetFormattedCounterArrayDouble
type PDH_FMT_COUNTERVALUE_ITEM_DOUBLE struct {
SzName *uint16
FmtValue PDH_FMT_COUNTERVALUE_DOUBLE
}
// Union specialization for 'large' values, used by PdhGetFormattedCounterArrayLarge()
// PDH_FMT_COUNTERVALUE_ITEM_LARGE is n union specialization for 'large' values, used by PdhGetFormattedCounterArrayLarge()
type PDH_FMT_COUNTERVALUE_ITEM_LARGE struct {
SzName *uint16 // pointer to a string
FmtValue PDH_FMT_COUNTERVALUE_LARGE
}
// Union specialization for long values, used by PdhGetFormattedCounterArrayLong()
// PDH_FMT_COUNTERVALUE_ITEM_LONG is n union specialization for long values, used by PdhGetFormattedCounterArrayLong()
type PDH_FMT_COUNTERVALUE_ITEM_LONG struct {
SzName *uint16 // pointer to a string
FmtValue PDH_FMT_COUNTERVALUE_LONG
@ -72,7 +73,8 @@ type PDH_FMT_COUNTERVALUE_ITEM_LONG struct {
type PDH_COUNTER_INFO struct {
//Size of the structure, including the appended strings, in bytes.
DwLength uint32
//Counter type. For a list of counter types, see the Counter Types section of the <a "href=http://go.microsoft.com/fwlink/p/?linkid=84422">Windows Server 2003 Deployment Kit</a>.
//Counter type. For a list of counter types,
//see the Counter Types section of the <a "href=http://go.microsoft.com/fwlink/p/?linkid=84422">Windows Server 2003 Deployment Kit</a>.
//The counter type constants are defined in Winperf.h.
DwType uint32
//Counter version information. Not used.
@ -100,8 +102,8 @@ type PDH_COUNTER_INFO struct {
//Null-terminated string that contains the name of the object instance specified in the counter path. Is NULL, if the path does not specify an instance.
//The string follows this structure in memory.
SzInstanceName *uint16 // pointer to a string
//Null-terminated string that contains the name of the parent instance specified in the counter path. Is NULL, if the path does not specify a parent instance.
//The string follows this structure in memory.
//Null-terminated string that contains the name of the parent instance specified in the counter path.
//Is NULL, if the path does not specify a parent instance. The string follows this structure in memory.
SzParentInstance *uint16 // pointer to a string
//Instance index specified in the counter path. Is 0, if the path does not specify an instance index.
DwInstanceIndex uint32 // pointer to a string
@ -113,10 +115,11 @@ type PDH_COUNTER_INFO struct {
DataBuffer [1]uint32 // pointer to an extra space
}
// The PDH_RAW_COUNTER structure returns the data as it was collected from the counter provider. No translation, formatting, or other interpretation is performed on the data
// The PDH_RAW_COUNTER structure returns the data as it was collected from the counter provider.
// No translation, formatting, or other interpretation is performed on the data
type PDH_RAW_COUNTER struct {
// Counter status that indicates if the counter value is valid. Check this member before using the data in a calculation or displaying its value. For a list of possible values,
// see https://docs.microsoft.com/windows/desktop/PerfCtrs/checking-pdh-interface-return-values
// Counter status that indicates if the counter value is valid. Check this member before using the data in a calculation or displaying its value.
// For a list of possible values, see https://docs.microsoft.com/windows/desktop/PerfCtrs/checking-pdh-interface-return-values
CStatus uint32
// Local time for when the data was collected
TimeStamp FILETIME

View File

@ -10,13 +10,15 @@ import (
"unsafe"
)
// PerformanceQuery is abstraction for PDH_FMT_COUNTERVALUE_ITEM_DOUBLE
// CounterValue is abstraction for PDH_FMT_COUNTERVALUE_ITEM_DOUBLE
type CounterValue struct {
InstanceName string
Value interface{}
}
// PerformanceQuery provides wrappers around Windows performance counters API for easy usage in GO
//
//nolint:interfacebloat // conditionally allow to contain more methods
type PerformanceQuery interface {
Open() error
Close() error

View File

@ -165,7 +165,17 @@ func (m *WinPerfCounters) hostname() string {
return m.cachedHostname
}
func newCounter(counterHandle PDH_HCOUNTER, counterPath string, computer string, objectName string, instance string, counterName string, measurement string, includeTotal bool, useRawValue bool) *counter {
func newCounter(
counterHandle PDH_HCOUNTER,
counterPath string,
computer string,
objectName string,
instance string,
counterName string,
measurement string,
includeTotal bool,
useRawValue bool,
) *counter {
measurementName := sanitizedChars.Replace(measurement)
if measurementName == "" {
measurementName = "win_perf_counters"
@ -364,7 +374,8 @@ func (m *WinPerfCounters) ParseConfig() error {
counterPath = formatPath(computer, objectname, instance, counter)
err := m.AddItem(counterPath, computer, objectname, instance, counter, PerfObject.Measurement, PerfObject.IncludeTotal, PerfObject.UseRawValues)
err := m.AddItem(counterPath, computer, objectname, instance, counter,
PerfObject.Measurement, PerfObject.IncludeTotal, PerfObject.UseRawValues)
if err != nil {
if PerfObject.FailOnMissing || PerfObject.WarnOnMissing {
m.Log.Errorf("invalid counterPath %q: %s", counterPath, err.Error())

View File

@ -535,10 +535,9 @@ func TestWinPerfcountersConfigError2Integration(t *testing.T) {
Log: testutil.Logger{},
}
err := m.ParseConfig()
require.Error(t, m.ParseConfig())
var acc testutil.Accumulator
err = m.Gather(&acc)
require.Error(t, err)
require.Error(t, m.Gather(&acc))
}
func TestWinPerfcountersConfigError3Integration(t *testing.T) {

View File

@ -232,14 +232,22 @@ type FakePerformanceQueryCreator struct {
func (m FakePerformanceQueryCreator) NewPerformanceQuery(computer string) PerformanceQuery {
var ret PerformanceQuery
var ok bool
ret = nil
if ret, ok = m.fakeQueries[computer]; !ok {
panic(fmt.Errorf("query for %s not found", computer))
}
return ret
}
func createPerfObject(computer string, measurement string, object string, instances []string, counters []string, failOnMissing bool, includeTotal bool, useRawValues bool) []perfobject {
func createPerfObject(
computer string,
measurement string,
object string,
instances []string,
counters []string,
failOnMissing bool,
includeTotal bool,
useRawValues bool,
) []perfobject {
PerfObject := perfobject{
ObjectName: object,
Instances: instances,
@ -250,11 +258,11 @@ func createPerfObject(computer string, measurement string, object string, instan
IncludeTotal: includeTotal,
UseRawValues: useRawValues,
}
if computer != "" {
PerfObject.Sources = []string{computer}
}
perfObjects := []perfobject{PerfObject}
return perfObjects
return []perfobject{PerfObject}
}
func createCounterMap(counterPaths []string, values []float64, status []uint32) map[string]testCounter {
@ -1348,11 +1356,7 @@ func TestGatherError(t *testing.T) {
if testing.Short() {
t.Skip("Skipping long taking test in short mode")
}
var err error
expectedError := "error during collecting data on host 'localhost': error while getting value for counter \\O(I)\\C: The information passed is not valid.\r\n"
if testing.Short() {
t.Skip("Skipping long taking test in short mode")
}
measurement := "test"
perfObjects := createPerfObject("", measurement, "O", []string{"I"}, []string{"C"}, false, false, false)
cp1 := "\\O(I)\\C"
@ -1371,26 +1375,24 @@ func TestGatherError(t *testing.T) {
},
},
}
expectedError := "error during collecting data on host 'localhost': error while getting value for counter \\O(I)\\C: " +
"The information passed is not valid.\r\n"
var acc1 testutil.Accumulator
err = m.Gather(&acc1)
require.NoError(t, err)
require.NoError(t, m.Gather(&acc1))
require.Len(t, acc1.Errors, 1)
require.Equal(t, expectedError, acc1.Errors[0].Error())
m.UseWildcardsExpansion = true
err = m.cleanQueries()
require.NoError(t, err)
require.NoError(t, m.cleanQueries())
m.lastRefreshed = time.Time{}
var acc2 testutil.Accumulator
err = m.Gather(&acc2)
require.NoError(t, err)
require.NoError(t, m.Gather(&acc2))
require.Len(t, acc2.Errors, 1)
require.Equal(t, expectedError, acc2.Errors[0].Error())
err = m.cleanQueries()
require.NoError(t, err)
require.NoError(t, m.cleanQueries())
}
func TestGatherInvalidDataIgnore(t *testing.T) {
@ -1728,7 +1730,10 @@ func TestGatherTotalNoExpansion(t *testing.T) {
Object: perfObjects,
queryCreator: &FakePerformanceQueryCreator{
fakeQueries: map[string]*FakePerformanceQuery{"localhost": {
counters: createCounterMap(append([]string{"\\O(*)\\C1", "\\O(*)\\C2"}, cps1...), []float64{0, 0, 1.1, 1.2, 1.3, 1.4}, []uint32{0, 0, 0, 0, 0, 0}),
counters: createCounterMap(
append([]string{"\\O(*)\\C1", "\\O(*)\\C2"}, cps1...),
[]float64{0, 0, 1.1, 1.2, 1.3, 1.4},
[]uint32{0, 0, 0, 0, 0, 0}),
expandPaths: map[string][]string{
"\\O(*)\\C1": {cps1[0], cps1[2]},
"\\O(*)\\C2": {cps1[1], cps1[3]},
@ -1923,7 +1928,10 @@ func TestGatherRaw(t *testing.T) {
Object: perfObjects,
queryCreator: &FakePerformanceQueryCreator{
fakeQueries: map[string]*FakePerformanceQuery{"localhost": {
counters: createCounterMap(append([]string{"\\O(*)\\C1", "\\O(*)\\C2"}, cps1...), []float64{0, 0, 1.1, 2.2, 3.3, 4.4}, []uint32{0, 0, 0, 0, 0, 0}),
counters: createCounterMap(
append([]string{"\\O(*)\\C1", "\\O(*)\\C2"}, cps1...),
[]float64{0, 0, 1.1, 2.2, 3.3, 4.4},
[]uint32{0, 0, 0, 0, 0, 0}),
expandPaths: map[string][]string{
"\\O(*)\\C1": {cps1[0], cps1[2]},
"\\O(*)\\C2": {cps1[1], cps1[3]},

View File

@ -53,7 +53,7 @@ func (m *FakeSvcMgr) OpenService(name string) (WinService, error) {
}
}
}
return nil, fmt.Errorf("Cannot find service %s", name)
return nil, fmt.Errorf("cannot find service %q", name)
}
func (m *FakeSvcMgr) ListServices() ([]string, error) {
@ -116,15 +116,15 @@ func (m *FakeWinSvc) Query() (svc.Status, error) {
}
var testErrors = []testData{
{nil, errors.New("Fake mgr connect error"), nil, nil},
{nil, nil, errors.New("Fake mgr list services error"), nil},
{nil, errors.New("fake mgr connect error"), nil, nil},
{nil, nil, errors.New("fake mgr list services error"), nil},
{[]string{"Fake service 1", "Fake service 2", "Fake service 3"}, nil, nil, []serviceTestInfo{
{errors.New("Fake srv open error"), nil, nil, "Fake service 1", "", 0, 0},
{nil, errors.New("Fake srv query error"), nil, "Fake service 2", "", 0, 0},
{nil, nil, errors.New("Fake srv config error"), "Fake service 3", "", 0, 0},
{errors.New("fake srv open error"), nil, nil, "Fake service 1", "", 0, 0},
{nil, errors.New("fake srv query error"), nil, "Fake service 2", "", 0, 0},
{nil, nil, errors.New("fake srv config error"), "Fake service 3", "", 0, 0},
}},
{[]string{"Fake service 1"}, nil, nil, []serviceTestInfo{
{errors.New("Fake srv open error"), nil, nil, "Fake service 1", "", 0, 0},
{errors.New("fake srv open error"), nil, nil, "Fake service 1", "", 0, 0},
}},
}
@ -206,8 +206,8 @@ func TestGatherContainsTag(t *testing.T) {
for _, s := range testSimpleData[0].services {
fields := make(map[string]interface{})
tags := make(map[string]string)
fields["state"] = int(s.state)
fields["startup_mode"] = int(s.startUpMode)
fields["state"] = s.state
fields["startup_mode"] = s.startUpMode
tags["service_name"] = s.serviceName
tags["display_name"] = s.displayName
acc1.AssertContainsTaggedFields(t, "win_services", fields, tags)
@ -227,8 +227,8 @@ func TestExcludingNamesTag(t *testing.T) {
for _, s := range testSimpleData[0].services {
fields := make(map[string]interface{})
tags := make(map[string]string)
fields["state"] = int(s.state)
fields["startup_mode"] = int(s.startUpMode)
fields["state"] = s.state
fields["startup_mode"] = s.startUpMode
tags["service_name"] = s.serviceName
tags["display_name"] = s.displayName
acc1.AssertDoesNotContainsTaggedFields(t, "win_services", fields, tags)