From 25de05a8fc0d0e4dabf3bad85fd889ef3332b8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20=C5=BBak?= Date: Mon, 27 Jan 2025 19:34:59 +0100 Subject: [PATCH] chore: Fix linter findings for `revive:exported` in `plugins/inputs/win*` (#16427) --- plugins/inputs/win_eventlog/event.go | 17 +- .../inputs/win_eventlog/syscall_windows.go | 33 +- plugins/inputs/win_eventlog/util.go | 32 +- plugins/inputs/win_eventlog/util_test.go | 27 +- plugins/inputs/win_eventlog/win_eventlog.go | 129 ++-- .../win_eventlog/win_eventlog_notwindows.go | 10 +- .../inputs/win_eventlog/win_eventlog_test.go | 3 - .../inputs/win_eventlog/zsyscall_windows.go | 90 ++- plugins/inputs/win_perf_counters/pdh.go | 579 +++++++++--------- plugins/inputs/win_perf_counters/pdh_386.go | 11 +- plugins/inputs/win_perf_counters/pdh_amd64.go | 6 +- plugins/inputs/win_perf_counters/pdh_arm64.go | 4 +- .../win_perf_counters/performance_query.go | 188 +++--- .../win_perf_counters/win_perf_counters.go | 318 +++++----- .../win_perf_counters_integration_test.go | 72 +-- .../win_perf_counters_notwindows.go | 2 +- .../win_perf_counters_test.go | 272 ++++---- plugins/inputs/win_services/win_services.go | 181 +++--- .../win_services_integration_test.go | 20 +- .../win_services/win_services_notwindows.go | 1 + .../inputs/win_services/win_services_test.go | 22 +- plugins/inputs/win_wmi/method.go | 7 +- plugins/inputs/win_wmi/query.go | 9 +- plugins/inputs/win_wmi/win_wmi.go | 32 +- plugins/inputs/win_wmi/win_wmi_notwindows.go | 8 +- plugins/inputs/win_wmi/win_wmi_test.go | 6 +- 26 files changed, 1012 insertions(+), 1067 deletions(-) diff --git a/plugins/inputs/win_eventlog/event.go b/plugins/inputs/win_eventlog/event.go index 8c06d800f..1f4e2bbb3 100644 --- a/plugins/inputs/win_eventlog/event.go +++ b/plugins/inputs/win_eventlog/event.go @@ -1,15 +1,12 @@ //go:build windows -// Package win_eventlog Input plugin to collect Windows Event Log messages -// -//revive:disable-next-line:var-naming package win_eventlog -// Event is the event entry representation +// event is the event entry representation // Only the most common elements are processed, human-readable data is rendered in Message // More info on schema, if there will be need to add more: // https://docs.microsoft.com/en-us/windows/win32/wes/eventschema-elements -type Event struct { +type event struct { Source provider `xml:"System>Provider"` EventID int `xml:"System>EventID"` Version int `xml:"System>Version"` @@ -44,7 +41,7 @@ type eventData struct { InnerXML []byte `xml:",innerxml"` } -// provider is the Event provider information +// provider is the event provider information type provider struct { Name string `xml:"Name,attr"` } @@ -55,24 +52,24 @@ type correlation struct { RelatedActivityID string `xml:"RelatedActivityID,attr"` } -// execution Info for Event +// execution Info for event type execution struct { ProcessID uint32 `xml:"ProcessID,attr"` ThreadID uint32 `xml:"ThreadID,attr"` ProcessName string } -// security Data for Event +// security Data for event type security struct { UserID string `xml:"UserID,attr"` } -// timeCreated field for Event +// timeCreated field for event type timeCreated struct { SystemTime string `xml:"SystemTime,attr"` } -// renderingInfo is provided for events forwarded by Windows Event Collector +// renderingInfo is provided for events forwarded by Windows event Collector // see https://learn.microsoft.com/en-us/windows/win32/api/winevt/nf-winevt-evtformatmessage#parameters type renderingInfo struct { Message string `xml:"Message"` diff --git a/plugins/inputs/win_eventlog/syscall_windows.go b/plugins/inputs/win_eventlog/syscall_windows.go index b29a6b168..fb19d4fb1 100644 --- a/plugins/inputs/win_eventlog/syscall_windows.go +++ b/plugins/inputs/win_eventlog/syscall_windows.go @@ -1,41 +1,36 @@ //go:build windows -// Package win_eventlog Input plugin to collect Windows Event Log messages -// -//revive:disable-next-line:var-naming package win_eventlog import "syscall" -// Event log error codes. +// event log error codes. // https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx const ( - //revive:disable:var-naming - ERROR_INSUFFICIENT_BUFFER syscall.Errno = 122 - ERROR_NO_MORE_ITEMS syscall.Errno = 259 - ERROR_INVALID_OPERATION syscall.Errno = 4317 - //revive:enable:var-naming + errInsufficientBuffer syscall.Errno = 122 + errNoMoreItems syscall.Errno = 259 + errInvalidOperation syscall.Errno = 4317 ) -// EvtSubscribeFlag defines the possible values that specify when to start subscribing to events. -type EvtSubscribeFlag uint32 +// evtSubscribeFlag defines the possible values that specify when to start subscribing to events. +type evtSubscribeFlag uint32 // EVT_SUBSCRIBE_FLAGS enumeration // https://msdn.microsoft.com/en-us/library/windows/desktop/aa385588(v=vs.85).aspx const ( - EvtSubscribeToFutureEvents EvtSubscribeFlag = 1 - EvtSubscribeStartAtOldestRecord EvtSubscribeFlag = 2 - EvtSubscribeStartAfterBookmark EvtSubscribeFlag = 3 + evtSubscribeToFutureEvents evtSubscribeFlag = 1 + evtSubscribeStartAtOldestRecord evtSubscribeFlag = 2 + evtSubscribeStartAfterBookmark evtSubscribeFlag = 3 ) -// EvtRenderFlag uint32 -type EvtRenderFlag uint32 +// evtRenderFlag uint32 +type evtRenderFlag uint32 // EVT_RENDER_FLAGS enumeration // https://msdn.microsoft.com/en-us/library/windows/desktop/aa385563(v=vs.85).aspx const ( - // Render the event as an XML string. For details on the contents of the XML string, see the Event schema. - EvtRenderEventXML EvtRenderFlag = 1 + // Render the event as an XML string. For details on the contents of the XML string, see the event schema. + evtRenderEventXML evtRenderFlag = 1 // Render bookmark - EvtRenderBookmark EvtRenderFlag = 2 + evtRenderBookmark evtRenderFlag = 2 ) diff --git a/plugins/inputs/win_eventlog/util.go b/plugins/inputs/win_eventlog/util.go index 3f8639a8d..92e8a984d 100644 --- a/plugins/inputs/win_eventlog/util.go +++ b/plugins/inputs/win_eventlog/util.go @@ -1,8 +1,5 @@ //go:build windows -// Package win_eventlog Input plugin to collect Windows Event Log messages -// -//revive:disable-next-line:var-naming package win_eventlog import ( @@ -18,8 +15,8 @@ import ( "golang.org/x/sys/windows" ) -// DecodeUTF16 to UTF8 bytes -func DecodeUTF16(b []byte) ([]byte, error) { +// decodeUTF16 to UTF8 bytes +func decodeUTF16(b []byte) ([]byte, error) { if len(b)%2 != 0 { return nil, errors.New("must have even length byte slice") } @@ -41,9 +38,9 @@ func DecodeUTF16(b []byte) ([]byte, error) { return ret.Bytes(), nil } -// GetFromSnapProcess finds information about process by the given pid +// getFromSnapProcess finds information about process by the given pid // Returns process name -func GetFromSnapProcess(pid uint32) (string, error) { +func getFromSnapProcess(pid uint32) (string, error) { snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, pid) if err != nil { return "", err @@ -74,8 +71,8 @@ type xmlnode struct { Nodes []xmlnode `xml:",any"` } -// EventField for unique rendering -type EventField struct { +// eventField for unique rendering +type eventField struct { Name string Value string } @@ -88,11 +85,11 @@ func (n *xmlnode) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { return d.DecodeElement((*node)(n), &start) } -// UnrollXMLFields extracts fields from xml data -func UnrollXMLFields(data []byte, fieldsUsage map[string]int, separator string) ([]EventField, map[string]int) { +// unrollXMLFields extracts fields from xml data +func unrollXMLFields(data []byte, fieldsUsage map[string]int, separator string) ([]eventField, map[string]int) { buf := bytes.NewBuffer(data) dec := xml.NewDecoder(buf) - var fields []EventField + var fields []eventField for { var node xmlnode err := dec.Decode(&node) @@ -106,7 +103,7 @@ func UnrollXMLFields(data []byte, fieldsUsage map[string]int, separator string) if len(innerText) > 0 { valueName := strings.Join(parents, separator) fieldsUsage[valueName]++ - field := EventField{Name: valueName, Value: innerText} + field := eventField{Name: valueName, Value: innerText} fields = append(fields, field) } return true @@ -132,18 +129,17 @@ func walkXML(nodes []xmlnode, parents []string, separator string, f func(xmlnode } } -// UniqueFieldNames forms unique field names -// by adding _ if there are several of them -func UniqueFieldNames(fields []EventField, fieldsUsage map[string]int, separator string) []EventField { +// uniqueFieldNames forms unique field names by adding _ if there are several of them +func uniqueFieldNames(fields []eventField, fieldsUsage map[string]int, separator string) []eventField { var fieldsCounter = make(map[string]int, len(fields)) - fieldsUnique := make([]EventField, 0, len(fields)) + fieldsUnique := make([]eventField, 0, len(fields)) for _, field := range fields { fieldName := field.Name if fieldsUsage[field.Name] > 1 { fieldsCounter[field.Name]++ fieldName = fmt.Sprint(field.Name, separator, fieldsCounter[field.Name]) } - fieldsUnique = append(fieldsUnique, EventField{ + fieldsUnique = append(fieldsUnique, eventField{ Name: fieldName, Value: field.Value, }) diff --git a/plugins/inputs/win_eventlog/util_test.go b/plugins/inputs/win_eventlog/util_test.go index a36601e42..b3fbc0f57 100644 --- a/plugins/inputs/win_eventlog/util_test.go +++ b/plugins/inputs/win_eventlog/util_test.go @@ -1,8 +1,5 @@ //go:build windows -// Package win_eventlog Input plugin to collect Windows Event Log messages -// -//revive:disable-next-line:var-naming package win_eventlog import ( @@ -52,13 +49,13 @@ func TestDecodeUTF16(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := DecodeUTF16(tt.args.b) + got, err := decodeUTF16(tt.args.b) if (err != nil) != tt.wantErr { - t.Errorf("DecodeUTF16() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("decodeUTF16() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("DecodeUTF16() = %v, want %v", got, tt.want) + t.Errorf("decodeUTF16() = %v, want %v", got, tt.want) } }) } @@ -110,7 +107,7 @@ func TestUnrollXMLFields(t *testing.T) { tests := []struct { name string args args - want1 []EventField + want1 []eventField want2 map[string]int }{ { @@ -128,7 +125,7 @@ func TestUnrollXMLFields(t *testing.T) { data: container.EventData.InnerXML, fieldsUsage: map[string]int{}, }, - want1: []EventField{ + want1: []eventField{ {Name: "Data", Value: "2120-07-26T15:24:25Z"}, {Name: "Data", Value: "RulesEngine"}, {Name: "Data_Engine", Value: "RulesEngine"}, @@ -141,7 +138,7 @@ func TestUnrollXMLFields(t *testing.T) { data: container.UserData.InnerXML, fieldsUsage: map[string]int{}, }, - want1: []EventField{ + want1: []eventField{ {Name: "CbsPackageChangeState_IntendedPackageState", Value: "5111"}, {Name: "CbsPackageChangeState_ErrorCode_Code", Value: "0x0"}, }, @@ -153,7 +150,7 @@ func TestUnrollXMLFields(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, got1 := UnrollXMLFields(tt.args.data, tt.args.fieldsUsage, "_") + got, got1 := unrollXMLFields(tt.args.data, tt.args.fieldsUsage, "_") if !reflect.DeepEqual(got, tt.want1) { t.Errorf("ExtractFields() got = %v, want %v", got, tt.want1) } @@ -166,25 +163,25 @@ func TestUnrollXMLFields(t *testing.T) { func TestUniqueFieldNames(t *testing.T) { type args struct { - fields []EventField + fields []eventField fieldsUsage map[string]int } tests := []struct { name string args args - want []EventField + want []eventField }{ { name: "Unique values", args: args{ - fields: []EventField{ + fields: []eventField{ {Name: "Data", Value: "2120-07-26T15:24:25Z"}, {Name: "Data", Value: "RulesEngine"}, {Name: "Engine", Value: "RulesEngine"}, }, fieldsUsage: map[string]int{"Data": 2, "Engine": 1}, }, - want: []EventField{ + want: []eventField{ {Name: "Data_1", Value: "2120-07-26T15:24:25Z"}, {Name: "Data_2", Value: "RulesEngine"}, {Name: "Engine", Value: "RulesEngine"}, @@ -193,7 +190,7 @@ func TestUniqueFieldNames(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := UniqueFieldNames(tt.args.fields, tt.args.fieldsUsage, "_"); !reflect.DeepEqual(got, tt.want) { + if got := uniqueFieldNames(tt.args.fields, tt.args.fieldsUsage, "_"); !reflect.DeepEqual(got, tt.want) { t.Errorf("PrintFields() = %v, want %v", got, tt.want) } }) diff --git a/plugins/inputs/win_eventlog/win_eventlog.go b/plugins/inputs/win_eventlog/win_eventlog.go index f0c60cf9b..44de33906 100644 --- a/plugins/inputs/win_eventlog/win_eventlog.go +++ b/plugins/inputs/win_eventlog/win_eventlog.go @@ -1,9 +1,6 @@ //go:generate ../../../tools/readme_config_includer/generator //go:build windows -// Package win_eventlog Input plugin to collect Windows Event Log messages -// -//revive:disable-next-line:var-naming package win_eventlog import ( @@ -28,7 +25,8 @@ import ( //go:embed sample.conf var sampleConfig string -// WinEventLog config +const bufferSize = 1 << 14 + type WinEventLog struct { Locale uint32 `toml:"locale"` EventlogName string `toml:"eventlog_name"` @@ -46,16 +44,14 @@ type WinEventLog struct { ExcludeEmpty []string `toml:"exclude_empty"` Log telegraf.Logger `toml:"-"` - subscription EvtHandle - subscriptionFlag EvtSubscribeFlag - bookmark EvtHandle + subscription evtHandle + subscriptionFlag evtSubscribeFlag + bookmark evtHandle tagFilter filter.Filter fieldFilter filter.Filter fieldEmptyFilter filter.Filter } -const bufferSize = 1 << 14 - func (*WinEventLog) SampleConfig() string { return sampleConfig } @@ -66,16 +62,16 @@ func (w *WinEventLog) Init() error { w.BatchSize = 5 } - w.subscriptionFlag = EvtSubscribeToFutureEvents + w.subscriptionFlag = evtSubscribeToFutureEvents if w.FromBeginning { - w.subscriptionFlag = EvtSubscribeStartAtOldestRecord + w.subscriptionFlag = evtSubscribeStartAtOldestRecord } if w.Query == "" { w.Query = "*" } - bookmark, err := _EvtCreateBookmark(nil) + bookmark, err := evtCreateBookmark(nil) if err != nil { return err } @@ -96,7 +92,7 @@ func (w *WinEventLog) Init() error { return nil } -func (w *WinEventLog) Start(_ telegraf.Accumulator) error { +func (w *WinEventLog) Start(telegraf.Accumulator) error { subscription, err := w.evtSubscribe() if err != nil { return fmt.Errorf("subscription of Windows Event Log failed: %w", err) @@ -107,11 +103,6 @@ func (w *WinEventLog) Start(_ telegraf.Accumulator) error { return nil } -func (w *WinEventLog) Stop() { - //nolint:errcheck // ending the subscription, error can be ignored - _ = _EvtClose(w.subscription) -} - func (w *WinEventLog) GetState() interface{} { bookmarkXML, err := renderBookmark(w.bookmark) if err != nil { @@ -132,22 +123,21 @@ func (w *WinEventLog) SetState(state interface{}) error { return fmt.Errorf("conversion to pointer failed: %w", err) } - bookmark, err := _EvtCreateBookmark(ptr) + bookmark, err := evtCreateBookmark(ptr) if err != nil { return fmt.Errorf("creating bookmark failed: %w", err) } w.bookmark = bookmark - w.subscriptionFlag = EvtSubscribeStartAfterBookmark + w.subscriptionFlag = evtSubscribeStartAfterBookmark return nil } -// Gather Windows Event Log entries func (w *WinEventLog) Gather(acc telegraf.Accumulator) error { for { events, err := w.fetchEvents(w.subscription) if err != nil { - if errors.Is(err, ERROR_NO_MORE_ITEMS) { + if errors.Is(err, errNoMoreItems) { break } w.Log.Errorf("Error getting events: %v", err) @@ -163,7 +153,7 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error { event := events[i] evt := reflect.ValueOf(&event).Elem() timeStamp := time.Now() - // Walk through all fields of Event struct to process System tags or fields + // Walk through all fields of event struct to process System tags or fields for i := 0; i < evt.NumField(); i++ { fieldName := evt.Type().Field(i).Name fieldType := evt.Field(i).Type().String() @@ -179,7 +169,7 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error { fieldName = "ProcessID" // Look up Process Name from pid if should, _ := w.shouldProcessField("ProcessName"); should { - processName, err := GetFromSnapProcess(fieldValue) + processName, err := getFromSnapProcess(fieldValue) if err == nil { computedValues["ProcessName"] = processName } @@ -250,18 +240,18 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error { } // Unroll additional XML - var xmlFields []EventField + var xmlFields []eventField if w.ProcessUserData { - fieldsUserData, xmlFieldsUsage := UnrollXMLFields(event.UserData.InnerXML, fieldsUsage, w.Separator) + fieldsUserData, xmlFieldsUsage := unrollXMLFields(event.UserData.InnerXML, fieldsUsage, w.Separator) xmlFields = append(xmlFields, fieldsUserData...) fieldsUsage = xmlFieldsUsage } if w.ProcessEventData { - fieldsEventData, xmlFieldsUsage := UnrollXMLFields(event.EventData.InnerXML, fieldsUsage, w.Separator) + fieldsEventData, xmlFieldsUsage := unrollXMLFields(event.EventData.InnerXML, fieldsUsage, w.Separator) xmlFields = append(xmlFields, fieldsEventData...) fieldsUsage = xmlFieldsUsage } - uniqueXMLFields := UniqueFieldNames(xmlFields, fieldsUsage, w.Separator) + uniqueXMLFields := uniqueFieldNames(xmlFields, fieldsUsage, w.Separator) for _, xmlField := range uniqueXMLFields { should, where := w.shouldProcessField(xmlField.Name) if !should { @@ -282,6 +272,11 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error { return nil } +func (w *WinEventLog) Stop() { + //nolint:errcheck // ending the subscription, error can be ignored + _ = evtClose(w.subscription) +} + func (w *WinEventLog) shouldProcessField(field string) (should bool, list string) { if w.tagFilter != nil && w.tagFilter.Match(field) { return true, "tags" @@ -311,7 +306,7 @@ func (w *WinEventLog) shouldExcludeEmptyField(field, fieldType string, fieldValu return false } -func (w *WinEventLog) evtSubscribe() (EvtHandle, error) { +func (w *WinEventLog) evtSubscribe() (evtHandle, error) { sigEvent, err := windows.CreateEvent(nil, 0, 0, nil) if err != nil { return 0, err @@ -328,11 +323,11 @@ func (w *WinEventLog) evtSubscribe() (EvtHandle, error) { return 0, err } - var bookmark EvtHandle - if w.subscriptionFlag == EvtSubscribeStartAfterBookmark { + var bookmark evtHandle + if w.subscriptionFlag == evtSubscribeStartAfterBookmark { bookmark = w.bookmark } - subsHandle, err := _EvtSubscribe(0, uintptr(sigEvent), logNamePtr, xqueryPtr, bookmark, 0, 0, w.subscriptionFlag) + subsHandle, err := evtSubscribe(0, uintptr(sigEvent), logNamePtr, xqueryPtr, bookmark, 0, 0, w.subscriptionFlag) if err != nil { return 0, err } @@ -340,13 +335,13 @@ func (w *WinEventLog) evtSubscribe() (EvtHandle, error) { return subsHandle, nil } -func (w *WinEventLog) fetchEventHandles(subsHandle EvtHandle) ([]EvtHandle, error) { +func (w *WinEventLog) fetchEventHandles(subsHandle evtHandle) ([]evtHandle, error) { var evtReturned uint32 - eventHandles := make([]EvtHandle, w.BatchSize) - if err := _EvtNext(subsHandle, w.BatchSize, &eventHandles[0], 0, 0, &evtReturned); err != nil { - if errors.Is(err, ERROR_INVALID_OPERATION) && evtReturned == 0 { - return nil, ERROR_NO_MORE_ITEMS + eventHandles := make([]evtHandle, w.BatchSize) + if err := evtNext(subsHandle, w.BatchSize, &eventHandles[0], 0, 0, &evtReturned); err != nil { + if errors.Is(err, errInvalidOperation) && evtReturned == 0 { + return nil, errNoMoreItems } return nil, err } @@ -354,8 +349,8 @@ func (w *WinEventLog) fetchEventHandles(subsHandle EvtHandle) ([]EvtHandle, erro return eventHandles[:evtReturned], nil } -func (w *WinEventLog) fetchEvents(subsHandle EvtHandle) ([]Event, error) { - var events []Event +func (w *WinEventLog) fetchEvents(subsHandle evtHandle) ([]event, error) { + var events []event eventHandles, err := w.fetchEventHandles(subsHandle) if err != nil { @@ -370,27 +365,27 @@ func (w *WinEventLog) fetchEvents(subsHandle EvtHandle) ([]Event, error) { if event, err := w.renderEvent(eventHandle); err == nil { events = append(events, event) } - if err := _EvtUpdateBookmark(w.bookmark, eventHandle); err != nil && evterr == nil { + if err := evtUpdateBookmark(w.bookmark, eventHandle); err != nil && evterr == nil { evterr = err } - if err := _EvtClose(eventHandle); err != nil && evterr == nil { + if err := evtClose(eventHandle); err != nil && evterr == nil { evterr = err } } return events, evterr } -func renderBookmark(bookmark EvtHandle) (string, error) { +func renderBookmark(bookmark evtHandle) (string, error) { var bufferUsed, propertyCount uint32 buf := make([]byte, bufferSize) - err := _EvtRender(0, bookmark, EvtRenderBookmark, uint32(len(buf)), &buf[0], &bufferUsed, &propertyCount) + err := evtRender(0, bookmark, evtRenderBookmark, uint32(len(buf)), &buf[0], &bufferUsed, &propertyCount) if err != nil { return "", err } - x, err := DecodeUTF16(buf[:bufferUsed]) + x, err := decodeUTF16(buf[:bufferUsed]) if err != nil { return "", err } @@ -400,17 +395,17 @@ func renderBookmark(bookmark EvtHandle) (string, error) { return string(x), err } -func (w *WinEventLog) renderEvent(eventHandle EvtHandle) (Event, error) { +func (w *WinEventLog) renderEvent(eventHandle evtHandle) (event, error) { var bufferUsed, propertyCount uint32 buf := make([]byte, bufferSize) - event := Event{} - err := _EvtRender(0, eventHandle, EvtRenderEventXML, uint32(len(buf)), &buf[0], &bufferUsed, &propertyCount) + event := event{} + err := evtRender(0, eventHandle, evtRenderEventXML, uint32(len(buf)), &buf[0], &bufferUsed, &propertyCount) if err != nil { return event, err } - eventXML, err := DecodeUTF16(buf[:bufferUsed]) + eventXML, err := decodeUTF16(buf[:bufferUsed]) if err != nil { return event, err } @@ -434,19 +429,19 @@ func (w *WinEventLog) renderEvent(eventHandle EvtHandle) (Event, error) { return w.renderRemoteMessage(event) } -func (w *WinEventLog) renderLocalMessage(event Event, 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 } - defer _EvtClose(publisherHandle) //nolint:errcheck // Ignore error returned during Close + defer evtClose(publisherHandle) //nolint:errcheck // Ignore error returned during Close // Populating text values - keywords, err := formatEventString(EvtFormatMessageKeyword, eventHandle, publisherHandle) + keywords, err := formatEventString(evtFormatMessageKeyword, eventHandle, publisherHandle) if err == nil { event.Keywords = keywords } - message, err := formatEventString(EvtFormatMessageEvent, eventHandle, publisherHandle) + message, err := formatEventString(evtFormatMessageEvent, eventHandle, publisherHandle) if err == nil { if w.OnlyFirstLineOfMessage { scanner := bufio.NewScanner(strings.NewReader(message)) @@ -455,22 +450,22 @@ func (w *WinEventLog) renderLocalMessage(event Event, eventHandle EvtHandle) (Ev } event.Message = message } - level, err := formatEventString(EvtFormatMessageLevel, eventHandle, publisherHandle) + level, err := formatEventString(evtFormatMessageLevel, eventHandle, publisherHandle) if err == nil { event.LevelText = level } - task, err := formatEventString(EvtFormatMessageTask, eventHandle, publisherHandle) + task, err := formatEventString(evtFormatMessageTask, eventHandle, publisherHandle) if err == nil { event.TaskText = task } - opcode, err := formatEventString(EvtFormatMessageOpcode, eventHandle, publisherHandle) + opcode, err := formatEventString(evtFormatMessageOpcode, eventHandle, publisherHandle) if err == nil { event.OpcodeText = opcode } return event, nil } -func (w *WinEventLog) renderRemoteMessage(event Event) (Event, error) { +func (w *WinEventLog) renderRemoteMessage(event event) (event, error) { // Populating text values from RenderingInfo part of the XML if len(event.RenderingInfo.Keywords) > 0 { event.Keywords = strings.Join(event.RenderingInfo.Keywords, ",") @@ -496,11 +491,11 @@ func (w *WinEventLog) renderRemoteMessage(event Event) (Event, error) { return event, nil } -func formatEventString(messageFlag EvtFormatMessageFlag, eventHandle, publisherHandle EvtHandle) (string, error) { +func formatEventString(messageFlag evtFormatMessageFlag, eventHandle, publisherHandle evtHandle) (string, error) { var bufferUsed uint32 - err := _EvtFormatMessage(publisherHandle, eventHandle, 0, 0, 0, messageFlag, + err := evtFormatMessage(publisherHandle, eventHandle, 0, 0, 0, messageFlag, 0, nil, &bufferUsed) - if err != nil && !errors.Is(err, ERROR_INSUFFICIENT_BUFFER) { + if err != nil && !errors.Is(err, errInsufficientBuffer) { return "", err } @@ -513,20 +508,20 @@ func formatEventString(messageFlag EvtFormatMessageFlag, eventHandle, publisherH buffer := make([]byte, bufferUsed) bufferUsed = 0 - err = _EvtFormatMessage(publisherHandle, eventHandle, 0, 0, 0, messageFlag, + err = evtFormatMessage(publisherHandle, eventHandle, 0, 0, 0, messageFlag, uint32(len(buffer)/2), &buffer[0], &bufferUsed) bufferUsed *= 2 if err != nil { return "", err } - result, err := DecodeUTF16(buffer[:bufferUsed]) + result, err := decodeUTF16(buffer[:bufferUsed]) if err != nil { return "", err } var out string - if messageFlag == EvtFormatMessageKeyword { + if messageFlag == evtFormatMessageKeyword { // Keywords are returned as array of a zero-terminated strings splitZero := func(c rune) bool { return c == '\x00' } eventKeywords := strings.FieldsFunc(string(result), splitZero) @@ -540,18 +535,14 @@ func formatEventString(messageFlag EvtFormatMessageFlag, eventHandle, publisherH } // openPublisherMetadata opens a handle to the publisher's metadata. Close must -// be called on returned EvtHandle when finished with the handle. -func openPublisherMetadata( - session EvtHandle, - publisherName string, - lang uint32, -) (EvtHandle, error) { +// be called on returned evtHandle when finished with the handle. +func openPublisherMetadata(session evtHandle, publisherName string, lang uint32) (evtHandle, error) { p, err := syscall.UTF16PtrFromString(publisherName) if err != nil { return 0, err } - h, err := _EvtOpenPublisherMetadata(session, p, nil, lang, 0) + h, err := evtOpenPublisherMetadata(session, p, nil, lang, 0) if err != nil { return 0, err } diff --git a/plugins/inputs/win_eventlog/win_eventlog_notwindows.go b/plugins/inputs/win_eventlog/win_eventlog_notwindows.go index c2baadedd..c0e41d53d 100644 --- a/plugins/inputs/win_eventlog/win_eventlog_notwindows.go +++ b/plugins/inputs/win_eventlog/win_eventlog_notwindows.go @@ -17,14 +17,14 @@ type WinEventLog struct { Log telegraf.Logger `toml:"-"` } +func (*WinEventLog) SampleConfig() string { return sampleConfig } + func (w *WinEventLog) Init() error { - w.Log.Warn("current platform is not supported") + w.Log.Warn("Current platform is not supported") return nil } -func (*WinEventLog) SampleConfig() string { return sampleConfig } -func (*WinEventLog) Gather(_ telegraf.Accumulator) error { return nil } -func (*WinEventLog) Start(_ telegraf.Accumulator) error { return nil } -func (*WinEventLog) Stop() {} + +func (*WinEventLog) Gather(telegraf.Accumulator) error { return nil } func init() { inputs.Add("win_eventlog", func() telegraf.Input { diff --git a/plugins/inputs/win_eventlog/win_eventlog_test.go b/plugins/inputs/win_eventlog/win_eventlog_test.go index c7f0f8e4f..8dbcb5943 100644 --- a/plugins/inputs/win_eventlog/win_eventlog_test.go +++ b/plugins/inputs/win_eventlog/win_eventlog_test.go @@ -1,8 +1,5 @@ //go:build windows -// Package win_eventlog Input plugin to collect Windows Event Log messages -// -//revive:disable-next-line:var-naming package win_eventlog import ( diff --git a/plugins/inputs/win_eventlog/zsyscall_windows.go b/plugins/inputs/win_eventlog/zsyscall_windows.go index 4e61f4b8f..7185de3e2 100644 --- a/plugins/inputs/win_eventlog/zsyscall_windows.go +++ b/plugins/inputs/win_eventlog/zsyscall_windows.go @@ -1,8 +1,5 @@ //go:build windows -// Package win_eventlog Input plugin to collect Windows Event Log messages -// -//revive:disable-next-line:var-naming package win_eventlog import ( @@ -14,50 +11,45 @@ import ( var _ unsafe.Pointer -// EvtHandle uintptr -type EvtHandle uintptr +// evtHandle uintptr +type evtHandle uintptr -// Do the interface allocations only once for common -// Errno values. +// Do the interface allocations only once for common errno values. const ( - //revive:disable-next-line:var-naming - errnoERROR_IO_PENDING = 997 + errnoErrorIOPending = 997 ) var ( - //revive:disable-next-line:var-naming - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errErrorIOPending error = syscall.Errno(errnoErrorIOPending) ) -// EvtFormatMessageFlag defines the values that specify the message string from -// the event to format. -type EvtFormatMessageFlag uint32 +// evtFormatMessageFlag defines the values that specify the message string from the event to format. +type evtFormatMessageFlag uint32 // EVT_FORMAT_MESSAGE_FLAGS enumeration // https://msdn.microsoft.com/en-us/library/windows/desktop/aa385525(v=vs.85).aspx const ( - // EvtFormatMessageEvent - Format the event's message string. - EvtFormatMessageEvent EvtFormatMessageFlag = iota + 1 - // EvtFormatMessageLevel - Format the message string of the level specified in the event. - EvtFormatMessageLevel - // EvtFormatMessageTask - Format the message string of the task specified in the event. - EvtFormatMessageTask - // EvtFormatMessageOpcode - Format the message string of the task specified in the event. - EvtFormatMessageOpcode - // EvtFormatMessageKeyword - Format the message string of the keywords specified in the event. If the + // evtFormatMessageEvent - Format the event's message string. + evtFormatMessageEvent evtFormatMessageFlag = iota + 1 + // evtFormatMessageLevel - Format the message string of the level specified in the event. + evtFormatMessageLevel + // evtFormatMessageTask - Format the message string of the task specified in the event. + evtFormatMessageTask + // evtFormatMessageOpcode - Format the message string of the task specified in the event. + evtFormatMessageOpcode + // 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 + evtFormatMessageKeyword ) -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. +// errnoErr returns common boxed Errno values, to prevent allocations at runtime. func errnoErr(e syscall.Errno) error { switch e { case 0: return nil - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING + case errnoErrorIOPending: + return errErrorIOPending } return e @@ -77,16 +69,16 @@ var ( ) //nolint:revive //argument-limit conditionally more arguments allowed -func _EvtSubscribe( - session EvtHandle, +func evtSubscribe( + session evtHandle, signalEvent uintptr, channelPath *uint16, query *uint16, - bookmark EvtHandle, + bookmark evtHandle, context uintptr, callback syscall.Handle, - flags EvtSubscribeFlag, -) (EvtHandle, error) { + flags evtSubscribeFlag, +) (evtHandle, error) { r0, _, e1 := syscall.SyscallN( procEvtSubscribe.Addr(), uintptr(session), @@ -100,7 +92,7 @@ func _EvtSubscribe( ) var err error - handle := EvtHandle(r0) + handle := evtHandle(r0) if handle == 0 { if e1 != 0 { err = errnoErr(e1) @@ -112,10 +104,10 @@ func _EvtSubscribe( } //nolint:revive //argument-limit conditionally more arguments allowed -func _EvtRender( - context EvtHandle, - fragment EvtHandle, - flags EvtRenderFlag, +func evtRender( + context evtHandle, + fragment evtHandle, + flags evtRenderFlag, bufferSize uint32, buffer *byte, bufferUsed *uint32, @@ -143,7 +135,7 @@ func _EvtRender( return err } -func _EvtClose(object EvtHandle) error { +func evtClose(object evtHandle) error { r1, _, e1 := syscall.SyscallN(procEvtClose.Addr(), uintptr(object)) var err error if r1 == 0 { @@ -156,7 +148,7 @@ func _EvtClose(object EvtHandle) error { return err } -func _EvtNext(resultSet EvtHandle, eventArraySize uint32, eventArray *EvtHandle, timeout, flags uint32, numReturned *uint32) error { +func evtNext(resultSet evtHandle, eventArraySize uint32, eventArray *evtHandle, timeout, flags uint32, numReturned *uint32) error { r1, _, e1 := syscall.SyscallN( procEvtNext.Addr(), uintptr(resultSet), @@ -179,13 +171,13 @@ func _EvtNext(resultSet EvtHandle, eventArraySize uint32, eventArray *EvtHandle, } //nolint:revive //argument-limit conditionally more arguments allowed -func _EvtFormatMessage( - publisherMetadata EvtHandle, - event EvtHandle, +func evtFormatMessage( + publisherMetadata evtHandle, + event evtHandle, messageID uint32, valueCount uint32, values uintptr, - flags EvtFormatMessageFlag, + flags evtFormatMessageFlag, bufferSize uint32, buffer *byte, bufferUsed *uint32, @@ -214,7 +206,7 @@ func _EvtFormatMessage( return err } -func _EvtOpenPublisherMetadata(session EvtHandle, publisherIdentity, logFilePath *uint16, locale, flags uint32) (EvtHandle, error) { +func evtOpenPublisherMetadata(session evtHandle, publisherIdentity, logFilePath *uint16, locale, flags uint32) (evtHandle, error) { r0, _, e1 := syscall.SyscallN( procEvtOpenPublisherMetadata.Addr(), uintptr(session), @@ -225,7 +217,7 @@ func _EvtOpenPublisherMetadata(session EvtHandle, publisherIdentity, logFilePath ) var err error - handle := EvtHandle(r0) + handle := evtHandle(r0) if handle == 0 { if e1 != 0 { err = errnoErr(e1) @@ -236,10 +228,10 @@ func _EvtOpenPublisherMetadata(session EvtHandle, publisherIdentity, logFilePath return handle, err } -func _EvtCreateBookmark(bookmarkXML *uint16) (EvtHandle, error) { +func evtCreateBookmark(bookmarkXML *uint16) (evtHandle, error) { //nolint:gosec // G103: Valid use of unsafe call to pass bookmarkXML r0, _, e1 := syscall.SyscallN(procEvtCreateBookmark.Addr(), uintptr(unsafe.Pointer(bookmarkXML))) - handle := EvtHandle(r0) + handle := evtHandle(r0) if handle != 0 { return handle, nil } @@ -249,7 +241,7 @@ func _EvtCreateBookmark(bookmarkXML *uint16) (EvtHandle, error) { return handle, syscall.EINVAL } -func _EvtUpdateBookmark(bookmark, event EvtHandle) error { +func evtUpdateBookmark(bookmark, event evtHandle) error { r0, _, e1 := syscall.SyscallN(procEvtUpdateBookmark.Addr(), uintptr(bookmark), uintptr(event)) if r0 != 0 { return nil diff --git a/plugins/inputs/win_perf_counters/pdh.go b/plugins/inputs/win_perf_counters/pdh.go index 0ce63c4e1..9ee031a9b 100644 --- a/plugins/inputs/win_perf_counters/pdh.go +++ b/plugins/inputs/win_perf_counters/pdh.go @@ -44,215 +44,214 @@ import ( // Error codes const ( - ErrorSuccess = 0 - ErrorFailure = 1 - ErrorInvalidFunction = 1 - EpochDifferenceMicros int64 = 11644473600000000 + errorSuccess = 0 + errorFailure = 1 + errorInvalidFunction = 1 + epochDifferenceMicros int64 = 11644473600000000 ) type ( - HANDLE uintptr + handle uintptr ) // PDH error codes, which can be returned by all Pdh* functions. Taken from mingw-w64 pdhmsg.h - const ( - PdhCstatusValidData = 0x00000000 // The returned data is valid. - PdhCstatusNewData = 0x00000001 // The return data value is valid and different from the last sample. - PdhCstatusNoMachine = 0x800007D0 // Unable to connect to the specified computer, or the computer is offline. - PdhCstatusNoInstance = 0x800007D1 - PdhMoreData = 0x800007D2 // The PdhGetFormattedCounterArray* function can return this if there's 'more data to be displayed'. - PdhCstatusItemNotValidated = 0x800007D3 - PdhRetry = 0x800007D4 - PdhNoData = 0x800007D5 // The query does not currently contain any counters (for example, limited access) - PdhCalcNegativeDenominator = 0x800007D6 - PdhCalcNegativeTimebase = 0x800007D7 - PdhCalcNegativeValue = 0x800007D8 - PdhDialogCancelled = 0x800007D9 - PdhEndOfLogFile = 0x800007DA - PdhAsyncQueryTimeout = 0x800007DB - PdhCannotSetDefaultRealtimeDatasource = 0x800007DC - PdhCstatusNoObject = 0xC0000BB8 - PdhCstatusNoCounter = 0xC0000BB9 // The specified counter could not be found. - PdhCstatusInvalidData = 0xC0000BBA // The counter was successfully found, but the data returned is not valid. - PdhMemoryAllocationFailure = 0xC0000BBB - PdhInvalidHandle = 0xC0000BBC - PdhInvalidArgument = 0xC0000BBD // Required argument is missing or incorrect. - PdhFunctionNotFound = 0xC0000BBE - PdhCstatusNoCountername = 0xC0000BBF - PdhCstatusBadCountername = 0xC0000BC0 // Unable to parse the counter path. Check the format and syntax of the specified path. - PdhInvalidBuffer = 0xC0000BC1 - PdhInsufficientBuffer = 0xC0000BC2 - PdhCannotConnectMachine = 0xC0000BC3 - PdhInvalidPath = 0xC0000BC4 - PdhInvalidInstance = 0xC0000BC5 - PdhInvalidData = 0xC0000BC6 // specified counter does not contain valid data or a successful status code. - PdhNoDialogData = 0xC0000BC7 - PdhCannotReadNameStrings = 0xC0000BC8 - PdhLogFileCreateError = 0xC0000BC9 - PdhLogFileOpenError = 0xC0000BCA - PdhLogTypeNotFound = 0xC0000BCB - PdhNoMoreData = 0xC0000BCC - PdhEntryNotInLogFile = 0xC0000BCD - PdhDataSourceIsLogFile = 0xC0000BCE - PdhDataSourceIsRealTime = 0xC0000BCF - PdhUnableReadLogHeader = 0xC0000BD0 - PdhFileNotFound = 0xC0000BD1 - PdhFileAlreadyExists = 0xC0000BD2 - PdhNotImplemented = 0xC0000BD3 - PdhStringNotFound = 0xC0000BD4 - PdhUnableMapNameFiles = 0x80000BD5 - PdhUnknownLogFormat = 0xC0000BD6 - PdhUnknownLogsvcCommand = 0xC0000BD7 - PdhLogsvcQueryNotFound = 0xC0000BD8 - PdhLogsvcNotOpened = 0xC0000BD9 - PdhWbemError = 0xC0000BDA - PdhAccessDenied = 0xC0000BDB - PdhLogFileTooSmall = 0xC0000BDC - PdhInvalidDatasource = 0xC0000BDD - PdhInvalidSqldb = 0xC0000BDE - PdhNoCounters = 0xC0000BDF - PdhSQLAllocFailed = 0xC0000BE0 - PdhSQLAllocconFailed = 0xC0000BE1 - PdhSQLExecDirectFailed = 0xC0000BE2 - PdhSQLFetchFailed = 0xC0000BE3 - PdhSQLRowcountFailed = 0xC0000BE4 - PdhSQLMoreResultsFailed = 0xC0000BE5 - PdhSQLConnectFailed = 0xC0000BE6 - PdhSQLBindFailed = 0xC0000BE7 - PdhCannotConnectWmiServer = 0xC0000BE8 - PdhPlaCollectionAlreadyRunning = 0xC0000BE9 - PdhPlaErrorScheduleOverlap = 0xC0000BEA - PdhPlaCollectionNotFound = 0xC0000BEB - PdhPlaErrorScheduleElapsed = 0xC0000BEC - PdhPlaErrorNostart = 0xC0000BED - PdhPlaErrorAlreadyExists = 0xC0000BEE - PdhPlaErrorTypeMismatch = 0xC0000BEF - PdhPlaErrorFilepath = 0xC0000BF0 - PdhPlaServiceError = 0xC0000BF1 - PdhPlaValidationError = 0xC0000BF2 - PdhPlaValidationWarning = 0x80000BF3 - PdhPlaErrorNameTooLong = 0xC0000BF4 - PdhInvalidSQLLogFormat = 0xC0000BF5 - PdhCounterAlreadyInQuery = 0xC0000BF6 - PdhBinaryLogCorrupt = 0xC0000BF7 - PdhLogSampleTooSmall = 0xC0000BF8 - PdhOsLaterVersion = 0xC0000BF9 - PdhOsEarlierVersion = 0xC0000BFA - PdhIncorrectAppendTime = 0xC0000BFB - PdhUnmatchedAppendCounter = 0xC0000BFC - PdhSQLAlterDetailFailed = 0xC0000BFD - PdhQueryPerfDataTimeout = 0xC0000BFE + pdhCstatusValidData = 0x00000000 // The returned data is valid. + pdhCstatusNewData = 0x00000001 // The return data value is valid and different from the last sample. + pdhCstatusNoMachine = 0x800007D0 // Unable to connect to the specified computer, or the computer is offline. + pdhCstatusNoInstance = 0x800007D1 + pdhMoreData = 0x800007D2 // The pdhGetFormattedCounterArray* function can return this if there's 'more data to be displayed'. + pdhCstatusItemNotValidated = 0x800007D3 + pdhRetry = 0x800007D4 + pdhNoData = 0x800007D5 // The query does not currently contain any counters (for example, limited access) + pdhCalcNegativeDenominator = 0x800007D6 + pdhCalcNegativeTimebase = 0x800007D7 + pdhCalcNegativeValue = 0x800007D8 + pdhDialogCancelled = 0x800007D9 + pdhEndOfLogFile = 0x800007DA + pdhAsyncQueryTimeout = 0x800007DB + pdhCannotSetDefaultRealtimeDatasource = 0x800007DC + pdhCstatusNoObject = 0xC0000BB8 + pdhCstatusNoCounter = 0xC0000BB9 // The specified counter could not be found. + pdhCstatusInvalidData = 0xC0000BBA // The counter was successfully found, but the data returned is not valid. + pdhMemoryAllocationFailure = 0xC0000BBB + pdhInvalidHandle = 0xC0000BBC + pdhInvalidArgument = 0xC0000BBD // Required argument is missing or incorrect. + pdhFunctionNotFound = 0xC0000BBE + pdhCstatusNoCountername = 0xC0000BBF + pdhCstatusBadCountername = 0xC0000BC0 // Unable to parse the counter path. Check the format and syntax of the specified path. + pdhInvalidBuffer = 0xC0000BC1 + pdhInsufficientBuffer = 0xC0000BC2 + pdhCannotConnectMachine = 0xC0000BC3 + pdhInvalidPath = 0xC0000BC4 + pdhInvalidInstance = 0xC0000BC5 + pdhInvalidData = 0xC0000BC6 // specified counter does not contain valid data or a successful status code. + pdhNoDialogData = 0xC0000BC7 + pdhCannotReadNameStrings = 0xC0000BC8 + pdhLogFileCreateError = 0xC0000BC9 + pdhLogFileOpenError = 0xC0000BCA + pdhLogTypeNotFound = 0xC0000BCB + pdhNoMoreData = 0xC0000BCC + pdhEntryNotInLogFile = 0xC0000BCD + pdhDataSourceIsLogFile = 0xC0000BCE + pdhDataSourceIsRealTime = 0xC0000BCF + pdhUnableReadLogHeader = 0xC0000BD0 + pdhFileNotFound = 0xC0000BD1 + pdhFileAlreadyExists = 0xC0000BD2 + pdhNotImplemented = 0xC0000BD3 + pdhStringNotFound = 0xC0000BD4 + pdhUnableMapNameFiles = 0x80000BD5 + pdhUnknownLogFormat = 0xC0000BD6 + pdhUnknownLogsvcCommand = 0xC0000BD7 + pdhLogsvcQueryNotFound = 0xC0000BD8 + pdhLogsvcNotOpened = 0xC0000BD9 + pdhWbemError = 0xC0000BDA + pdhAccessDenied = 0xC0000BDB + pdhLogFileTooSmall = 0xC0000BDC + pdhInvalidDatasource = 0xC0000BDD + pdhInvalidSqldb = 0xC0000BDE + pdhNoCounters = 0xC0000BDF + pdhSQLAllocFailed = 0xC0000BE0 + pdhSQLAllocconFailed = 0xC0000BE1 + pdhSQLExecDirectFailed = 0xC0000BE2 + pdhSQLFetchFailed = 0xC0000BE3 + pdhSQLRowcountFailed = 0xC0000BE4 + pdhSQLMoreResultsFailed = 0xC0000BE5 + pdhSQLConnectFailed = 0xC0000BE6 + pdhSQLBindFailed = 0xC0000BE7 + pdhCannotConnectWmiServer = 0xC0000BE8 + pdhPlaCollectionAlreadyRunning = 0xC0000BE9 + pdhPlaErrorScheduleOverlap = 0xC0000BEA + pdhPlaCollectionNotFound = 0xC0000BEB + pdhPlaErrorScheduleElapsed = 0xC0000BEC + pdhPlaErrorNostart = 0xC0000BED + pdhPlaErrorAlreadyExists = 0xC0000BEE + pdhPlaErrorTypeMismatch = 0xC0000BEF + pdhPlaErrorFilepath = 0xC0000BF0 + pdhPlaServiceError = 0xC0000BF1 + pdhPlaValidationError = 0xC0000BF2 + pdhPlaValidationWarning = 0x80000BF3 + pdhPlaErrorNameTooLong = 0xC0000BF4 + pdhInvalidSQLLogFormat = 0xC0000BF5 + pdhCounterAlreadyInQuery = 0xC0000BF6 + pdhBinaryLogCorrupt = 0xC0000BF7 + pdhLogSampleTooSmall = 0xC0000BF8 + pdhOsLaterVersion = 0xC0000BF9 + pdhOsEarlierVersion = 0xC0000BFA + pdhIncorrectAppendTime = 0xC0000BFB + pdhUnmatchedAppendCounter = 0xC0000BFC + pdhSQLAlterDetailFailed = 0xC0000BFD + pdhQueryPerfDataTimeout = 0xC0000BFE ) -var PDHErrors = map[uint32]string{ - PdhCstatusValidData: "PDH_CSTATUS_VALID_DATA", - PdhCstatusNewData: "PDH_CSTATUS_NEW_DATA", - PdhCstatusNoMachine: "PDH_CSTATUS_NO_MACHINE", - PdhCstatusNoInstance: "PDH_CSTATUS_NO_INSTANCE", - PdhMoreData: "PDH_MORE_DATA", - PdhCstatusItemNotValidated: "PDH_CSTATUS_ITEM_NOT_VALIDATED", - PdhRetry: "PDH_RETRY", - PdhNoData: "PDH_NO_DATA", - PdhCalcNegativeDenominator: "PDH_CALC_NEGATIVE_DENOMINATOR", - PdhCalcNegativeTimebase: "PDH_CALC_NEGATIVE_TIMEBASE", - PdhCalcNegativeValue: "PDH_CALC_NEGATIVE_VALUE", - PdhDialogCancelled: "PDH_DIALOG_CANCELLED", - PdhEndOfLogFile: "PDH_END_OF_LOG_FILE", - PdhAsyncQueryTimeout: "PDH_ASYNC_QUERY_TIMEOUT", - PdhCannotSetDefaultRealtimeDatasource: "PDH_CANNOT_SET_DEFAULT_REALTIME_DATASOURCE", - PdhCstatusNoObject: "PDH_CSTATUS_NO_OBJECT", - PdhCstatusNoCounter: "PDH_CSTATUS_NO_COUNTER", - PdhCstatusInvalidData: "PDH_CSTATUS_INVALID_DATA", - PdhMemoryAllocationFailure: "PDH_MEMORY_ALLOCATION_FAILURE", - PdhInvalidHandle: "PDH_INVALID_HANDLE", - PdhInvalidArgument: "PDH_INVALID_ARGUMENT", - PdhFunctionNotFound: "PDH_FUNCTION_NOT_FOUND", - PdhCstatusNoCountername: "PDH_CSTATUS_NO_COUNTERNAME", - PdhCstatusBadCountername: "PDH_CSTATUS_BAD_COUNTERNAME", - PdhInvalidBuffer: "PDH_INVALID_BUFFER", - PdhInsufficientBuffer: "PDH_INSUFFICIENT_BUFFER", - PdhCannotConnectMachine: "PDH_CANNOT_CONNECT_MACHINE", - PdhInvalidPath: "PDH_INVALID_PATH", - PdhInvalidInstance: "PDH_INVALID_INSTANCE", - PdhInvalidData: "PDH_INVALID_DATA", - PdhNoDialogData: "PDH_NO_DIALOG_DATA", - PdhCannotReadNameStrings: "PDH_CANNOT_READ_NAME_STRINGS", - PdhLogFileCreateError: "PDH_LOG_FILE_CREATE_ERROR", - PdhLogFileOpenError: "PDH_LOG_FILE_OPEN_ERROR", - PdhLogTypeNotFound: "PDH_LOG_TYPE_NOT_FOUND", - PdhNoMoreData: "PDH_NO_MORE_DATA", - PdhEntryNotInLogFile: "PDH_ENTRY_NOT_IN_LOG_FILE", - PdhDataSourceIsLogFile: "PDH_DATA_SOURCE_IS_LOG_FILE", - PdhDataSourceIsRealTime: "PDH_DATA_SOURCE_IS_REAL_TIME", - PdhUnableReadLogHeader: "PDH_UNABLE_READ_LOG_HEADER", - PdhFileNotFound: "PDH_FILE_NOT_FOUND", - PdhFileAlreadyExists: "PDH_FILE_ALREADY_EXISTS", - PdhNotImplemented: "PDH_NOT_IMPLEMENTED", - PdhStringNotFound: "PDH_STRING_NOT_FOUND", - PdhUnableMapNameFiles: "PDH_UNABLE_MAP_NAME_FILES", - PdhUnknownLogFormat: "PDH_UNKNOWN_LOG_FORMAT", - PdhUnknownLogsvcCommand: "PDH_UNKNOWN_LOGSVC_COMMAND", - PdhLogsvcQueryNotFound: "PDH_LOGSVC_QUERY_NOT_FOUND", - PdhLogsvcNotOpened: "PDH_LOGSVC_NOT_OPENED", - PdhWbemError: "PDH_WBEM_ERROR", - PdhAccessDenied: "PDH_ACCESS_DENIED", - PdhLogFileTooSmall: "PDH_LOG_FILE_TOO_SMALL", - PdhInvalidDatasource: "PDH_INVALID_DATASOURCE", - PdhInvalidSqldb: "PDH_INVALID_SQLDB", - PdhNoCounters: "PDH_NO_COUNTERS", - PdhSQLAllocFailed: "PDH_SQL_ALLOC_FAILED", - PdhSQLAllocconFailed: "PDH_SQL_ALLOCCON_FAILED", - PdhSQLExecDirectFailed: "PDH_SQL_EXEC_DIRECT_FAILED", - PdhSQLFetchFailed: "PDH_SQL_FETCH_FAILED", - PdhSQLRowcountFailed: "PDH_SQL_ROWCOUNT_FAILED", - PdhSQLMoreResultsFailed: "PDH_SQL_MORE_RESULTS_FAILED", - PdhSQLConnectFailed: "PDH_SQL_CONNECT_FAILED", - PdhSQLBindFailed: "PDH_SQL_BIND_FAILED", - PdhCannotConnectWmiServer: "PDH_CANNOT_CONNECT_WMI_SERVER", - PdhPlaCollectionAlreadyRunning: "PDH_PLA_COLLECTION_ALREADY_RUNNING", - PdhPlaErrorScheduleOverlap: "PDH_PLA_ERROR_SCHEDULE_OVERLAP", - PdhPlaCollectionNotFound: "PDH_PLA_COLLECTION_NOT_FOUND", - PdhPlaErrorScheduleElapsed: "PDH_PLA_ERROR_SCHEDULE_ELAPSED", - PdhPlaErrorNostart: "PDH_PLA_ERROR_NOSTART", - PdhPlaErrorAlreadyExists: "PDH_PLA_ERROR_ALREADY_EXISTS", - PdhPlaErrorTypeMismatch: "PDH_PLA_ERROR_TYPE_MISMATCH", - PdhPlaErrorFilepath: "PDH_PLA_ERROR_FILEPATH", - PdhPlaServiceError: "PDH_PLA_SERVICE_ERROR", - PdhPlaValidationError: "PDH_PLA_VALIDATION_ERROR", - PdhPlaValidationWarning: "PDH_PLA_VALIDATION_WARNING", - PdhPlaErrorNameTooLong: "PDH_PLA_ERROR_NAME_TOO_LONG", - PdhInvalidSQLLogFormat: "PDH_INVALID_SQL_LOG_FORMAT", - PdhCounterAlreadyInQuery: "PDH_COUNTER_ALREADY_IN_QUERY", - PdhBinaryLogCorrupt: "PDH_BINARY_LOG_CORRUPT", - PdhLogSampleTooSmall: "PDH_LOG_SAMPLE_TOO_SMALL", - PdhOsLaterVersion: "PDH_OS_LATER_VERSION", - PdhOsEarlierVersion: "PDH_OS_EARLIER_VERSION", - PdhIncorrectAppendTime: "PDH_INCORRECT_APPEND_TIME", - PdhUnmatchedAppendCounter: "PDH_UNMATCHED_APPEND_COUNTER", - PdhSQLAlterDetailFailed: "PDH_SQL_ALTER_DETAIL_FAILED", - PdhQueryPerfDataTimeout: "PDH_QUERY_PERF_DATA_TIMEOUT", +var pdhErrors = map[uint32]string{ + pdhCstatusValidData: "PDH_CSTATUS_VALID_DATA", + pdhCstatusNewData: "PDH_CSTATUS_NEW_DATA", + pdhCstatusNoMachine: "PDH_CSTATUS_NO_MACHINE", + pdhCstatusNoInstance: "PDH_CSTATUS_NO_INSTANCE", + pdhMoreData: "PDH_MORE_DATA", + pdhCstatusItemNotValidated: "PDH_CSTATUS_ITEM_NOT_VALIDATED", + pdhRetry: "PDH_RETRY", + pdhNoData: "PDH_NO_DATA", + pdhCalcNegativeDenominator: "PDH_CALC_NEGATIVE_DENOMINATOR", + pdhCalcNegativeTimebase: "PDH_CALC_NEGATIVE_TIMEBASE", + pdhCalcNegativeValue: "PDH_CALC_NEGATIVE_VALUE", + pdhDialogCancelled: "PDH_DIALOG_CANCELLED", + pdhEndOfLogFile: "PDH_END_OF_LOG_FILE", + pdhAsyncQueryTimeout: "PDH_ASYNC_QUERY_TIMEOUT", + pdhCannotSetDefaultRealtimeDatasource: "PDH_CANNOT_SET_DEFAULT_REALTIME_DATASOURCE", + pdhCstatusNoObject: "PDH_CSTATUS_NO_OBJECT", + pdhCstatusNoCounter: "PDH_CSTATUS_NO_COUNTER", + pdhCstatusInvalidData: "PDH_CSTATUS_INVALID_DATA", + pdhMemoryAllocationFailure: "PDH_MEMORY_ALLOCATION_FAILURE", + pdhInvalidHandle: "PDH_INVALID_HANDLE", + pdhInvalidArgument: "PDH_INVALID_ARGUMENT", + pdhFunctionNotFound: "PDH_FUNCTION_NOT_FOUND", + pdhCstatusNoCountername: "PDH_CSTATUS_NO_COUNTERNAME", + pdhCstatusBadCountername: "PDH_CSTATUS_BAD_COUNTERNAME", + pdhInvalidBuffer: "PDH_INVALID_BUFFER", + pdhInsufficientBuffer: "PDH_INSUFFICIENT_BUFFER", + pdhCannotConnectMachine: "PDH_CANNOT_CONNECT_MACHINE", + pdhInvalidPath: "PDH_INVALID_PATH", + pdhInvalidInstance: "PDH_INVALID_INSTANCE", + pdhInvalidData: "PDH_INVALID_DATA", + pdhNoDialogData: "PDH_NO_DIALOG_DATA", + pdhCannotReadNameStrings: "PDH_CANNOT_READ_NAME_STRINGS", + pdhLogFileCreateError: "PDH_LOG_FILE_CREATE_ERROR", + pdhLogFileOpenError: "PDH_LOG_FILE_OPEN_ERROR", + pdhLogTypeNotFound: "PDH_LOG_TYPE_NOT_FOUND", + pdhNoMoreData: "PDH_NO_MORE_DATA", + pdhEntryNotInLogFile: "PDH_ENTRY_NOT_IN_LOG_FILE", + pdhDataSourceIsLogFile: "PDH_DATA_SOURCE_IS_LOG_FILE", + pdhDataSourceIsRealTime: "PDH_DATA_SOURCE_IS_REAL_TIME", + pdhUnableReadLogHeader: "PDH_UNABLE_READ_LOG_HEADER", + pdhFileNotFound: "PDH_FILE_NOT_FOUND", + pdhFileAlreadyExists: "PDH_FILE_ALREADY_EXISTS", + pdhNotImplemented: "PDH_NOT_IMPLEMENTED", + pdhStringNotFound: "PDH_STRING_NOT_FOUND", + pdhUnableMapNameFiles: "PDH_UNABLE_MAP_NAME_FILES", + pdhUnknownLogFormat: "PDH_UNKNOWN_LOG_FORMAT", + pdhUnknownLogsvcCommand: "PDH_UNKNOWN_LOGSVC_COMMAND", + pdhLogsvcQueryNotFound: "PDH_LOGSVC_QUERY_NOT_FOUND", + pdhLogsvcNotOpened: "PDH_LOGSVC_NOT_OPENED", + pdhWbemError: "PDH_WBEM_ERROR", + pdhAccessDenied: "PDH_ACCESS_DENIED", + pdhLogFileTooSmall: "PDH_LOG_FILE_TOO_SMALL", + pdhInvalidDatasource: "PDH_INVALID_DATASOURCE", + pdhInvalidSqldb: "PDH_INVALID_SQLDB", + pdhNoCounters: "PDH_NO_COUNTERS", + pdhSQLAllocFailed: "PDH_SQL_ALLOC_FAILED", + pdhSQLAllocconFailed: "PDH_SQL_ALLOCCON_FAILED", + pdhSQLExecDirectFailed: "PDH_SQL_EXEC_DIRECT_FAILED", + pdhSQLFetchFailed: "PDH_SQL_FETCH_FAILED", + pdhSQLRowcountFailed: "PDH_SQL_ROWCOUNT_FAILED", + pdhSQLMoreResultsFailed: "PDH_SQL_MORE_RESULTS_FAILED", + pdhSQLConnectFailed: "PDH_SQL_CONNECT_FAILED", + pdhSQLBindFailed: "PDH_SQL_BIND_FAILED", + pdhCannotConnectWmiServer: "PDH_CANNOT_CONNECT_WMI_SERVER", + pdhPlaCollectionAlreadyRunning: "PDH_PLA_COLLECTION_ALREADY_RUNNING", + pdhPlaErrorScheduleOverlap: "PDH_PLA_ERROR_SCHEDULE_OVERLAP", + pdhPlaCollectionNotFound: "PDH_PLA_COLLECTION_NOT_FOUND", + pdhPlaErrorScheduleElapsed: "PDH_PLA_ERROR_SCHEDULE_ELAPSED", + pdhPlaErrorNostart: "PDH_PLA_ERROR_NOSTART", + pdhPlaErrorAlreadyExists: "PDH_PLA_ERROR_ALREADY_EXISTS", + pdhPlaErrorTypeMismatch: "PDH_PLA_ERROR_TYPE_MISMATCH", + pdhPlaErrorFilepath: "PDH_PLA_ERROR_FILEPATH", + pdhPlaServiceError: "PDH_PLA_SERVICE_ERROR", + pdhPlaValidationError: "PDH_PLA_VALIDATION_ERROR", + pdhPlaValidationWarning: "PDH_PLA_VALIDATION_WARNING", + pdhPlaErrorNameTooLong: "PDH_PLA_ERROR_NAME_TOO_LONG", + pdhInvalidSQLLogFormat: "PDH_INVALID_SQL_LOG_FORMAT", + pdhCounterAlreadyInQuery: "PDH_COUNTER_ALREADY_IN_QUERY", + pdhBinaryLogCorrupt: "PDH_BINARY_LOG_CORRUPT", + pdhLogSampleTooSmall: "PDH_LOG_SAMPLE_TOO_SMALL", + pdhOsLaterVersion: "PDH_OS_LATER_VERSION", + pdhOsEarlierVersion: "PDH_OS_EARLIER_VERSION", + pdhIncorrectAppendTime: "PDH_INCORRECT_APPEND_TIME", + pdhUnmatchedAppendCounter: "PDH_UNMATCHED_APPEND_COUNTER", + pdhSQLAlterDetailFailed: "PDH_SQL_ALTER_DETAIL_FAILED", + pdhQueryPerfDataTimeout: "PDH_QUERY_PERF_DATA_TIMEOUT", } // Formatting options for GetFormattedCounterValue(). const ( - PdhFmtRaw = 0x00000010 - PdhFmtAnsi = 0x00000020 - PdhFmtUnicode = 0x00000040 - PdhFmtLong = 0x00000100 // Return data as a long int. - PdhFmtDouble = 0x00000200 // Return data as a double precision floating point real. - PdhFmtLarge = 0x00000400 // Return data as a 64 bit integer. - PdhFmtNoscale = 0x00001000 // can be OR-ed: Do not apply the counter's default scaling factor. - PdhFmt1000 = 0x00002000 // can be OR-ed: multiply the actual value by 1,000. - PdhFmtNodata = 0x00004000 // can be OR-ed: unknown what this is for, MSDN says nothing. - PdhFmtNocap100 = 0x00008000 // can be OR-ed: do not cap values > 100. - PerfDetailCostly = 0x00010000 - PerfDetailStandard = 0x0000FFFF + pdhFmtRaw = 0x00000010 + pdhFmtAnsi = 0x00000020 + pdhFmtUnicode = 0x00000040 + pdhFmtLong = 0x00000100 // Return data as a long int. + pdhFmtDouble = 0x00000200 // Return data as a double precision floating point real. + pdhFmtLarge = 0x00000400 // Return data as a 64 bit integer. + pdhFmtNoscale = 0x00001000 // can be OR-ed: Do not apply the counter's default scaling factor. + pdhFmt1000 = 0x00002000 // can be OR-ed: multiply the actual value by 1,000. + pdhFmtNodata = 0x00004000 // can be OR-ed: unknown what this is for, MSDN says nothing. + pdhFmtNocap100 = 0x00008000 // can be OR-ed: do not cap values > 100. + perfDetailCostly = 0x00010000 + perfDetailStandard = 0x0000FFFF ) type ( - pdhQueryHandle HANDLE // query handle - pdhCounterHandle HANDLE // counter handle + pdhQueryHandle handle // query handle + pdhCounterHandle handle // counter handle ) var ( @@ -260,19 +259,18 @@ var ( libPdhDll *syscall.DLL // Functions - pdhAddCounterW *syscall.Proc - pdhAddEnglishCounterW *syscall.Proc - pdhCloseQuery *syscall.Proc - pdhCollectQueryData *syscall.Proc - pdhCollectQueryDataWithTime *syscall.Proc - pdhGetFormattedCounterValue *syscall.Proc - pdhGetFormattedCounterArrayW *syscall.Proc - pdhOpenQuery *syscall.Proc - pdhValidatePathW *syscall.Proc - pdhExpandWildCardPathW *syscall.Proc - pdhGetCounterInfoW *syscall.Proc - pdhGetRawCounterValue *syscall.Proc - pdhGetRawCounterArrayW *syscall.Proc + pdhAddCounterWProc *syscall.Proc + pdhAddEnglishCounterWProc *syscall.Proc + pdhCloseQueryProc *syscall.Proc + pdhCollectQueryDataProc *syscall.Proc + pdhCollectQueryDataWithTimeProc *syscall.Proc + pdhGetFormattedCounterValueProc *syscall.Proc + pdhGetFormattedCounterArrayWProc *syscall.Proc + pdhOpenQueryProc *syscall.Proc + pdhExpandWildCardPathWProc *syscall.Proc + pdhGetCounterInfoWProc *syscall.Proc + pdhGetRawCounterValueProc *syscall.Proc + pdhGetRawCounterArrayWProc *syscall.Proc ) func init() { @@ -280,26 +278,25 @@ func init() { libPdhDll = syscall.MustLoadDLL("pdh.dll") // Functions - pdhAddCounterW = libPdhDll.MustFindProc("PdhAddCounterW") - pdhAddEnglishCounterW, _ = libPdhDll.FindProc("PdhAddEnglishCounterW") // XXX: only supported on versions > Vista. - pdhCloseQuery = libPdhDll.MustFindProc("PdhCloseQuery") - pdhCollectQueryData = libPdhDll.MustFindProc("PdhCollectQueryData") - pdhCollectQueryDataWithTime, _ = libPdhDll.FindProc("PdhCollectQueryDataWithTime") - pdhGetFormattedCounterValue = libPdhDll.MustFindProc("PdhGetFormattedCounterValue") - pdhGetFormattedCounterArrayW = libPdhDll.MustFindProc("PdhGetFormattedCounterArrayW") - pdhOpenQuery = libPdhDll.MustFindProc("PdhOpenQuery") - pdhValidatePathW = libPdhDll.MustFindProc("PdhValidatePathW") - pdhExpandWildCardPathW = libPdhDll.MustFindProc("PdhExpandWildCardPathW") - pdhGetCounterInfoW = libPdhDll.MustFindProc("PdhGetCounterInfoW") - pdhGetRawCounterValue = libPdhDll.MustFindProc("PdhGetRawCounterValue") - pdhGetRawCounterArrayW = libPdhDll.MustFindProc("PdhGetRawCounterArrayW") + pdhAddCounterWProc = libPdhDll.MustFindProc("PdhAddCounterW") + pdhAddEnglishCounterWProc, _ = libPdhDll.FindProc("PdhAddEnglishCounterW") // XXX: only supported on versions > Vista. + pdhCloseQueryProc = libPdhDll.MustFindProc("PdhCloseQuery") + pdhCollectQueryDataProc = libPdhDll.MustFindProc("PdhCollectQueryData") + pdhCollectQueryDataWithTimeProc, _ = libPdhDll.FindProc("PdhCollectQueryDataWithTime") + pdhGetFormattedCounterValueProc = libPdhDll.MustFindProc("PdhGetFormattedCounterValue") + pdhGetFormattedCounterArrayWProc = libPdhDll.MustFindProc("PdhGetFormattedCounterArrayW") + pdhOpenQueryProc = libPdhDll.MustFindProc("PdhOpenQuery") + pdhExpandWildCardPathWProc = libPdhDll.MustFindProc("PdhExpandWildCardPathW") + pdhGetCounterInfoWProc = libPdhDll.MustFindProc("PdhGetCounterInfoW") + pdhGetRawCounterValueProc = libPdhDll.MustFindProc("PdhGetRawCounterValue") + pdhGetRawCounterArrayWProc = libPdhDll.MustFindProc("PdhGetRawCounterArrayW") } -// PdhAddCounter adds the specified counter to the query. This is the internationalized version. Preferably, use the -// function PdhAddEnglishCounter instead. hQuery is the query handle, which has been fetched by PdhOpenQuery. +// pdhAddCounter adds the specified counter to the query. This is the internationalized version. Preferably, use the +// function pdhAddEnglishCounter instead. hQuery is the query handle, which has been fetched by pdhOpenQuery. // szFullCounterPath is a full, internationalized counter path (this will differ per Windows language version). // dwUserData is a 'user-defined value', which becomes part of the counter information. To retrieve this value -// later, call PdhGetCounterInfo() and access dwQueryUserData of the pdhCounterInfo structure. +// later, call pdhGetCounterInfo() and access dwQueryUserData of the pdhCounterInfo structure. // // Examples of szFullCounterPath (in an English version of Windows): // @@ -333,9 +330,9 @@ func init() { // The typeperf command may also be pretty easy. To find all performance counters, simply execute: // // typeperf -qx -func PdhAddCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData uintptr, phCounter *pdhCounterHandle) uint32 { +func pdhAddCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData uintptr, phCounter *pdhCounterHandle) uint32 { ptxt, _ := syscall.UTF16PtrFromString(szFullCounterPath) - ret, _, _ := pdhAddCounterW.Call( + ret, _, _ := pdhAddCounterWProc.Call( uintptr(hQuery), uintptr(unsafe.Pointer(ptxt)), //nolint:gosec // G103: Valid use of unsafe call to pass ptxt dwUserData, @@ -344,21 +341,21 @@ func PdhAddCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData u return uint32(ret) } -// PdhAddEnglishCounterSupported returns true if PdhAddEnglishCounterW Win API function was found in pdh.dll. +// pdhAddEnglishCounterSupported returns true if PdhAddEnglishCounterW Win API function was found in pdh.dll. // PdhAddEnglishCounterW function is not supported on pre-Windows Vista systems -func PdhAddEnglishCounterSupported() bool { - return pdhAddEnglishCounterW != nil +func pdhAddEnglishCounterSupported() bool { + return pdhAddEnglishCounterWProc != nil } -// PdhAddEnglishCounter adds the specified language-neutral counter to the query. See the PdhAddCounter function. This function only exists on +// pdhAddEnglishCounter adds the specified language-neutral counter to the query. See the pdhAddCounter function. This function only exists on // Windows versions higher than Vista. -func PdhAddEnglishCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData uintptr, phCounter *pdhCounterHandle) uint32 { - if pdhAddEnglishCounterW == nil { - return ErrorInvalidFunction +func pdhAddEnglishCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUserData uintptr, phCounter *pdhCounterHandle) uint32 { + if pdhAddEnglishCounterWProc == nil { + return errorInvalidFunction } ptxt, _ := syscall.UTF16PtrFromString(szFullCounterPath) - ret, _, _ := pdhAddEnglishCounterW.Call( + ret, _, _ := pdhAddEnglishCounterWProc.Call( uintptr(hQuery), uintptr(unsafe.Pointer(ptxt)), //nolint:gosec // G103: Valid use of unsafe call to pass ptxt dwUserData, @@ -367,85 +364,85 @@ func PdhAddEnglishCounter(hQuery pdhQueryHandle, szFullCounterPath string, dwUse return uint32(ret) } -// PdhCloseQuery closes all counters contained in the specified query, closes all handles related to the query, +// pdhCloseQuery closes all counters contained in the specified query, closes all handles related to the query, // and frees all memory associated with the query. -func PdhCloseQuery(hQuery pdhQueryHandle) uint32 { - ret, _, _ := pdhCloseQuery.Call(uintptr(hQuery)) +func pdhCloseQuery(hQuery pdhQueryHandle) uint32 { + ret, _, _ := pdhCloseQueryProc.Call(uintptr(hQuery)) return uint32(ret) } -// PdhCollectQueryData 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: // // var handle win.PDH_HQUERY // var counterHandle win.PDH_HCOUNTER -// ret := win.PdhOpenQuery(0, 0, &handle) -// ret = win.PdhAddEnglishCounter(handle, "\\Processor(_Total)\\% Idle Time", 0, &counterHandle) +// ret := win.pdhOpenQuery(0, 0, &handle) +// ret = win.pdhAddEnglishCounter(handle, "\\Processor(_Total)\\% Idle Time", 0, &counterHandle) // var derp win.PDH_FMT_COUNTERVALUE_DOUBLE // -// ret = win.PdhCollectQueryData(handle) +// ret = win.pdhCollectQueryData(handle) // fmt.Printf("Collect return code is %x\n", ret) // return code will be PDH_CSTATUS_INVALID_DATA -// ret = win.PdhGetFormattedCounterValueDouble(counterHandle, 0, &derp) +// ret = win.pdhGetFormattedCounterValueDouble(counterHandle, 0, &derp) // -// ret = win.PdhCollectQueryData(handle) +// ret = win.pdhCollectQueryData(handle) // fmt.Printf("Collect return code is %x\n", ret) // return code will be ERROR_SUCCESS -// ret = win.PdhGetFormattedCounterValueDouble(counterHandle, 0, &derp) +// ret = win.pdhGetFormattedCounterValueDouble(counterHandle, 0, &derp) // -// The PdhCollectQueryData will return an error in the first call because it needs two values for +// The pdhCollectQueryData will return an error in the first call because it needs two values for // displaying the correct data for the processor idle time. The second call will have a 0 return code. -func PdhCollectQueryData(hQuery pdhQueryHandle) uint32 { - ret, _, _ := pdhCollectQueryData.Call(uintptr(hQuery)) +func pdhCollectQueryData(hQuery pdhQueryHandle) uint32 { + ret, _, _ := pdhCollectQueryDataProc.Call(uintptr(hQuery)) return uint32(ret) } -// PdhCollectQueryDataWithTime queries data from perfmon, retrieving the device/windows timestamp from the node it was collected on. +// pdhCollectQueryDataWithTime queries data from perfmon, retrieving the device/windows timestamp from the node it was collected on. // Converts the filetime structure to a GO time class and returns the native time. -func PdhCollectQueryDataWithTime(hQuery pdhQueryHandle) (uint32, time.Time) { +func pdhCollectQueryDataWithTime(hQuery pdhQueryHandle) (uint32, time.Time) { var localFileTime fileTime //nolint:gosec // G103: Valid use of unsafe call to pass localFileTime - ret, _, _ := pdhCollectQueryDataWithTime.Call(uintptr(hQuery), uintptr(unsafe.Pointer(&localFileTime))) + ret, _, _ := pdhCollectQueryDataWithTimeProc.Call(uintptr(hQuery), uintptr(unsafe.Pointer(&localFileTime))) - if ret == ErrorSuccess { + if ret == errorSuccess { var utcFileTime fileTime ret, _, _ := kernelLocalFileTimeToFileTime.Call( uintptr(unsafe.Pointer(&localFileTime)), //nolint:gosec // G103: Valid use of unsafe call to pass localFileTime uintptr(unsafe.Pointer(&utcFileTime))) //nolint:gosec // G103: Valid use of unsafe call to pass utcFileTime if ret == 0 { - return uint32(ErrorFailure), time.Now() + return uint32(errorFailure), time.Now() } // First convert 100-ns intervals to microseconds, then adjust for the // epoch difference var totalMicroSeconds int64 totalMicroSeconds = ((int64(utcFileTime.dwHighDateTime) << 32) | int64(utcFileTime.dwLowDateTime)) / 10 - totalMicroSeconds -= EpochDifferenceMicros + totalMicroSeconds -= epochDifferenceMicros retTime := time.Unix(0, totalMicroSeconds*1000) - return uint32(ErrorSuccess), retTime + return uint32(errorSuccess), retTime } return uint32(ret), time.Now() } -// PdhGetFormattedCounterValueDouble formats the given hCounter using a 'double'. The result is set into the specialized union struct pValue. +// pdhGetFormattedCounterValueDouble formats the given hCounter using a 'double'. The result is set into the specialized union struct pValue. // This function does not directly translate to a Windows counterpart due to union specialization tricks. -func PdhGetFormattedCounterValueDouble(hCounter pdhCounterHandle, lpdwType *uint32, pValue *pdhFmtCountervalueDouble) uint32 { - ret, _, _ := pdhGetFormattedCounterValue.Call( +func pdhGetFormattedCounterValueDouble(hCounter pdhCounterHandle, lpdwType *uint32, pValue *pdhFmtCountervalueDouble) uint32 { + ret, _, _ := pdhGetFormattedCounterValueProc.Call( uintptr(hCounter), - uintptr(PdhFmtDouble|PdhFmtNocap100), + uintptr(pdhFmtDouble|pdhFmtNocap100), uintptr(unsafe.Pointer(lpdwType)), //nolint:gosec // G103: Valid use of unsafe call to pass lpdwType uintptr(unsafe.Pointer(pValue))) //nolint:gosec // G103: Valid use of unsafe call to pass pValue return uint32(ret) } -// PdhGetFormattedCounterArrayDouble returns an array of formatted counter values. Use this function when you want to format the counter values of a +// pdhGetFormattedCounterArrayDouble returns an array of formatted counter values. Use this function when you want to format the counter values of a // counter that contains a wildcard character for the instance name. The itemBuffer must a slice of type pdhFmtCountervalueItemDouble. // An example of how this function can be used: // @@ -460,15 +457,15 @@ func PdhGetFormattedCounterValueDouble(hCounter pdhCounterHandle, lpdwType *uint // // for { // // collect -// ret := win.PdhCollectQueryData(queryHandle) +// ret := win.pdhCollectQueryData(queryHandle) // if ret == win.ERROR_SUCCESS { -// ret = win.PdhGetFormattedCounterArrayDouble(counterHandle, &bufSize, &bufCount, &emptyBuf[0]) // uses null ptr here according to MSDN. +// ret = win.pdhGetFormattedCounterArrayDouble(counterHandle, &bufSize, &bufCount, &emptyBuf[0]) // uses null ptr here according to MSDN. // if ret == win.PDH_MORE_DATA { // filledBuf := make([]win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE, bufCount*size) -// ret = win.PdhGetFormattedCounterArrayDouble(counterHandle, &bufSize, &bufCount, &filledBuf[0]) +// ret = win.pdhGetFormattedCounterArrayDouble(counterHandle, &bufSize, &bufCount, &filledBuf[0]) // for i := 0; i < int(bufCount); i++ { // c := filledBuf[i] -// var s string = win.UTF16PtrToString(c.SzName) +// var s string = win.utf16PtrToString(c.SzName) // fmt.Printf("Index %d -> %s, value %v\n", i, s, c.FmtValue.DoubleValue) // } // @@ -482,10 +479,10 @@ func PdhGetFormattedCounterValueDouble(hCounter pdhCounterHandle, lpdwType *uint // time.Sleep(2000 * time.Millisecond) // } // } -func PdhGetFormattedCounterArrayDouble(hCounter pdhCounterHandle, lpdwBufferSize, lpdwBufferCount *uint32, itemBuffer *byte) uint32 { - ret, _, _ := pdhGetFormattedCounterArrayW.Call( +func pdhGetFormattedCounterArrayDouble(hCounter pdhCounterHandle, lpdwBufferSize, lpdwBufferCount *uint32, itemBuffer *byte) uint32 { + ret, _, _ := pdhGetFormattedCounterArrayWProc.Call( uintptr(hCounter), - uintptr(PdhFmtDouble|PdhFmtNocap100), + uintptr(pdhFmtDouble|pdhFmtNocap100), uintptr(unsafe.Pointer(lpdwBufferSize)), //nolint:gosec // G103: Valid use of unsafe call to pass lpdwBufferSize uintptr(unsafe.Pointer(lpdwBufferCount)), //nolint:gosec // G103: Valid use of unsafe call to pass lpdwBufferCount uintptr(unsafe.Pointer(itemBuffer))) //nolint:gosec // G103: Valid use of unsafe call to pass itemBuffer @@ -493,15 +490,15 @@ func PdhGetFormattedCounterArrayDouble(hCounter pdhCounterHandle, lpdwBufferSize return uint32(ret) } -// PdhOpenQuery creates a new query that is used to manage the collection of performance data. +// pdhOpenQuery creates a new query that is used to manage the collection of performance data. // szDataSource is a null terminated string that specifies the name of the log file from which to // retrieve the performance data. If 0, performance data is collected from a real-time data source. // dwUserData is a user-defined value to associate with this query. To retrieve the user data later, -// call PdhGetCounterInfo and access dwQueryUserData of the pdhCounterInfo structure. phQuery is +// call pdhGetCounterInfo and access dwQueryUserData of the pdhCounterInfo structure. phQuery is // the handle to the query, and must be used in subsequent calls. This function returns a PDH_ -// constant error code, or ErrorSuccess if the call succeeded. -func PdhOpenQuery(szDataSource, dwUserData uintptr, phQuery *pdhQueryHandle) uint32 { - ret, _, _ := pdhOpenQuery.Call( +// constant error code, or errorSuccess if the call succeeded. +func pdhOpenQuery(szDataSource, dwUserData uintptr, phQuery *pdhQueryHandle) uint32 { + ret, _, _ := pdhOpenQueryProc.Call( szDataSource, dwUserData, uintptr(unsafe.Pointer(phQuery))) //nolint:gosec // G103: Valid use of unsafe call to pass phQuery @@ -509,7 +506,7 @@ func PdhOpenQuery(szDataSource, dwUserData uintptr, phQuery *pdhQueryHandle) uin return uint32(ret) } -// PdhExpandWildCardPath examines the specified computer or log file and returns those counter paths that match the given counter path +// 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 @@ -542,10 +539,10 @@ func PdhOpenQuery(szDataSource, dwUserData uintptr, phQuery *pdhQueryHandle) uin // If a wildcard character is specified in the counter name, all counters of the specified object are returned. // // Partial counter path string matches (for example, "pro*") are supported. -func PdhExpandWildCardPath(szWildCardPath string, mszExpandedPathList *uint16, pcchPathListLength *uint32) uint32 { +func pdhExpandWildCardPath(szWildCardPath string, mszExpandedPathList *uint16, pcchPathListLength *uint32) uint32 { ptxt, _ := syscall.UTF16PtrFromString(szWildCardPath) flags := uint32(0) // expand instances and counters - ret, _, _ := pdhExpandWildCardPathW.Call( + ret, _, _ := pdhExpandWildCardPathWProc.Call( 0, // search counters on local computer uintptr(unsafe.Pointer(ptxt)), //nolint:gosec // G103: Valid use of unsafe call to pass ptxt uintptr(unsafe.Pointer(mszExpandedPathList)), //nolint:gosec // G103: Valid use of unsafe call to pass mszExpandedPathList @@ -555,27 +552,19 @@ func PdhExpandWildCardPath(szWildCardPath string, mszExpandedPathList *uint16, p return uint32(ret) } -// PdhValidatePath validates a path. Will return ErrorSuccess when ok, or PdhCstatusBadCountername when the path is erroneous. -func PdhValidatePath(path string) uint32 { - ptxt, _ := syscall.UTF16PtrFromString(path) - ret, _, _ := pdhValidatePathW.Call(uintptr(unsafe.Pointer(ptxt))) //nolint:gosec // G103: Valid use of unsafe call to pass ptxt - - return uint32(ret) -} - -func PdhFormatError(msgID uint32) string { +func pdhFormatError(msgID uint32) string { var flags uint32 = windows.FORMAT_MESSAGE_FROM_HMODULE | windows.FORMAT_MESSAGE_ARGUMENT_ARRAY | windows.FORMAT_MESSAGE_IGNORE_INSERTS buf := make([]uint16, 300) _, err := windows.FormatMessage(flags, uintptr(libPdhDll.Handle), msgID, 0, buf, nil) if err == nil { - return UTF16PtrToString(&buf[0]) + return utf16PtrToString(&buf[0]) } return fmt.Sprintf("(pdhErr=%d) %s", msgID, err.Error()) } -// PdhGetCounterInfo 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. +// 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. @@ -590,8 +579,8 @@ func PdhFormatError(msgID uint32) string { // Caller-allocated buffer that receives a pdhCounterInfo 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 pdhCounterHandle, bRetrieveExplainText int, pdwBufferSize *uint32, lpBuffer *byte) uint32 { - ret, _, _ := pdhGetCounterInfoW.Call( +func pdhGetCounterInfo(hCounter pdhCounterHandle, bRetrieveExplainText int, pdwBufferSize *uint32, lpBuffer *byte) uint32 { + ret, _, _ := pdhGetCounterInfoWProc.Call( uintptr(hCounter), uintptr(bRetrieveExplainText), uintptr(unsafe.Pointer(pdwBufferSize)), //nolint:gosec // G103: Valid use of unsafe call to pass pdwBufferSize @@ -600,12 +589,12 @@ func PdhGetCounterInfo(hCounter pdhCounterHandle, bRetrieveExplainText int, pdwB return uint32(ret) } -// PdhGetRawCounterValue returns the current raw value of the counter. -// If the specified counter instance does not exist, this function will return ErrorSuccess +// pdhGetRawCounterValue returns the current raw value of the counter. +// If the specified counter instance does not exist, this function will return errorSuccess // and the CStatus member of the pdhRawCounter structure will contain PdhCstatusNoInstance. // // hCounter [in] -// Handle of the counter from which to retrieve the current raw value. The PdhAddCounter function returns this handle. +// Handle of the counter from which to retrieve the current raw value. The pdhAddCounter function returns this handle. // // lpdwType [out] // Receives the counter type. For a list of counter types, see the Counter Types section of the Windows Server 2003 Deployment Kit. @@ -613,8 +602,8 @@ func PdhGetCounterInfo(hCounter pdhCounterHandle, bRetrieveExplainText int, pdwB // // pValue [out] // A pdhRawCounter structure that receives the counter value. -func PdhGetRawCounterValue(hCounter pdhCounterHandle, lpdwType *uint32, pValue *pdhRawCounter) uint32 { - ret, _, _ := pdhGetRawCounterValue.Call( +func pdhGetRawCounterValue(hCounter pdhCounterHandle, lpdwType *uint32, pValue *pdhRawCounter) uint32 { + ret, _, _ := pdhGetRawCounterValueProc.Call( uintptr(hCounter), uintptr(unsafe.Pointer(lpdwType)), //nolint:gosec // G103: Valid use of unsafe call to pass lpdwType uintptr(unsafe.Pointer(pValue))) //nolint:gosec // G103: Valid use of unsafe call to pass pValue @@ -622,10 +611,10 @@ func PdhGetRawCounterValue(hCounter pdhCounterHandle, lpdwType *uint32, pValue * return uint32(ret) } -// PdhGetRawCounterArray 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. +// Handle of the counter for whose current raw instance values you want to retrieve. The pdhAddCounter function returns this handle. // // lpdwBufferSize // Size of the ItemBuffer buffer, in bytes. If zero on input, the function returns PdhMoreData and sets this parameter to the required buffer size. @@ -638,8 +627,8 @@ func PdhGetRawCounterValue(hCounter pdhCounterHandle, lpdwType *uint32, pValue * // ItemBuffer // Caller-allocated buffer that receives the array of pdhRawCounterItem structures; the structures contain the raw instance counter values. // Set to NULL if lpdwBufferSize is zero. -func PdhGetRawCounterArray(hCounter pdhCounterHandle, lpdwBufferSize, lpdwBufferCount *uint32, itemBuffer *byte) uint32 { - ret, _, _ := pdhGetRawCounterArrayW.Call( +func pdhGetRawCounterArray(hCounter pdhCounterHandle, lpdwBufferSize, lpdwBufferCount *uint32, itemBuffer *byte) uint32 { + ret, _, _ := pdhGetRawCounterArrayWProc.Call( uintptr(hCounter), uintptr(unsafe.Pointer(lpdwBufferSize)), //nolint:gosec // G103: Valid use of unsafe call to pass lpdwBufferSize uintptr(unsafe.Pointer(lpdwBufferCount)), //nolint:gosec // G103: Valid use of unsafe call to pass lpdwBufferCount diff --git a/plugins/inputs/win_perf_counters/pdh_386.go b/plugins/inputs/win_perf_counters/pdh_386.go index feb085078..863044bf2 100644 --- a/plugins/inputs/win_perf_counters/pdh_386.go +++ b/plugins/inputs/win_perf_counters/pdh_386.go @@ -52,13 +52,6 @@ type pdhFmtCountervalueItemDouble struct { FmtValue pdhFmtCountervalueDouble } -// pdhFmtCountervalueItemLong is a union specialization for long values, used by PdhGetFormattedCounterArrayLong() -type PdhFmtCountervalueItemLong struct { - SzName *uint16 // pointer to a string - padding [4]byte //nolint:unused // Memory reservation - FmtValue pdhFmtCountervalueLong -} - // pdhCounterInfo structure contains information describing the properties of a counter. This information also includes the counter path. type pdhCounterInfo struct { //Size of the structure, including the appended strings, in bytes. @@ -78,9 +71,9 @@ type pdhCounterInfo struct { LScale int32 //Default scale factor as suggested by the counter's provider. LDefaultScale int32 - //The value passed in the dwUserData parameter when calling PdhAddCounter. + //The value passed in the dwUserData parameter when calling pdhAddCounter. DwUserData *uint32 - //The value passed in the dwUserData parameter when calling PdhOpenQuery. + //The value passed in the dwUserData parameter when calling pdhOpenQuery. DwQueryUserData *uint32 //Null-terminated string that specifies the full counter path. The string follows this structure in memory. SzFullPath *uint16 // pointer to a string diff --git a/plugins/inputs/win_perf_counters/pdh_amd64.go b/plugins/inputs/win_perf_counters/pdh_amd64.go index 7140fa2eb..0fbbb242f 100644 --- a/plugins/inputs/win_perf_counters/pdh_amd64.go +++ b/plugins/inputs/win_perf_counters/pdh_amd64.go @@ -38,7 +38,7 @@ type pdhFmtCountervalueDouble struct { DoubleValue float64 } -// pdhFmtCountervalueItemDouble is a union specialization for double values, used by PdhGetFormattedCounterArrayDouble +// pdhFmtCountervalueItemDouble is a union specialization for double values, used by pdhGetFormattedCounterArrayDouble type pdhFmtCountervalueItemDouble struct { SzName *uint16 FmtValue pdhFmtCountervalueDouble @@ -63,9 +63,9 @@ type pdhCounterInfo struct { LScale int32 // Default scale factor as suggested by the counter's provider. LDefaultScale int32 - // The value passed in the dwUserData parameter when calling PdhAddCounter. + // The value passed in the dwUserData parameter when calling pdhAddCounter. DwUserData *uint32 - // The value passed in the dwUserData parameter when calling PdhOpenQuery. + // The value passed in the dwUserData parameter when calling pdhOpenQuery. DwQueryUserData *uint32 // Null-terminated string that specifies the full counter path. The string follows this structure in memory. SzFullPath *uint16 // pointer to a string diff --git a/plugins/inputs/win_perf_counters/pdh_arm64.go b/plugins/inputs/win_perf_counters/pdh_arm64.go index 338d9975c..4fe671106 100644 --- a/plugins/inputs/win_perf_counters/pdh_arm64.go +++ b/plugins/inputs/win_perf_counters/pdh_arm64.go @@ -62,9 +62,9 @@ type pdhCounterInfo struct { LScale int32 //Default scale factor as suggested by the counter's provider. LDefaultScale int32 - //The value passed in the dwUserData parameter when calling PdhAddCounter. + //The value passed in the dwUserData parameter when calling pdhAddCounter. DwUserData *uint32 - //The value passed in the dwUserData parameter when calling PdhOpenQuery. + //The value passed in the dwUserData parameter when calling pdhOpenQuery. DwQueryUserData *uint32 //Null-terminated string that specifies the full counter path. The string follows this structure in memory. SzFullPath *uint16 // pointer to a string diff --git a/plugins/inputs/win_perf_counters/performance_query.go b/plugins/inputs/win_perf_counters/performance_query.go index 482d3660e..f0ea795b0 100644 --- a/plugins/inputs/win_perf_counters/performance_query.go +++ b/plugins/inputs/win_perf_counters/performance_query.go @@ -17,36 +17,36 @@ var errBufferLimitReached = errors.New("buffer limit reached") // counterValue is abstraction for pdhFmtCountervalueItemDouble type counterValue struct { - InstanceName string - Value interface{} + instanceName string + value interface{} } -// PerformanceQuery provides wrappers around Windows performance counters API for easy usage in GO +// 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 - AddCounterToQuery(counterPath string) (pdhCounterHandle, error) - AddEnglishCounterToQuery(counterPath string) (pdhCounterHandle, error) - GetCounterPath(counterHandle pdhCounterHandle) (string, error) - ExpandWildCardPath(counterPath string) ([]string, error) - GetFormattedCounterValueDouble(hCounter pdhCounterHandle) (float64, error) - GetRawCounterValue(hCounter pdhCounterHandle) (int64, error) - GetFormattedCounterArrayDouble(hCounter pdhCounterHandle) ([]counterValue, error) - GetRawCounterArray(hCounter pdhCounterHandle) ([]counterValue, error) - CollectData() error - CollectDataWithTime() (time.Time, error) - IsVistaOrNewer() bool +type performanceQuery interface { + open() error + close() error + addCounterToQuery(counterPath string) (pdhCounterHandle, error) + addEnglishCounterToQuery(counterPath string) (pdhCounterHandle, error) + getCounterPath(counterHandle pdhCounterHandle) (string, error) + expandWildCardPath(counterPath string) ([]string, error) + getFormattedCounterValueDouble(hCounter pdhCounterHandle) (float64, error) + getRawCounterValue(hCounter pdhCounterHandle) (int64, error) + getFormattedCounterArrayDouble(hCounter pdhCounterHandle) ([]counterValue, error) + getRawCounterArray(hCounter pdhCounterHandle) ([]counterValue, error) + collectData() error + collectDataWithTime() (time.Time, error) + isVistaOrNewer() bool } -type PerformanceQueryCreator interface { - NewPerformanceQuery(string, uint32) PerformanceQuery +type performanceQueryCreator interface { + newPerformanceQuery(string, uint32) performanceQuery } // pdhError represents error returned from Performance Counters API type pdhError struct { - ErrorCode uint32 + errorCode uint32 errorText string } @@ -54,14 +54,14 @@ func (m *pdhError) Error() string { return m.errorText } -func NewPdhError(code uint32) error { +func newPdhError(code uint32) error { return &pdhError{ - ErrorCode: code, - errorText: PdhFormatError(code), + errorCode: code, + errorText: pdhFormatError(code), } } -// performanceQueryImpl is implementation of PerformanceQuery interface, which calls phd.dll functions +// performanceQueryImpl is implementation of performanceQuery interface, which calls phd.dll functions type performanceQueryImpl struct { maxBufferSize uint32 query pdhQueryHandle @@ -69,75 +69,75 @@ type performanceQueryImpl struct { type performanceQueryCreatorImpl struct{} -func (performanceQueryCreatorImpl) NewPerformanceQuery(_ string, maxBufferSize uint32) PerformanceQuery { +func (performanceQueryCreatorImpl) newPerformanceQuery(_ string, maxBufferSize uint32) performanceQuery { return &performanceQueryImpl{maxBufferSize: maxBufferSize} } -// Open creates a new counterPath that is used to manage the collection of performance data. +// open creates a new counterPath that is used to manage the collection of performance data. // It returns counterPath handle used for subsequent calls for adding counters and querying data -func (m *performanceQueryImpl) Open() error { +func (m *performanceQueryImpl) open() error { if m.query != 0 { - err := m.Close() + err := m.close() if err != nil { return err } } var handle pdhQueryHandle - if ret := PdhOpenQuery(0, 0, &handle); ret != ErrorSuccess { - return NewPdhError(ret) + if ret := pdhOpenQuery(0, 0, &handle); ret != errorSuccess { + return newPdhError(ret) } m.query = handle return nil } -// Close closes the counterPath, releases associated counter handles and frees resources -func (m *performanceQueryImpl) Close() error { +// close closes the counterPath, releases associated counter handles and frees resources +func (m *performanceQueryImpl) close() error { if m.query == 0 { return errors.New("uninitialized query") } - if ret := PdhCloseQuery(m.query); ret != ErrorSuccess { - return NewPdhError(ret) + if ret := pdhCloseQuery(m.query); ret != errorSuccess { + return newPdhError(ret) } m.query = 0 return nil } -func (m *performanceQueryImpl) AddCounterToQuery(counterPath string) (pdhCounterHandle, error) { +func (m *performanceQueryImpl) addCounterToQuery(counterPath string) (pdhCounterHandle, error) { var counterHandle pdhCounterHandle if m.query == 0 { return 0, errors.New("uninitialized query") } - if ret := PdhAddCounter(m.query, counterPath, 0, &counterHandle); ret != ErrorSuccess { - return 0, NewPdhError(ret) + if ret := pdhAddCounter(m.query, counterPath, 0, &counterHandle); ret != errorSuccess { + return 0, newPdhError(ret) } return counterHandle, nil } -func (m *performanceQueryImpl) AddEnglishCounterToQuery(counterPath string) (pdhCounterHandle, error) { +func (m *performanceQueryImpl) addEnglishCounterToQuery(counterPath string) (pdhCounterHandle, error) { var counterHandle pdhCounterHandle if m.query == 0 { return 0, errors.New("uninitialized query") } - if ret := PdhAddEnglishCounter(m.query, counterPath, 0, &counterHandle); ret != ErrorSuccess { - return 0, NewPdhError(ret) + if ret := pdhAddEnglishCounter(m.query, counterPath, 0, &counterHandle); ret != errorSuccess { + return 0, newPdhError(ret) } return counterHandle, nil } -// GetCounterPath return counter information for given handle -func (m *performanceQueryImpl) GetCounterPath(counterHandle pdhCounterHandle) (string, error) { +// getCounterPath returns counter information for given handle +func (m *performanceQueryImpl) getCounterPath(counterHandle pdhCounterHandle) (string, error) { for buflen := initialBufferSize; buflen <= m.maxBufferSize; buflen *= 2 { buf := make([]byte, buflen) // Get the info with the current buffer size size := buflen - ret := PdhGetCounterInfo(counterHandle, 0, &size, &buf[0]) - if ret == ErrorSuccess { + ret := pdhGetCounterInfo(counterHandle, 0, &size, &buf[0]) + if ret == errorSuccess { ci := (*pdhCounterInfo)(unsafe.Pointer(&buf[0])) //nolint:gosec // G103: Valid use of unsafe call to create PDH_COUNTER_INFO - return UTF16PtrToString(ci.SzFullPath), nil + return utf16PtrToString(ci.SzFullPath), nil } // Use the size as a hint if it exceeds the current buffer size @@ -146,24 +146,24 @@ func (m *performanceQueryImpl) GetCounterPath(counterHandle pdhCounterHandle) (s } // We got a non-recoverable error so exit here - if ret != PdhMoreData { - return "", NewPdhError(ret) + if ret != pdhMoreData { + return "", newPdhError(ret) } } return "", errBufferLimitReached } -// ExpandWildCardPath examines local computer and returns those counter paths that match the given counter path which contains wildcard characters. -func (m *performanceQueryImpl) ExpandWildCardPath(counterPath string) ([]string, error) { +// expandWildCardPath examines local computer and returns those counter paths that match the given counter path which contains wildcard characters. +func (m *performanceQueryImpl) expandWildCardPath(counterPath string) ([]string, error) { for buflen := initialBufferSize; buflen <= m.maxBufferSize; buflen *= 2 { buf := make([]uint16, buflen) // Get the info with the current buffer size size := buflen - ret := PdhExpandWildCardPath(counterPath, &buf[0], &size) - if ret == ErrorSuccess { - return UTF16ToStringArray(buf), nil + ret := pdhExpandWildCardPath(counterPath, &buf[0], &size) + if ret == errorSuccess { + return utf16ToStringArray(buf), nil } // Use the size as a hint if it exceeds the current buffer size @@ -172,43 +172,43 @@ func (m *performanceQueryImpl) ExpandWildCardPath(counterPath string) ([]string, } // We got a non-recoverable error so exit here - if ret != PdhMoreData { - return nil, NewPdhError(ret) + if ret != pdhMoreData { + return nil, newPdhError(ret) } } return nil, errBufferLimitReached } -// GetFormattedCounterValueDouble computes a displayable value for the specified counter -func (*performanceQueryImpl) GetFormattedCounterValueDouble(hCounter pdhCounterHandle) (float64, error) { +// getFormattedCounterValueDouble computes a displayable value for the specified counter +func (*performanceQueryImpl) getFormattedCounterValueDouble(hCounter pdhCounterHandle) (float64, error) { var counterType uint32 var value pdhFmtCountervalueDouble - if ret := PdhGetFormattedCounterValueDouble(hCounter, &counterType, &value); ret != ErrorSuccess { - return 0, NewPdhError(ret) + if ret := pdhGetFormattedCounterValueDouble(hCounter, &counterType, &value); ret != errorSuccess { + return 0, newPdhError(ret) } - if value.CStatus == PdhCstatusValidData || value.CStatus == PdhCstatusNewData { + if value.CStatus == pdhCstatusValidData || value.CStatus == pdhCstatusNewData { return value.DoubleValue, nil } - return 0, NewPdhError(value.CStatus) + return 0, newPdhError(value.CStatus) } -func (m *performanceQueryImpl) GetFormattedCounterArrayDouble(hCounter pdhCounterHandle) ([]counterValue, error) { +func (m *performanceQueryImpl) getFormattedCounterArrayDouble(hCounter pdhCounterHandle) ([]counterValue, error) { for buflen := initialBufferSize; buflen <= m.maxBufferSize; buflen *= 2 { buf := make([]byte, buflen) // Get the info with the current buffer size var itemCount uint32 size := buflen - ret := PdhGetFormattedCounterArrayDouble(hCounter, &size, &itemCount, &buf[0]) - if ret == ErrorSuccess { + ret := pdhGetFormattedCounterArrayDouble(hCounter, &size, &itemCount, &buf[0]) + if ret == errorSuccess { //nolint:gosec // G103: Valid use of unsafe call to create PDH_FMT_COUNTERVALUE_ITEM_DOUBLE items := (*[1 << 20]pdhFmtCountervalueItemDouble)(unsafe.Pointer(&buf[0]))[:itemCount] values := make([]counterValue, 0, itemCount) for _, item := range items { - if item.FmtValue.CStatus == PdhCstatusValidData || item.FmtValue.CStatus == PdhCstatusNewData { - val := counterValue{UTF16PtrToString(item.SzName), item.FmtValue.DoubleValue} + if item.FmtValue.CStatus == pdhCstatusValidData || item.FmtValue.CStatus == pdhCstatusNewData { + val := counterValue{utf16PtrToString(item.SzName), item.FmtValue.DoubleValue} values = append(values, val) } } @@ -221,29 +221,29 @@ func (m *performanceQueryImpl) GetFormattedCounterArrayDouble(hCounter pdhCounte } // We got a non-recoverable error so exit here - if ret != PdhMoreData { - return nil, NewPdhError(ret) + if ret != pdhMoreData { + return nil, newPdhError(ret) } } return nil, errBufferLimitReached } -func (m *performanceQueryImpl) GetRawCounterArray(hCounter pdhCounterHandle) ([]counterValue, error) { +func (m *performanceQueryImpl) getRawCounterArray(hCounter pdhCounterHandle) ([]counterValue, error) { for buflen := initialBufferSize; buflen <= m.maxBufferSize; buflen *= 2 { buf := make([]byte, buflen) // Get the info with the current buffer size var itemCount uint32 size := buflen - ret := PdhGetRawCounterArray(hCounter, &size, &itemCount, &buf[0]) - if ret == ErrorSuccess { + ret := pdhGetRawCounterArray(hCounter, &size, &itemCount, &buf[0]) + if ret == errorSuccess { //nolint:gosec // G103: Valid use of unsafe call to create PDH_RAW_COUNTER_ITEM items := (*[1 << 20]pdhRawCounterItem)(unsafe.Pointer(&buf[0]))[:itemCount] values := make([]counterValue, 0, itemCount) for _, item := range items { - if item.RawValue.CStatus == PdhCstatusValidData || item.RawValue.CStatus == PdhCstatusNewData { - val := counterValue{UTF16PtrToString(item.SzName), item.RawValue.FirstValue} + if item.RawValue.CStatus == pdhCstatusValidData || item.RawValue.CStatus == pdhCstatusNewData { + val := counterValue{utf16PtrToString(item.SzName), item.RawValue.FirstValue} values = append(values, val) } } @@ -256,42 +256,42 @@ func (m *performanceQueryImpl) GetRawCounterArray(hCounter pdhCounterHandle) ([] } // We got a non-recoverable error so exit here - if ret != PdhMoreData { - return nil, NewPdhError(ret) + if ret != pdhMoreData { + return nil, newPdhError(ret) } } return nil, errBufferLimitReached } -func (m *performanceQueryImpl) CollectData() error { +func (m *performanceQueryImpl) collectData() error { var ret uint32 if m.query == 0 { return errors.New("uninitialized query") } - if ret = PdhCollectQueryData(m.query); ret != ErrorSuccess { - return NewPdhError(ret) + if ret = pdhCollectQueryData(m.query); ret != errorSuccess { + return newPdhError(ret) } return nil } -func (m *performanceQueryImpl) CollectDataWithTime() (time.Time, error) { +func (m *performanceQueryImpl) collectDataWithTime() (time.Time, error) { if m.query == 0 { return time.Now(), errors.New("uninitialized query") } - ret, mtime := PdhCollectQueryDataWithTime(m.query) - if ret != ErrorSuccess { - return time.Now(), NewPdhError(ret) + ret, mtime := pdhCollectQueryDataWithTime(m.query) + if ret != errorSuccess { + return time.Now(), newPdhError(ret) } return mtime, nil } -func (*performanceQueryImpl) IsVistaOrNewer() bool { - return PdhAddEnglishCounterSupported() +func (*performanceQueryImpl) isVistaOrNewer() bool { + return pdhAddEnglishCounterSupported() } -func (m *performanceQueryImpl) GetRawCounterValue(hCounter pdhCounterHandle) (int64, error) { +func (m *performanceQueryImpl) getRawCounterValue(hCounter pdhCounterHandle) (int64, error) { if m.query == 0 { return 0, errors.New("uninitialised query") } @@ -300,17 +300,17 @@ func (m *performanceQueryImpl) GetRawCounterValue(hCounter pdhCounterHandle) (in var value pdhRawCounter var ret uint32 - if ret = PdhGetRawCounterValue(hCounter, &counterType, &value); ret == ErrorSuccess { - if value.CStatus == PdhCstatusValidData || value.CStatus == PdhCstatusNewData { + if ret = pdhGetRawCounterValue(hCounter, &counterType, &value); ret == errorSuccess { + if value.CStatus == pdhCstatusValidData || value.CStatus == pdhCstatusNewData { return value.FirstValue, nil } - return 0, NewPdhError(value.CStatus) + return 0, newPdhError(value.CStatus) } - return 0, NewPdhError(ret) + return 0, newPdhError(ret) } -// UTF16PtrToString converts Windows API LPTSTR (pointer to string) to go string -func UTF16PtrToString(s *uint16) string { +// utf16PtrToString converts Windows API LPTSTR (pointer to string) to go string +func utf16PtrToString(s *uint16) string { if s == nil { return "" } @@ -318,16 +318,16 @@ func UTF16PtrToString(s *uint16) string { return syscall.UTF16ToString((*[1 << 29]uint16)(unsafe.Pointer(s))[0:]) } -// UTF16ToStringArray converts list of Windows API NULL terminated strings to go string array -func UTF16ToStringArray(buf []uint16) []string { +// utf16ToStringArray converts list of Windows API NULL terminated strings to go string array +func utf16ToStringArray(buf []uint16) []string { var strings []string nextLineStart := 0 - stringLine := UTF16PtrToString(&buf[0]) + stringLine := utf16PtrToString(&buf[0]) for stringLine != "" { strings = append(strings, stringLine) nextLineStart += len([]rune(stringLine)) + 1 remainingBuf := buf[nextLineStart:] - stringLine = UTF16PtrToString(&remainingBuf[0]) + stringLine = utf16PtrToString(&remainingBuf[0]) } return strings } diff --git a/plugins/inputs/win_perf_counters/win_perf_counters.go b/plugins/inputs/win_perf_counters/win_perf_counters.go index 4802eb17e..a56cb39a2 100644 --- a/plugins/inputs/win_perf_counters/win_perf_counters.go +++ b/plugins/inputs/win_perf_counters/win_perf_counters.go @@ -21,51 +21,56 @@ import ( //go:embed sample.conf var sampleConfig string -var defaultMaxBufferSize = config.Size(100 * 1024 * 1024) +var ( + defaultMaxBufferSize = config.Size(100 * 1024 * 1024) + sanitizedChars = strings.NewReplacer("/sec", "_persec", "/Sec", "_persec", " ", "_", "%", "Percent", `\`, "") +) + +const emptyInstance = "------" type WinPerfCounters struct { - PrintValid bool `toml:"PrintValid"` - PreVistaSupport bool `toml:"PreVistaSupport" deprecated:"1.7.0;1.35.0;determined dynamically"` - UsePerfCounterTime bool - Object []perfObject - CountersRefreshInterval config.Duration - UseWildcardsExpansion bool - LocalizeWildcardsExpansion bool - IgnoredErrors []string `toml:"IgnoredErrors"` - MaxBufferSize config.Size - Sources []string + PrintValid bool `toml:"PrintValid"` + PreVistaSupport bool `toml:"PreVistaSupport" deprecated:"1.7.0;1.35.0;determined dynamically"` + UsePerfCounterTime bool `toml:"UsePerfCounterTime"` + Object []perfObject `toml:"object"` + CountersRefreshInterval config.Duration `toml:"CountersRefreshInterval"` + UseWildcardsExpansion bool `toml:"UseWildcardsExpansion"` + LocalizeWildcardsExpansion bool `toml:"LocalizeWildcardsExpansion"` + IgnoredErrors []string `toml:"IgnoredErrors"` + MaxBufferSize config.Size `toml:"MaxBufferSize"` + Sources []string `toml:"Sources"` - Log telegraf.Logger + Log telegraf.Logger `toml:"-"` lastRefreshed time.Time - queryCreator PerformanceQueryCreator + queryCreator performanceQueryCreator hostCounters map[string]*hostCountersInfo // cached os.Hostname() cachedHostname string } +type perfObject struct { + Sources []string `toml:"Sources"` + ObjectName string `toml:"ObjectName"` + Counters []string `toml:"Counters"` + Instances []string `toml:"Instances"` + Measurement string `toml:"Measurement"` + WarnOnMissing bool `toml:"WarnOnMissing"` + FailOnMissing bool `toml:"FailOnMissing"` + IncludeTotal bool `toml:"IncludeTotal"` + UseRawValues bool `toml:"UseRawValues"` +} + type hostCountersInfo struct { // computer name used as key and for printing computer string // computer name used in tag tag string counters []*counter - query PerformanceQuery + query performanceQuery timestamp time.Time } -type perfObject struct { - Sources []string - ObjectName string - Counters []string - Instances []string - Measurement string - WarnOnMissing bool - FailOnMissing bool - IncludeTotal bool - UseRawValues bool -} - type counter struct { counterPath string computer string @@ -86,8 +91,103 @@ type instanceGrouping struct { type fieldGrouping map[instanceGrouping]map[string]interface{} -var sanitizedChars = strings.NewReplacer("/sec", "_persec", "/Sec", "_persec", - " ", "_", "%", "Percent", `\`, "") +func (*WinPerfCounters) SampleConfig() string { + return sampleConfig +} + +func (m *WinPerfCounters) Init() error { + // Check the buffer size + if m.MaxBufferSize < config.Size(initialBufferSize) { + return fmt.Errorf("maximum buffer size should at least be %d", 2*initialBufferSize) + } + if m.MaxBufferSize > math.MaxUint32 { + return fmt.Errorf("maximum buffer size should be smaller than %d", uint32(math.MaxUint32)) + } + + if m.UseWildcardsExpansion && !m.LocalizeWildcardsExpansion { + // Counters must not have wildcards with this option + found := false + wildcards := []string{"*", "?"} + + for _, object := range m.Object { + for _, wildcard := range wildcards { + if strings.Contains(object.ObjectName, wildcard) { + found = true + m.Log.Errorf("Object: %s, contains wildcard %s", object.ObjectName, wildcard) + } + } + for _, counter := range object.Counters { + for _, wildcard := range wildcards { + if strings.Contains(counter, wildcard) { + found = true + m.Log.Errorf("Object: %s, counter: %s contains wildcard %s", object.ObjectName, counter, wildcard) + } + } + } + } + + if found { + return errors.New("wildcards can't be used with LocalizeWildcardsExpansion=false") + } + } + return nil +} + +func (m *WinPerfCounters) Gather(acc telegraf.Accumulator) error { + // Parse the config once + var err error + + if m.lastRefreshed.IsZero() || (m.CountersRefreshInterval > 0 && m.lastRefreshed.Add(time.Duration(m.CountersRefreshInterval)).Before(time.Now())) { + if err := m.cleanQueries(); err != nil { + return err + } + + if err := m.parseConfig(); err != nil { + return err + } + for _, hostCounterSet := range m.hostCounters { + // some counters need two data samples before computing a value + if err = hostCounterSet.query.collectData(); err != nil { + return m.checkError(err) + } + } + m.lastRefreshed = time.Now() + // minimum time between collecting two samples + time.Sleep(time.Second) + } + + for _, hostCounterSet := range m.hostCounters { + if m.UsePerfCounterTime && hostCounterSet.query.isVistaOrNewer() { + hostCounterSet.timestamp, err = hostCounterSet.query.collectDataWithTime() + if err != nil { + return err + } + } else { + hostCounterSet.timestamp = time.Now() + if err := hostCounterSet.query.collectData(); err != nil { + return err + } + } + } + var wg sync.WaitGroup + // iterate over computers + for _, hostCounterInfo := range m.hostCounters { + wg.Add(1) + go func(hostInfo *hostCountersInfo) { + m.Log.Debugf("Gathering from %s", hostInfo.computer) + start := time.Now() + err := m.gatherComputerCounters(hostInfo, acc) + m.Log.Debugf("Gathering from %s finished in %v", hostInfo.computer, time.Since(start)) + if err != nil && m.checkError(err) != nil { + acc.AddError(fmt.Errorf("error during collecting data on host %q: %w", hostInfo.computer, err)) + } + wg.Done() + }(hostCounterInfo) + } + + wg.Wait() + return nil +} // extractCounterInfoFromCounterPath gets object name, instance name (if available) and counter name from counter path // General Counter path pattern is: \\computer\object(parent/instance#index)\counter @@ -153,10 +253,6 @@ func extractCounterInfoFromCounterPath(counterPath string) (computer string, obj return computer, object, instance, counter, nil } -func (*WinPerfCounters) SampleConfig() string { - return sampleConfig -} - func (m *WinPerfCounters) hostname() string { if m.cachedHostname != "" { return m.cachedHostname @@ -195,7 +291,7 @@ func newCounter( } //nolint:revive //argument-limit conditionally more arguments allowed -func (m *WinPerfCounters) AddItem(counterPath, computer, objectName, instance, counterName, measurement string, includeTotal bool, useRawValue bool) error { +func (m *WinPerfCounters) addItem(counterPath, computer, objectName, instance, counterName, measurement string, includeTotal bool, useRawValue bool) error { origCounterPath := counterPath var err error var counterHandle pdhCounterHandle @@ -211,20 +307,20 @@ func (m *WinPerfCounters) AddItem(counterPath, computer, objectName, instance, c if !ok { hostCounter = &hostCountersInfo{computer: computer, tag: sourceTag} m.hostCounters[computer] = hostCounter - hostCounter.query = m.queryCreator.NewPerformanceQuery(computer, uint32(m.MaxBufferSize)) - if err := hostCounter.query.Open(); err != nil { + hostCounter.query = m.queryCreator.newPerformanceQuery(computer, uint32(m.MaxBufferSize)) + if err := hostCounter.query.open(); err != nil { return err } hostCounter.counters = make([]*counter, 0) } - if !hostCounter.query.IsVistaOrNewer() { - counterHandle, err = hostCounter.query.AddCounterToQuery(counterPath) + if !hostCounter.query.isVistaOrNewer() { + counterHandle, err = hostCounter.query.addCounterToQuery(counterPath) if err != nil { return err } } else { - counterHandle, err = hostCounter.query.AddEnglishCounterToQuery(counterPath) + counterHandle, err = hostCounter.query.addEnglishCounterToQuery(counterPath) if err != nil { return err } @@ -232,11 +328,11 @@ func (m *WinPerfCounters) AddItem(counterPath, computer, objectName, instance, c if m.UseWildcardsExpansion { origInstance := instance - counterPath, err = hostCounter.query.GetCounterPath(counterHandle) + counterPath, err = hostCounter.query.getCounterPath(counterHandle) if err != nil { return err } - counters, err := hostCounter.query.ExpandWildCardPath(counterPath) + counters, err := hostCounter.query.expandWildCardPath(counterPath) if err != nil { return err } @@ -247,7 +343,7 @@ func (m *WinPerfCounters) AddItem(counterPath, computer, objectName, instance, c } for _, counterPath := range counters { - _, err := hostCounter.query.AddCounterToQuery(counterPath) + _, err := hostCounter.query.addCounterToQuery(counterPath) if err != nil { return err } @@ -261,7 +357,7 @@ func (m *WinPerfCounters) AddItem(counterPath, computer, objectName, instance, c if !m.LocalizeWildcardsExpansion { // On localized installations of Windows, Telegraf // should return English metrics, but - // ExpandWildCardPath returns localized counters. Undo + // expandWildCardPath returns localized counters. Undo // that by using the original object and counter // names, along with the expanded instance. @@ -272,7 +368,7 @@ func (m *WinPerfCounters) AddItem(counterPath, computer, objectName, instance, c newInstance = instance } counterPath = formatPath(computer, origObjectName, newInstance, origCounterName) - counterHandle, err = hostCounter.query.AddEnglishCounterToQuery(counterPath) + counterHandle, err = hostCounter.query.addEnglishCounterToQuery(counterPath) if err != nil { return err } @@ -287,7 +383,7 @@ func (m *WinPerfCounters) AddItem(counterPath, computer, objectName, instance, c useRawValue, ) } else { - counterHandle, err = hostCounter.query.AddCounterToQuery(counterPath) + counterHandle, err = hostCounter.query.addCounterToQuery(counterPath) if err != nil { return err } @@ -335,8 +431,6 @@ func (m *WinPerfCounters) AddItem(counterPath, computer, objectName, instance, c return nil } -const emptyInstance = "------" - func formatPath(computer, objectName, instance, counter string) string { path := "" if instance == emptyInstance { @@ -350,7 +444,7 @@ func formatPath(computer, objectName, instance, counter string) string { return path } -func (m *WinPerfCounters) ParseConfig() error { +func (m *WinPerfCounters) parseConfig() error { var counterPath string if len(m.Sources) == 0 { @@ -380,7 +474,7 @@ func (m *WinPerfCounters) ParseConfig() error { objectName := PerfObject.ObjectName counterPath = formatPath(computer, objectName, instance, counter) - err := m.AddItem(counterPath, computer, objectName, instance, counter, + err := m.addItem(counterPath, computer, objectName, instance, counter, PerfObject.Measurement, PerfObject.IncludeTotal, PerfObject.UseRawValues) if err != nil { if PerfObject.FailOnMissing || PerfObject.WarnOnMissing { @@ -402,7 +496,7 @@ func (m *WinPerfCounters) checkError(err error) error { var pdhErr *pdhError if errors.As(err, &pdhErr) { for _, ignoredErrors := range m.IgnoredErrors { - if PDHErrors[pdhErr.ErrorCode] == ignoredErrors { + if pdhErrors[pdhErr.errorCode] == ignoredErrors { return nil } } @@ -412,62 +506,6 @@ func (m *WinPerfCounters) checkError(err error) error { return err } -func (m *WinPerfCounters) Gather(acc telegraf.Accumulator) error { - // Parse the config once - var err error - - if m.lastRefreshed.IsZero() || (m.CountersRefreshInterval > 0 && m.lastRefreshed.Add(time.Duration(m.CountersRefreshInterval)).Before(time.Now())) { - if err := m.cleanQueries(); err != nil { - return err - } - - if err := m.ParseConfig(); err != nil { - return err - } - for _, hostCounterSet := range m.hostCounters { - // some counters need two data samples before computing a value - if err = hostCounterSet.query.CollectData(); err != nil { - return m.checkError(err) - } - } - m.lastRefreshed = time.Now() - // minimum time between collecting two samples - time.Sleep(time.Second) - } - - for _, hostCounterSet := range m.hostCounters { - if m.UsePerfCounterTime && hostCounterSet.query.IsVistaOrNewer() { - hostCounterSet.timestamp, err = hostCounterSet.query.CollectDataWithTime() - if err != nil { - return err - } - } else { - hostCounterSet.timestamp = time.Now() - if err := hostCounterSet.query.CollectData(); err != nil { - return err - } - } - } - var wg sync.WaitGroup - // iterate over computers - for _, hostCounterInfo := range m.hostCounters { - wg.Add(1) - go func(hostInfo *hostCountersInfo) { - m.Log.Debugf("Gathering from %s", hostInfo.computer) - start := time.Now() - err := m.gatherComputerCounters(hostInfo, acc) - m.Log.Debugf("Gathering from %s finished in %v", hostInfo.computer, time.Since(start)) - if err != nil && m.checkError(err) != nil { - acc.AddError(fmt.Errorf("error during collecting data on host %q: %w", hostInfo.computer, err)) - } - wg.Done() - }(hostCounterInfo) - } - - wg.Wait() - return nil -} - func (m *WinPerfCounters) gatherComputerCounters(hostCounterInfo *hostCountersInfo, acc telegraf.Accumulator) error { var value interface{} var err error @@ -477,9 +515,9 @@ func (m *WinPerfCounters) gatherComputerCounters(hostCounterInfo *hostCountersIn // collect if m.UseWildcardsExpansion { if metric.useRawValue { - value, err = hostCounterInfo.query.GetRawCounterValue(metric.counterHandle) + value, err = hostCounterInfo.query.getRawCounterValue(metric.counterHandle) } else { - value, err = hostCounterInfo.query.GetFormattedCounterValueDouble(metric.counterHandle) + value, err = hostCounterInfo.query.getFormattedCounterValueDouble(metric.counterHandle) } if err != nil { // ignore invalid data as some counters from process instances returns this sometimes @@ -493,9 +531,9 @@ func (m *WinPerfCounters) gatherComputerCounters(hostCounterInfo *hostCountersIn } else { var counterValues []counterValue if metric.useRawValue { - counterValues, err = hostCounterInfo.query.GetRawCounterArray(metric.counterHandle) + counterValues, err = hostCounterInfo.query.getRawCounterArray(metric.counterHandle) } else { - counterValues, err = hostCounterInfo.query.GetFormattedCounterArrayDouble(metric.counterHandle) + counterValues, err = hostCounterInfo.query.getFormattedCounterArrayDouble(metric.counterHandle) } if err != nil { // ignore invalid data as some counters from process instances returns this sometimes @@ -506,14 +544,14 @@ func (m *WinPerfCounters) gatherComputerCounters(hostCounterInfo *hostCountersIn continue } for _, cValue := range counterValues { - if strings.Contains(metric.instance, "#") && strings.HasPrefix(metric.instance, cValue.InstanceName) { + if strings.Contains(metric.instance, "#") && strings.HasPrefix(metric.instance, cValue.instanceName) { // If you are using a multiple instance identifier such as "w3wp#1" // phd.dll returns only the first 2 characters of the identifier. - cValue.InstanceName = metric.instance + cValue.instanceName = metric.instance } if shouldIncludeMetric(metric, cValue) { - addCounterMeasurement(metric, cValue.InstanceName, cValue.Value, collectedFields) + addCounterMeasurement(metric, cValue.instanceName, cValue.value, collectedFields) } } } @@ -535,7 +573,7 @@ func (m *WinPerfCounters) gatherComputerCounters(hostCounterInfo *hostCountersIn func (m *WinPerfCounters) cleanQueries() error { for _, hostCounterInfo := range m.hostCounters { - if err := hostCounterInfo.query.Close(); err != nil { + if err := hostCounterInfo.query.close(); err != nil { return err } } @@ -548,11 +586,11 @@ func shouldIncludeMetric(metric *counter, cValue counterValue) bool { // If IncludeTotal is set, include all. return true } - if metric.instance == "*" && !strings.Contains(cValue.InstanceName, "_Total") { + if metric.instance == "*" && !strings.Contains(cValue.instanceName, "_Total") { // Catch if set to * and that it is not a '*_Total*' instance. return true } - if metric.instance == cValue.InstanceName { + if metric.instance == cValue.instanceName { // Catch if we set it to total or some form of it return true } @@ -572,55 +610,17 @@ func addCounterMeasurement(metric *counter, instanceName string, value interface func isKnownCounterDataError(err error) bool { var pdhErr *pdhError - if errors.As(err, &pdhErr) && (pdhErr.ErrorCode == PdhInvalidData || - pdhErr.ErrorCode == PdhCalcNegativeDenominator || - pdhErr.ErrorCode == PdhCalcNegativeValue || - pdhErr.ErrorCode == PdhCstatusInvalidData || - pdhErr.ErrorCode == PdhCstatusNoInstance || - pdhErr.ErrorCode == PdhNoData) { + if errors.As(err, &pdhErr) && (pdhErr.errorCode == pdhInvalidData || + pdhErr.errorCode == pdhCalcNegativeDenominator || + pdhErr.errorCode == pdhCalcNegativeValue || + pdhErr.errorCode == pdhCstatusInvalidData || + pdhErr.errorCode == pdhCstatusNoInstance || + pdhErr.errorCode == pdhNoData) { return true } return false } -func (m *WinPerfCounters) Init() error { - // Check the buffer size - if m.MaxBufferSize < config.Size(initialBufferSize) { - return fmt.Errorf("maximum buffer size should at least be %d", 2*initialBufferSize) - } - if m.MaxBufferSize > math.MaxUint32 { - return fmt.Errorf("maximum buffer size should be smaller than %d", uint32(math.MaxUint32)) - } - - if m.UseWildcardsExpansion && !m.LocalizeWildcardsExpansion { - // Counters must not have wildcards with this option - found := false - wildcards := []string{"*", "?"} - - for _, object := range m.Object { - for _, wildcard := range wildcards { - if strings.Contains(object.ObjectName, wildcard) { - found = true - m.Log.Errorf("Object: %s, contains wildcard %s", object.ObjectName, wildcard) - } - } - for _, counter := range object.Counters { - for _, wildcard := range wildcards { - if strings.Contains(counter, wildcard) { - found = true - m.Log.Errorf("Object: %s, counter: %s contains wildcard %s", object.ObjectName, counter, wildcard) - } - } - } - } - - if found { - return errors.New("wildcards can't be used with LocalizeWildcardsExpansion=false") - } - } - return nil -} - func init() { inputs.Add("win_perf_counters", func() telegraf.Input { return &WinPerfCounters{ diff --git a/plugins/inputs/win_perf_counters/win_perf_counters_integration_test.go b/plugins/inputs/win_perf_counters/win_perf_counters_integration_test.go index 33f678daf..2b6889424 100644 --- a/plugins/inputs/win_perf_counters/win_perf_counters_integration_test.go +++ b/plugins/inputs/win_perf_counters/win_perf_counters_integration_test.go @@ -19,97 +19,97 @@ func TestWinPerformanceQueryImplIntegration(t *testing.T) { } query := &performanceQueryImpl{maxBufferSize: uint32(defaultMaxBufferSize)} - err := query.Close() + err := query.close() require.Error(t, err, "uninitialized query must return errors") - _, err = query.AddCounterToQuery("") + _, err = query.addCounterToQuery("") require.Error(t, err, "uninitialized query must return errors") require.ErrorContains(t, err, "uninitialized") - _, err = query.AddEnglishCounterToQuery("") + _, err = query.addEnglishCounterToQuery("") require.Error(t, err, "uninitialized query must return errors") require.ErrorContains(t, err, "uninitialized") - err = query.CollectData() + err = query.collectData() require.Error(t, err, "uninitialized query must return errors") require.ErrorContains(t, err, "uninitialized") - require.NoError(t, query.Open()) + require.NoError(t, query.open()) counterPath := "\\Processor Information(_Total)\\% Processor Time" - hCounter, err := query.AddCounterToQuery(counterPath) + hCounter, err := query.addCounterToQuery(counterPath) require.NoError(t, err) require.NotEqual(t, 0, hCounter) - require.NoError(t, query.Close()) + require.NoError(t, query.close()) - require.NoError(t, query.Open()) + require.NoError(t, query.open()) - hCounter, err = query.AddEnglishCounterToQuery(counterPath) + hCounter, err = query.addEnglishCounterToQuery(counterPath) require.NoError(t, err) require.NotEqual(t, 0, hCounter) - cp, err := query.GetCounterPath(hCounter) + cp, err := query.getCounterPath(hCounter) require.NoError(t, err) require.True(t, strings.HasSuffix(cp, counterPath)) - require.NoError(t, query.CollectData()) + require.NoError(t, query.collectData()) time.Sleep(time.Second) - require.NoError(t, query.CollectData()) + require.NoError(t, query.collectData()) - fcounter, err := query.GetFormattedCounterValueDouble(hCounter) + fcounter, err := query.getFormattedCounterValueDouble(hCounter) require.NoError(t, err) require.Greater(t, fcounter, float64(0)) - rcounter, err := query.GetRawCounterValue(hCounter) + rcounter, err := query.getRawCounterValue(hCounter) require.NoError(t, err) require.Greater(t, rcounter, int64(10000000)) now := time.Now() - mtime, err := query.CollectDataWithTime() + mtime, err := query.collectDataWithTime() require.NoError(t, err) require.Less(t, mtime.Sub(now), time.Second) counterPath = "\\Process(*)\\% Processor Time" - paths, err := query.ExpandWildCardPath(counterPath) + paths, err := query.expandWildCardPath(counterPath) require.NoError(t, err) require.NotNil(t, paths) require.Greater(t, len(paths), 1) counterPath = "\\Process(_Total)\\*" - paths, err = query.ExpandWildCardPath(counterPath) + paths, err = query.expandWildCardPath(counterPath) require.NoError(t, err) require.NotNil(t, paths) require.Greater(t, len(paths), 1) - require.NoError(t, query.Open()) + require.NoError(t, query.open()) counterPath = "\\Process(*)\\% Processor Time" - hCounter, err = query.AddEnglishCounterToQuery(counterPath) + hCounter, err = query.addEnglishCounterToQuery(counterPath) require.NoError(t, err) require.NotEqual(t, 0, hCounter) - require.NoError(t, query.CollectData()) + require.NoError(t, query.collectData()) time.Sleep(time.Second) - require.NoError(t, query.CollectData()) + require.NoError(t, query.collectData()) - farr, err := query.GetFormattedCounterArrayDouble(hCounter) + farr, err := query.getFormattedCounterArrayDouble(hCounter) var phdErr *pdhError - if errors.As(err, &phdErr) && phdErr.ErrorCode != PdhInvalidData && phdErr.ErrorCode != PdhCalcNegativeValue { + if errors.As(err, &phdErr) && phdErr.errorCode != pdhInvalidData && phdErr.errorCode != pdhCalcNegativeValue { time.Sleep(time.Second) - farr, err = query.GetFormattedCounterArrayDouble(hCounter) + farr, err = query.getFormattedCounterArrayDouble(hCounter) } require.NoError(t, err) require.NotEmpty(t, farr) - rarr, err := query.GetRawCounterArray(hCounter) + rarr, err := query.getRawCounterArray(hCounter) require.NoError(t, err) require.NotEmpty(t, rarr, "Too") - require.NoError(t, query.Close()) + require.NoError(t, query.close()) } func TestWinPerfCountersConfigGet1Integration(t *testing.T) { @@ -137,7 +137,7 @@ func TestWinPerfCountersConfigGet1Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.NoError(t, m.ParseConfig()) + require.NoError(t, m.parseConfig()) } func TestWinPerfCountersConfigGet2Integration(t *testing.T) { @@ -165,7 +165,7 @@ func TestWinPerfCountersConfigGet2Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.NoError(t, m.ParseConfig()) + require.NoError(t, m.parseConfig()) hostCounters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -204,7 +204,7 @@ func TestWinPerfCountersConfigGet3Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.NoError(t, m.ParseConfig()) + require.NoError(t, m.parseConfig()) hostCounters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -241,7 +241,7 @@ func TestWinPerfCountersConfigGet4Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.NoError(t, m.ParseConfig()) + require.NoError(t, m.parseConfig()) hostCounters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -278,7 +278,7 @@ func TestWinPerfCountersConfigGet5Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.NoError(t, m.ParseConfig()) + require.NoError(t, m.parseConfig()) hostCounters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -315,7 +315,7 @@ func TestWinPerfCountersConfigGet6Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.NoError(t, m.ParseConfig()) + require.NoError(t, m.parseConfig()) _, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -343,7 +343,7 @@ func TestWinPerfCountersConfigGet7Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.NoError(t, m.ParseConfig()) + require.NoError(t, m.parseConfig()) hostCounters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -380,7 +380,7 @@ func TestWinPerfCountersConfigError1Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.Error(t, m.ParseConfig()) + require.Error(t, m.parseConfig()) } func TestWinPerfCountersConfigError2Integration(t *testing.T) { @@ -408,7 +408,7 @@ func TestWinPerfCountersConfigError2Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.NoError(t, m.ParseConfig()) + require.NoError(t, m.parseConfig()) var acc testutil.Accumulator require.Error(t, m.Gather(&acc)) } @@ -438,7 +438,7 @@ func TestWinPerfCountersConfigError3Integration(t *testing.T) { queryCreator: &performanceQueryCreatorImpl{}, } - require.Error(t, m.ParseConfig()) + require.Error(t, m.parseConfig()) } func TestWinPerfCountersCollect1Integration(t *testing.T) { diff --git a/plugins/inputs/win_perf_counters/win_perf_counters_notwindows.go b/plugins/inputs/win_perf_counters/win_perf_counters_notwindows.go index 6eb4f33b9..de187d1c0 100644 --- a/plugins/inputs/win_perf_counters/win_perf_counters_notwindows.go +++ b/plugins/inputs/win_perf_counters/win_perf_counters_notwindows.go @@ -20,7 +20,7 @@ type WinPerfCounters struct { func (*WinPerfCounters) SampleConfig() string { return sampleConfig } func (w *WinPerfCounters) Init() error { - w.Log.Warn("current platform is not supported") + w.Log.Warn("Current platform is not supported") return nil } diff --git a/plugins/inputs/win_perf_counters/win_perf_counters_test.go b/plugins/inputs/win_perf_counters/win_perf_counters_test.go index cb7d43c26..19f12d96f 100644 --- a/plugins/inputs/win_perf_counters/win_perf_counters_test.go +++ b/plugins/inputs/win_perf_counters/win_perf_counters_test.go @@ -22,16 +22,16 @@ type testCounter struct { status uint32 // allows for tests against specific pdh_error codes, rather than assuming all cases of "value == 0" to indicate error conditions } -type FakePerformanceQuery struct { +type fakePerformanceQuery struct { counters map[string]testCounter vistaAndNewer bool expandPaths map[string][]string openCalled bool } -var MetricTime = time.Date(2018, 5, 28, 12, 0, 0, 0, time.UTC) +var metricTime = time.Date(2018, 5, 28, 12, 0, 0, 0, time.UTC) -func (m *testCounter) ToCounterValue(raw bool) *counterValue { +func (m *testCounter) toCounterValue(raw bool) *counterValue { //nolint:dogsled,errcheck // only instance is needed for this helper function in tests _, _, inst, _, _ := extractCounterInfoFromCounterPath(m.path) if inst == "" { @@ -47,9 +47,9 @@ func (m *testCounter) ToCounterValue(raw bool) *counterValue { return &counterValue{inst, val} } -func (m *FakePerformanceQuery) Open() error { +func (m *fakePerformanceQuery) open() error { if m.openCalled { - err := m.Close() + err := m.close() if err != nil { return err } @@ -58,81 +58,81 @@ func (m *FakePerformanceQuery) Open() error { return nil } -func (m *FakePerformanceQuery) Close() error { +func (m *fakePerformanceQuery) close() error { if !m.openCalled { - return errors.New("in Close: uninitialized query") + return errors.New("in close: uninitialized query") } m.openCalled = false return nil } -func (m *FakePerformanceQuery) AddCounterToQuery(counterPath string) (pdhCounterHandle, error) { +func (m *fakePerformanceQuery) addCounterToQuery(counterPath string) (pdhCounterHandle, error) { if !m.openCalled { - return 0, errors.New("in AddCounterToQuery: uninitialized query") + return 0, errors.New("in addCounterToQuery: uninitialized query") } if c, ok := m.counters[counterPath]; ok { return c.handle, nil } - return 0, fmt.Errorf("in AddCounterToQuery: invalid counter path: %q", counterPath) + return 0, fmt.Errorf("in addCounterToQuery: invalid counter path: %q", counterPath) } -func (m *FakePerformanceQuery) AddEnglishCounterToQuery(counterPath string) (pdhCounterHandle, error) { +func (m *fakePerformanceQuery) addEnglishCounterToQuery(counterPath string) (pdhCounterHandle, error) { if !m.openCalled { - return 0, errors.New("in AddEnglishCounterToQuery: uninitialized query") + return 0, errors.New("in addEnglishCounterToQuery: uninitialized query") } if c, ok := m.counters[counterPath]; ok { return c.handle, nil } - return 0, fmt.Errorf("in AddEnglishCounterToQuery: invalid counter path: %q", counterPath) + return 0, fmt.Errorf("in addEnglishCounterToQuery: invalid counter path: %q", counterPath) } -func (m *FakePerformanceQuery) GetCounterPath(counterHandle pdhCounterHandle) (string, error) { +func (m *fakePerformanceQuery) getCounterPath(counterHandle pdhCounterHandle) (string, error) { for _, counter := range m.counters { if counter.handle == counterHandle { return counter.path, nil } } - return "", fmt.Errorf("in GetCounterPath: invalid handle: %q", counterHandle) + return "", fmt.Errorf("in getCounterPath: invalid handle: %q", counterHandle) } -func (m *FakePerformanceQuery) ExpandWildCardPath(counterPath string) ([]string, error) { +func (m *fakePerformanceQuery) expandWildCardPath(counterPath string) ([]string, error) { if e, ok := m.expandPaths[counterPath]; ok { return e, nil } - return nil, fmt.Errorf("in ExpandWildCardPath: invalid counter path: %q", counterPath) + return nil, fmt.Errorf("in expandWildCardPath: invalid counter path: %q", counterPath) } -func (m *FakePerformanceQuery) GetFormattedCounterValueDouble(counterHandle pdhCounterHandle) (float64, error) { +func (m *fakePerformanceQuery) getFormattedCounterValueDouble(counterHandle pdhCounterHandle) (float64, error) { if !m.openCalled { - return 0, errors.New("in GetFormattedCounterValueDouble: uninitialized query") + return 0, errors.New("in getFormattedCounterValueDouble: uninitialized query") } for _, counter := range m.counters { if counter.handle == counterHandle { if counter.status > 0 { - return 0, NewPdhError(counter.status) + return 0, newPdhError(counter.status) } return counter.value, nil } } - return 0, fmt.Errorf("in GetFormattedCounterValueDouble: invalid handle: %q", counterHandle) + return 0, fmt.Errorf("in getFormattedCounterValueDouble: invalid handle: %q", counterHandle) } -func (m *FakePerformanceQuery) GetRawCounterValue(counterHandle pdhCounterHandle) (int64, error) { +func (m *fakePerformanceQuery) getRawCounterValue(counterHandle pdhCounterHandle) (int64, error) { if !m.openCalled { - return 0, errors.New("in GetRawCounterValue: uninitialised query") + return 0, errors.New("in getRawCounterValue: uninitialised query") } for _, counter := range m.counters { if counter.handle == counterHandle { if counter.status > 0 { - return 0, NewPdhError(counter.status) + return 0, newPdhError(counter.status) } return int64(counter.value), nil } } - return 0, fmt.Errorf("in GetRawCounterValue: invalid handle: %q", counterHandle) + return 0, fmt.Errorf("in getRawCounterValue: invalid handle: %q", counterHandle) } -func (m *FakePerformanceQuery) findCounterByPath(counterPath string) *testCounter { +func (m *fakePerformanceQuery) findCounterByPath(counterPath string) *testCounter { for _, c := range m.counters { if c.path == counterPath { return &c @@ -141,9 +141,9 @@ func (m *FakePerformanceQuery) findCounterByPath(counterPath string) *testCounte return nil } -func (m *FakePerformanceQuery) GetFormattedCounterArrayDouble(hCounter pdhCounterHandle) ([]counterValue, error) { +func (m *fakePerformanceQuery) getFormattedCounterArrayDouble(hCounter pdhCounterHandle) ([]counterValue, error) { if !m.openCalled { - return nil, errors.New("in GetFormattedCounterArrayDouble: uninitialized query") + return nil, errors.New("in getFormattedCounterArrayDouble: uninitialized query") } for _, c := range m.counters { if c.handle == hCounter { @@ -152,24 +152,24 @@ func (m *FakePerformanceQuery) GetFormattedCounterArrayDouble(hCounter pdhCounte for _, p := range e { counter := m.findCounterByPath(p) if counter == nil { - return nil, fmt.Errorf("in GetFormattedCounterArrayDouble: invalid counter: %q", p) + return nil, fmt.Errorf("in getFormattedCounterArrayDouble: invalid counter: %q", p) } if counter.status > 0 { - return nil, NewPdhError(counter.status) + return nil, newPdhError(counter.status) } - counters = append(counters, *counter.ToCounterValue(false)) + counters = append(counters, *counter.toCounterValue(false)) } return counters, nil } - return nil, fmt.Errorf("in GetFormattedCounterArrayDouble: invalid counter: %q", hCounter) + return nil, fmt.Errorf("in getFormattedCounterArrayDouble: invalid counter: %q", hCounter) } } - return nil, fmt.Errorf("in GetFormattedCounterArrayDouble: invalid counter: %q, no paths found", hCounter) + return nil, fmt.Errorf("in getFormattedCounterArrayDouble: invalid counter: %q, no paths found", hCounter) } -func (m *FakePerformanceQuery) GetRawCounterArray(hCounter pdhCounterHandle) ([]counterValue, error) { +func (m *fakePerformanceQuery) getRawCounterArray(hCounter pdhCounterHandle) ([]counterValue, error) { if !m.openCalled { - return nil, errors.New("in GetRawCounterArray: uninitialised query") + return nil, errors.New("in getRawCounterArray: uninitialised query") } for _, c := range m.counters { if c.handle == hCounter { @@ -178,45 +178,45 @@ func (m *FakePerformanceQuery) GetRawCounterArray(hCounter pdhCounterHandle) ([] for _, p := range e { counter := m.findCounterByPath(p) if counter == nil { - return nil, fmt.Errorf("in GetRawCounterArray: invalid counter: %q", p) + return nil, fmt.Errorf("in getRawCounterArray: invalid counter: %q", p) } if counter.status > 0 { - return nil, NewPdhError(counter.status) + return nil, newPdhError(counter.status) } - counters = append(counters, *counter.ToCounterValue(true)) + counters = append(counters, *counter.toCounterValue(true)) } return counters, nil } - return nil, fmt.Errorf("in GetRawCounterArray: invalid counter: %q", hCounter) + return nil, fmt.Errorf("in getRawCounterArray: invalid counter: %q", hCounter) } } - return nil, fmt.Errorf("in GetRawCounterArray: invalid counter: %q, no paths found", hCounter) + return nil, fmt.Errorf("in getRawCounterArray: invalid counter: %q, no paths found", hCounter) } -func (m *FakePerformanceQuery) CollectData() error { +func (m *fakePerformanceQuery) collectData() error { if !m.openCalled { - return errors.New("in CollectData: uninitialized query") + return errors.New("in collectData: uninitialized query") } return nil } -func (m *FakePerformanceQuery) CollectDataWithTime() (time.Time, error) { +func (m *fakePerformanceQuery) collectDataWithTime() (time.Time, error) { if !m.openCalled { - return time.Now(), errors.New("in CollectDataWithTime: uninitialized query") + return time.Now(), errors.New("in collectDataWithTime: uninitialized query") } - return MetricTime, nil + return metricTime, nil } -func (m *FakePerformanceQuery) IsVistaOrNewer() bool { +func (m *fakePerformanceQuery) isVistaOrNewer() bool { return m.vistaAndNewer } -type FakePerformanceQueryCreator struct { - fakeQueries map[string]*FakePerformanceQuery +type fakePerformanceQueryCreator struct { + fakeQueries map[string]*fakePerformanceQuery } -func (m FakePerformanceQueryCreator) NewPerformanceQuery(computer string, _ uint32) PerformanceQuery { - var ret PerformanceQuery +func (m fakePerformanceQueryCreator) newPerformanceQuery(computer string, _ uint32) performanceQuery { + var ret performanceQuery var ok bool if ret, ok = m.fakeQueries[computer]; !ok { panic(fmt.Errorf("query for %q not found", computer)) @@ -332,8 +332,8 @@ func TestAddItemSimple(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: nil, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(cps1, []float64{1.1}, []uint32{0}), expandPaths: map[string][]string{ cps1[0]: cps1, @@ -343,7 +343,7 @@ func TestAddItemSimple(t *testing.T) { }, }, } - err = m.AddItem(cps1[0], "localhost", "O", "I", "c", "test", false, false) + err = m.addItem(cps1[0], "localhost", "O", "I", "c", "test", false, false) require.NoError(t, err) counters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -364,8 +364,8 @@ func TestAddItemInvalidCountPath(t *testing.T) { PrintValid: false, Object: nil, UseWildcardsExpansion: true, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(cps1, []float64{1.1}, []uint32{0}), expandPaths: map[string][]string{ cps1[0]: {"\\O/C"}, @@ -376,7 +376,7 @@ func TestAddItemInvalidCountPath(t *testing.T) { }, } require.NoError(t, err) - err = m.AddItem("\\O\\C", "localhost", "O", "------", "C", "test", false, false) + err = m.addItem("\\O\\C", "localhost", "O", "------", "C", "test", false, false) require.Error(t, err) } @@ -389,8 +389,8 @@ func TestParseConfigBasic(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(cps1, []float64{1.1, 1.2, 1.3, 1.4}, []uint32{0, 0, 0, 0}), expandPaths: map[string][]string{ cps1[0]: {cps1[0]}, @@ -404,7 +404,7 @@ func TestParseConfigBasic(t *testing.T) { }, } require.NoError(t, err) - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) counters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -413,7 +413,7 @@ func TestParseConfigBasic(t *testing.T) { require.NoError(t, err) m.UseWildcardsExpansion = true - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) counters, ok = m.hostCounters["localhost"] require.True(t, ok) @@ -441,8 +441,8 @@ func TestParseConfigMultiComps(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{ + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{ "localhost": { counters: createCounterMap(append(append(cps11, cps21...), cps31...), []float64{1.1, 1.1, 1.2, 2.1, 2.2, 1.1, 1.2, 1.3}, @@ -495,7 +495,7 @@ func TestParseConfigMultiComps(t *testing.T) { }, } require.NoError(t, err) - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) require.Len(t, m.hostCounters, 3) @@ -673,8 +673,8 @@ func TestParseConfigMultiCompsOverrideMultiplePerfObjects(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(cps1, []float64{1.1, 1.2, 1.3, 1.4}, []uint32{0, 0, 0, 0}), @@ -714,7 +714,7 @@ func TestParseConfigMultiCompsOverrideMultiplePerfObjects(t *testing.T) { }, } require.NoError(t, err) - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) require.Len(t, m.hostCounters, 3) @@ -825,8 +825,8 @@ func TestParseConfigMultiCompsOverrideOnePerfObject(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: []perfObject{perfObj, createPerfObject("", "m", "O1", []string{"I"}, []string{"C"}, false, false, false)[0]}, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{ + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{ "localhost": { counters: createCounterMap(cps21, []float64{1.1}, @@ -865,7 +865,7 @@ func TestParseConfigMultiCompsOverrideOnePerfObject(t *testing.T) { }, } require.NoError(t, err) - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) require.Len(t, m.hostCounters, 3) @@ -953,8 +953,8 @@ func TestParseConfigLocalhost(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(cps1, []float64{1.1}, []uint32{0}), expandPaths: map[string][]string{ cps1[0]: {cps1[0]}, @@ -965,7 +965,7 @@ func TestParseConfigLocalhost(t *testing.T) { }, } - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) hostCounters, ok := m.hostCounters["localhost"] @@ -980,7 +980,7 @@ func TestParseConfigLocalhost(t *testing.T) { m.Object[0].Sources = []string{""} - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) hostCounters, ok = m.hostCounters["localhost"] @@ -1000,8 +1000,8 @@ func TestParseConfigNoInstance(t *testing.T) { PrintValid: false, Object: perfObjects, UseWildcardsExpansion: false, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(cps1, []float64{1.1, 1.2}, []uint32{0, 0}), expandPaths: map[string][]string{ cps1[0]: {cps1[0]}, @@ -1013,7 +1013,7 @@ func TestParseConfigNoInstance(t *testing.T) { }, } - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) counters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -1023,7 +1023,7 @@ func TestParseConfigNoInstance(t *testing.T) { err = m.cleanQueries() require.NoError(t, err) - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) counters, ok = m.hostCounters["localhost"] require.True(t, ok) @@ -1038,8 +1038,8 @@ func TestParseConfigInvalidCounterError(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(cps1, []float64{1.1, 1.2, 1.3}, []uint32{0, 0, 0}), expandPaths: map[string][]string{ cps1[0]: {cps1[0]}, @@ -1052,14 +1052,14 @@ func TestParseConfigInvalidCounterError(t *testing.T) { }, } - err = m.ParseConfig() + err = m.parseConfig() require.Error(t, err) err = m.cleanQueries() require.NoError(t, err) m.UseWildcardsExpansion = true - err = m.ParseConfig() + err = m.parseConfig() require.Error(t, err) err = m.cleanQueries() require.NoError(t, err) @@ -1073,8 +1073,8 @@ func TestParseConfigInvalidCounterNoError(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(cps1, []float64{1.1, 1.2, 1.3}, []uint32{0, 0, 0}), expandPaths: map[string][]string{ cps1[0]: {cps1[0]}, @@ -1087,14 +1087,14 @@ func TestParseConfigInvalidCounterNoError(t *testing.T) { }, } - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) err = m.cleanQueries() require.NoError(t, err) m.UseWildcardsExpansion = true - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) err = m.cleanQueries() require.NoError(t, err) @@ -1109,8 +1109,8 @@ func TestParseConfigTotalExpansion(t *testing.T) { PrintValid: false, UseWildcardsExpansion: true, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(append(cps1, "\\O(*)\\*"), []float64{1.1, 1.2, 1.3, 1.4, 0}, []uint32{0, 0, 0, 0, 0}), expandPaths: map[string][]string{ "\\O(*)\\*": cps1, @@ -1121,7 +1121,7 @@ func TestParseConfigTotalExpansion(t *testing.T) { }, LocalizeWildcardsExpansion: true, } - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) counters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -1136,8 +1136,8 @@ func TestParseConfigTotalExpansion(t *testing.T) { PrintValid: false, UseWildcardsExpansion: true, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(append(cps1, "\\O(*)\\*"), []float64{1.1, 1.2, 1.3, 1.4, 0}, []uint32{0, 0, 0, 0, 0}), expandPaths: map[string][]string{ "\\O(*)\\*": cps1, @@ -1149,7 +1149,7 @@ func TestParseConfigTotalExpansion(t *testing.T) { LocalizeWildcardsExpansion: true, } - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) counters, ok = m.hostCounters["localhost"] require.True(t, ok) @@ -1167,8 +1167,8 @@ func TestParseConfigExpand(t *testing.T) { PrintValid: false, UseWildcardsExpansion: true, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(append(cps1, "\\O(*)\\*"), []float64{1.1, 1.2, 1.3, 1.4, 0}, []uint32{0, 0, 0, 0, 0}), expandPaths: map[string][]string{ "\\O(*)\\*": cps1, @@ -1179,7 +1179,7 @@ func TestParseConfigExpand(t *testing.T) { }, LocalizeWildcardsExpansion: true, } - err = m.ParseConfig() + err = m.parseConfig() require.NoError(t, err) counters, ok := m.hostCounters["localhost"] require.True(t, ok) @@ -1200,8 +1200,8 @@ func TestSimpleGather(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap([]string{cp1}, []float64{1.2}, []uint32{0}), expandPaths: map[string][]string{ cp1: {cp1}, @@ -1251,9 +1251,9 @@ func TestSimpleGatherNoData(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { - counters: createCounterMap([]string{cp1}, []float64{1.2}, []uint32{PdhNoData}), + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { + counters: createCounterMap([]string{cp1}, []float64{1.2}, []uint32{pdhNoData}), expandPaths: map[string][]string{ cp1: {cp1}, }, @@ -1305,8 +1305,8 @@ func TestSimpleGatherWithTimestamp(t *testing.T) { PrintValid: false, UsePerfCounterTime: true, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap([]string{cp1}, []float64{1.2}, []uint32{0}), expandPaths: map[string][]string{ cp1: {cp1}, @@ -1330,7 +1330,7 @@ func TestSimpleGatherWithTimestamp(t *testing.T) { "source": hostname(), } acc1.AssertContainsTaggedFields(t, measurement, fields1, tags1) - require.True(t, acc1.HasTimestamp(measurement, MetricTime)) + require.True(t, acc1.HasTimestamp(measurement, metricTime)) err = m.cleanQueries() require.NoError(t, err) } @@ -1347,9 +1347,9 @@ func TestGatherError(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { - counters: createCounterMap([]string{cp1}, []float64{-2}, []uint32{PdhPlaValidationWarning}), + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { + counters: createCounterMap([]string{cp1}, []float64{-2}, []uint32{pdhPlaValidationWarning}), expandPaths: map[string][]string{ cp1: {cp1}, }, @@ -1390,9 +1390,9 @@ func TestGatherInvalidDataIgnore(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { - counters: createCounterMap(cps1, []float64{1.2, 1, 0}, []uint32{0, PdhInvalidData, 0}), + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { + counters: createCounterMap(cps1, []float64{1.2, 1, 0}, []uint32{0, pdhInvalidData, 0}), expandPaths: map[string][]string{ cps1[0]: {cps1[0]}, cps1[1]: {cps1[1]}, @@ -1440,7 +1440,7 @@ func TestGatherRefreshingWithExpansion(t *testing.T) { measurement := "test" perfObjects := createPerfObject("", measurement, "O", []string{"*"}, []string{"*"}, true, false, false) cps1 := []string{"\\O(I1)\\C1", "\\O(I1)\\C2", "\\O(I2)\\C1", "\\O(I2)\\C2"} - fpm := &FakePerformanceQuery{ + fpm := &fakePerformanceQuery{ counters: createCounterMap(append(cps1, "\\O(*)\\*"), []float64{1.1, 1.2, 1.3, 1.4, 0}, []uint32{0, 0, 0, 0, 0}), expandPaths: map[string][]string{ "\\O(*)\\*": cps1, @@ -1452,8 +1452,8 @@ func TestGatherRefreshingWithExpansion(t *testing.T) { PrintValid: false, Object: perfObjects, UseWildcardsExpansion: true, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": fpm}, + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": fpm}, }, CountersRefreshInterval: config.Duration(time.Second * 10), LocalizeWildcardsExpansion: true, @@ -1491,7 +1491,7 @@ func TestGatherRefreshingWithExpansion(t *testing.T) { acc1.AssertContainsTaggedFields(t, measurement, fields2, tags2) cps2 := []string{"\\O(I1)\\C1", "\\O(I1)\\C2", "\\O(I2)\\C1", "\\O(I2)\\C2", "\\O(I3)\\C1", "\\O(I3)\\C2"} - fpm = &FakePerformanceQuery{ + fpm = &fakePerformanceQuery{ counters: createCounterMap(append(cps2, "\\O(*)\\*"), []float64{1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 0}, []uint32{0, 0, 0, 0, 0, 0, 0}), expandPaths: map[string][]string{ "\\O(*)\\*": cps2, @@ -1499,8 +1499,8 @@ func TestGatherRefreshingWithExpansion(t *testing.T) { vistaAndNewer: true, } - m.queryCreator = &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": fpm}, + m.queryCreator = &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": fpm}, } var acc2 testutil.Accumulator @@ -1548,7 +1548,7 @@ func TestGatherRefreshingWithoutExpansion(t *testing.T) { measurement := "test" perfObjects := createPerfObject("", measurement, "O", []string{"*"}, []string{"C1", "C2"}, true, false, false) cps1 := []string{"\\O(I1)\\C1", "\\O(I1)\\C2", "\\O(I2)\\C1", "\\O(I2)\\C2"} - fpm := &FakePerformanceQuery{ + fpm := &fakePerformanceQuery{ 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]}, @@ -1561,8 +1561,8 @@ func TestGatherRefreshingWithoutExpansion(t *testing.T) { PrintValid: false, Object: perfObjects, UseWildcardsExpansion: false, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": fpm}, + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": fpm}, }, CountersRefreshInterval: config.Duration(time.Second * 10)} var acc1 testutil.Accumulator @@ -1596,7 +1596,7 @@ func TestGatherRefreshingWithoutExpansion(t *testing.T) { acc1.AssertContainsTaggedFields(t, measurement, fields2, tags2) // test finding new instance cps2 := []string{"\\O(I1)\\C1", "\\O(I1)\\C2", "\\O(I2)\\C1", "\\O(I2)\\C2", "\\O(I3)\\C1", "\\O(I3)\\C2"} - fpm = &FakePerformanceQuery{ + fpm = &fakePerformanceQuery{ counters: createCounterMap( append([]string{"\\O(*)\\C1", "\\O(*)\\C2"}, cps2...), []float64{0, 0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6}, @@ -1612,8 +1612,8 @@ func TestGatherRefreshingWithoutExpansion(t *testing.T) { err = m.cleanQueries() require.NoError(t, err) m.lastRefreshed = time.Time{} - m.queryCreator = &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": fpm}, + m.queryCreator = &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": fpm}, } var acc2 testutil.Accumulator @@ -1643,7 +1643,7 @@ func TestGatherRefreshingWithoutExpansion(t *testing.T) { // test changed configuration perfObjects = createPerfObject("", measurement, "O", []string{"*"}, []string{"C1", "C2", "C3"}, true, false, false) cps3 := []string{"\\O(I1)\\C1", "\\O(I1)\\C2", "\\O(I1)\\C3", "\\O(I2)\\C1", "\\O(I2)\\C2", "\\O(I2)\\C3"} - fpm = &FakePerformanceQuery{ + fpm = &fakePerformanceQuery{ counters: createCounterMap( append([]string{"\\O(*)\\C1", "\\O(*)\\C2", "\\O(*)\\C3"}, cps3...), []float64{0, 0, 0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6}, @@ -1659,8 +1659,8 @@ func TestGatherRefreshingWithoutExpansion(t *testing.T) { err = m.cleanQueries() m.lastRefreshed = time.Time{} require.NoError(t, err) - m.queryCreator = &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": fpm}, + m.queryCreator = &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": fpm}, } m.Object = perfObjects @@ -1710,8 +1710,8 @@ func TestGatherTotalNoExpansion(t *testing.T) { PrintValid: false, UseWildcardsExpansion: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + 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}, @@ -1789,8 +1789,8 @@ func TestGatherMultiComps(t *testing.T) { Log: testutil.Logger{}, PrintValid: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + queryCreator: &fakePerformanceQueryCreator{ + fakeQueries: map[string]*fakePerformanceQuery{"localhost": { counters: createCounterMap(cps1, []float64{1.1, 1.2, 1.3, 1.4}, []uint32{0, 0, 0, 0}), @@ -1908,8 +1908,8 @@ func TestGatherRaw(t *testing.T) { PrintValid: false, UseWildcardsExpansion: false, Object: perfObjects, - queryCreator: &FakePerformanceQueryCreator{ - fakeQueries: map[string]*FakePerformanceQuery{"localhost": { + 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}, @@ -2000,16 +2000,16 @@ var stringArraySingleItem = []string{ } func TestUTF16ToStringArray(t *testing.T) { - singleItem := UTF16ToStringArray(unicodeStringListSingleItem) + singleItem := utf16ToStringArray(unicodeStringListSingleItem) require.Equal(t, singleItem, stringArraySingleItem, "Not equal single arrays") - noItem := UTF16ToStringArray(unicodeStringListNoItem) + noItem := utf16ToStringArray(unicodeStringListNoItem) require.Nil(t, noItem) - engStrings := UTF16ToStringArray(unicodeStringListWithEnglishChars) + engStrings := utf16ToStringArray(unicodeStringListWithEnglishChars) require.Equal(t, engStrings, stringArrayWithEnglishChars, "Not equal eng arrays") - czechStrings := UTF16ToStringArray(unicodeStringListWithCzechChars) + czechStrings := utf16ToStringArray(unicodeStringListWithCzechChars) require.Equal(t, czechStrings, stringArrayWithCzechChars, "Not equal czech arrays") } @@ -2069,7 +2069,7 @@ func TestCheckError(t *testing.T) { { Name: "Ignore PDH_NO_DATA", Err: &pdhError{ - ErrorCode: uint32(PdhNoData), + errorCode: uint32(pdhNoData), }, IgnoredErrors: []string{ "PDH_NO_DATA", @@ -2079,10 +2079,10 @@ func TestCheckError(t *testing.T) { { Name: "Don't ignore PDH_NO_DATA", Err: &pdhError{ - ErrorCode: uint32(PdhNoData), + errorCode: uint32(pdhNoData), }, ExpectedErr: &pdhError{ - ErrorCode: uint32(PdhNoData), + errorCode: uint32(pdhNoData), }, }, } diff --git a/plugins/inputs/win_services/win_services.go b/plugins/inputs/win_services/win_services.go index 785862d2a..3090ad8a8 100644 --- a/plugins/inputs/win_services/win_services.go +++ b/plugins/inputs/win_services/win_services.go @@ -23,90 +23,33 @@ import ( //go:embed sample.conf var sampleConfig string -type serviceError struct { - Message string - Service string - Err error +type WinServices struct { + ServiceNames []string `toml:"service_names"` + ServiceNamesExcluded []string `toml:"excluded_service_names"` + + Log telegraf.Logger `toml:"-"` + + mgrProvider managerProvider + servicesFilter filter.Filter } -func (e *serviceError) Error() string { - return fmt.Sprintf("%s: %q: %v", e.Message, e.Service, e.Err) -} - -func IsPermission(err error) bool { - var serviceErr *serviceError - if errors.As(err, &serviceErr) { - return errors.Is(serviceErr, fs.ErrPermission) - } - return false -} - -// WinService provides interface for svc.Service -type WinService interface { +// winService provides interface for svc.Service +type winService interface { Close() error Config() (mgr.Config, error) Query() (svc.Status, error) } -// ManagerProvider sets interface for acquiring manager instance, like mgr.Mgr -type ManagerProvider interface { - Connect() (WinServiceManager, error) +// managerProvider sets interface for acquiring manager instance, like mgr.Mgr +type managerProvider interface { + connect() (winServiceManager, error) } -// WinServiceManager provides interface for mgr.Mgr -type WinServiceManager interface { - Disconnect() error - OpenService(name string) (WinService, error) - ListServices() ([]string, error) -} - -// winSvcMgr is wrapper for mgr.Mgr implementing WinServiceManager interface -type winSvcMgr struct { - realMgr *mgr.Mgr -} - -func (m *winSvcMgr) Disconnect() error { - return m.realMgr.Disconnect() -} - -func (m *winSvcMgr) OpenService(name string) (WinService, error) { - serviceName, err := syscall.UTF16PtrFromString(name) - if err != nil { - return nil, fmt.Errorf("cannot convert service name %q: %w", name, err) - } - h, err := windows.OpenService(m.realMgr.Handle, serviceName, windows.GENERIC_READ) - if err != nil { - return nil, err - } - return &mgr.Service{Name: name, Handle: h}, nil -} - -func (m *winSvcMgr) ListServices() ([]string, error) { - return m.realMgr.ListServices() -} - -// mgProvider is an implementation of WinServiceManagerProvider interface returning winSvcMgr -type mgProvider struct { -} - -func (*mgProvider) Connect() (WinServiceManager, error) { - h, err := windows.OpenSCManager(nil, nil, windows.GENERIC_READ) - if err != nil { - return nil, err - } - scmgr := &mgr.Mgr{Handle: h} - return &winSvcMgr{scmgr}, nil -} - -// WinServices is an implementation if telegraf.Input interface, providing info about Windows Services -type WinServices struct { - Log telegraf.Logger - - ServiceNames []string `toml:"service_names"` - ServiceNamesExcluded []string `toml:"excluded_service_names"` - mgrProvider ManagerProvider - - servicesFilter filter.Filter +// winServiceManager provides interface for mgr.Mgr +type winServiceManager interface { + disconnect() error + openService(name string) (winService, error) + listServices() ([]string, error) } type serviceInfo struct { @@ -142,11 +85,11 @@ func (m *WinServices) Init() error { } func (m *WinServices) Gather(acc telegraf.Accumulator) error { - scmgr, err := m.mgrProvider.Connect() + scmgr, err := m.mgrProvider.connect() if err != nil { return fmt.Errorf("could not open service manager: %w", err) } - defer scmgr.Disconnect() + defer scmgr.disconnect() serviceNames, err := m.listServices(scmgr) if err != nil { @@ -156,7 +99,7 @@ func (m *WinServices) Gather(acc telegraf.Accumulator) error { for _, srvName := range serviceNames { service, err := collectServiceInfo(scmgr, srvName) if err != nil { - if IsPermission(err) { + if isPermission(err) { m.Log.Debug(err.Error()) } else { m.Log.Error(err.Error()) @@ -183,8 +126,8 @@ func (m *WinServices) Gather(acc telegraf.Accumulator) error { } // listServices returns a list of services to gather. -func (m *WinServices) listServices(scmgr WinServiceManager) ([]string, error) { - names, err := scmgr.ListServices() +func (m *WinServices) listServices(scmgr winServiceManager) ([]string, error) { + names, err := scmgr.listServices() if err != nil { return nil, fmt.Errorf("could not list services: %w", err) } @@ -201,14 +144,22 @@ func (m *WinServices) listServices(scmgr WinServiceManager) ([]string, error) { return services, nil } +func isPermission(err error) bool { + var serviceErr *serviceError + if errors.As(err, &serviceErr) { + return errors.Is(serviceErr, fs.ErrPermission) + } + return false +} + // collectServiceInfo gathers info about a service. -func collectServiceInfo(scmgr WinServiceManager, serviceName string) (*serviceInfo, error) { - srv, err := scmgr.OpenService(serviceName) +func collectServiceInfo(scmgr winServiceManager, serviceName string) (*serviceInfo, error) { + srv, err := scmgr.openService(serviceName) if err != nil { return nil, &serviceError{ - Message: "could not open service", - Service: serviceName, - Err: err, + message: "could not open service", + service: serviceName, + err: err, } } defer srv.Close() @@ -216,18 +167,18 @@ func collectServiceInfo(scmgr WinServiceManager, serviceName string) (*serviceIn srvStatus, err := srv.Query() if err != nil { return nil, &serviceError{ - Message: "could not query service", - Service: serviceName, - Err: err, + message: "could not query service", + service: serviceName, + err: err, } } srvCfg, err := srv.Config() if err != nil { return nil, &serviceError{ - Message: "could not get config of service", - Service: serviceName, - Err: err, + message: "could not get config of service", + service: serviceName, + err: err, } } @@ -240,6 +191,54 @@ func collectServiceInfo(scmgr WinServiceManager, serviceName string) (*serviceIn return serviceInfo, nil } +type serviceError struct { + message string + service string + err error +} + +func (e *serviceError) Error() string { + return fmt.Sprintf("%s: %q: %v", e.message, e.service, e.err) +} + +// winSvcMgr is wrapper for mgr.Mgr implementing winServiceManager interface +type winSvcMgr struct { + realMgr *mgr.Mgr +} + +func (m *winSvcMgr) disconnect() error { + return m.realMgr.Disconnect() +} + +func (m *winSvcMgr) openService(name string) (winService, error) { + serviceName, err := syscall.UTF16PtrFromString(name) + if err != nil { + return nil, fmt.Errorf("cannot convert service name %q: %w", name, err) + } + h, err := windows.OpenService(m.realMgr.Handle, serviceName, windows.GENERIC_READ) + if err != nil { + return nil, err + } + return &mgr.Service{Name: name, Handle: h}, nil +} + +func (m *winSvcMgr) listServices() ([]string, error) { + return m.realMgr.ListServices() +} + +// mgProvider is an implementation of WinServiceManagerProvider interface returning winSvcMgr +type mgProvider struct { +} + +func (*mgProvider) connect() (winServiceManager, error) { + h, err := windows.OpenSCManager(nil, nil, windows.GENERIC_READ) + if err != nil { + return nil, err + } + scmgr := &mgr.Mgr{Handle: h} + return &winSvcMgr{scmgr}, nil +} + func init() { inputs.Add("win_services", func() telegraf.Input { return &WinServices{ diff --git a/plugins/inputs/win_services/win_services_integration_test.go b/plugins/inputs/win_services/win_services_integration_test.go index 725756ae2..8ab995126 100644 --- a/plugins/inputs/win_services/win_services_integration_test.go +++ b/plugins/inputs/win_services/win_services_integration_test.go @@ -10,31 +10,31 @@ import ( "github.com/stretchr/testify/require" ) -var InvalidServices = []string{"XYZ1@", "ZYZ@", "SDF_@#"} -var KnownServices = []string{"LanmanServer", "TermService"} +var invalidServices = []string{"XYZ1@", "ZYZ@", "SDF_@#"} +var knownServices = []string{"LanmanServer", "TermService"} func TestListIntegration(t *testing.T) { if testing.Short() { t.Skip("Skipping integration test in short mode") } provider := &mgProvider{} - scmgr, err := provider.Connect() + scmgr, err := provider.connect() require.NoError(t, err) defer func() { - err := scmgr.Disconnect() + err := scmgr.disconnect() require.NoError(t, err) }() winServices := &WinServices{ - ServiceNames: KnownServices, + ServiceNames: knownServices, } require.NoError(t, winServices.Init()) services, err := winServices.listServices(scmgr) require.NoError(t, err) require.Len(t, services, 2, "Different number of services") - require.Equal(t, services[0], KnownServices[0]) - require.Equal(t, services[1], KnownServices[1]) + require.Equal(t, services[0], knownServices[0]) + require.Equal(t, services[1], knownServices[1]) } func TestEmptyListIntegration(t *testing.T) { @@ -42,10 +42,10 @@ func TestEmptyListIntegration(t *testing.T) { t.Skip("Skipping integration test in short mode") } provider := &mgProvider{} - scmgr, err := provider.Connect() + scmgr, err := provider.connect() require.NoError(t, err) defer func() { - err := scmgr.Disconnect() + err := scmgr.disconnect() require.NoError(t, err) }() @@ -65,7 +65,7 @@ func TestGatherErrorsIntegration(t *testing.T) { } ws := &WinServices{ Log: testutil.Logger{}, - ServiceNames: InvalidServices, + ServiceNames: invalidServices, mgrProvider: &mgProvider{}, } diff --git a/plugins/inputs/win_services/win_services_notwindows.go b/plugins/inputs/win_services/win_services_notwindows.go index 858c21e3a..b7df4c19e 100644 --- a/plugins/inputs/win_services/win_services_notwindows.go +++ b/plugins/inputs/win_services/win_services_notwindows.go @@ -23,6 +23,7 @@ func (w *WinServices) Init() error { w.Log.Warn("Current platform is not supported") return nil } + func (*WinServices) Gather(telegraf.Accumulator) error { return nil } func init() { diff --git a/plugins/inputs/win_services/win_services_test.go b/plugins/inputs/win_services/win_services_test.go index 756b8bb3d..f0228beec 100644 --- a/plugins/inputs/win_services/win_services_test.go +++ b/plugins/inputs/win_services/win_services_test.go @@ -18,7 +18,7 @@ import ( // testData is DD wrapper for unit testing of WinServices type testData struct { - // collection that will be returned in ListServices if service array passed into WinServices constructor is empty + // collection that will be returned in listServices if service array passed into WinServices constructor is empty queryServiceList []string mgrConnectError error mgrListServicesError error @@ -39,23 +39,23 @@ type FakeSvcMgr struct { testData testData } -func (*FakeSvcMgr) Disconnect() error { +func (*FakeSvcMgr) disconnect() error { return nil } -func (m *FakeSvcMgr) OpenService(name string) (WinService, error) { +func (m *FakeSvcMgr) openService(name string) (winService, error) { for _, s := range m.testData.services { if s.serviceName == name { if s.serviceOpenError != nil { return nil, s.serviceOpenError } - return &FakeWinSvc{s}, nil + return &fakeWinSvc{s}, nil } } return nil, fmt.Errorf("cannot find service %q", name) } -func (m *FakeSvcMgr) ListServices() ([]string, error) { +func (m *FakeSvcMgr) listServices() ([]string, error) { if m.testData.mgrListServicesError != nil { return nil, m.testData.mgrListServicesError } @@ -66,21 +66,22 @@ type FakeMgProvider struct { testData testData } -func (m *FakeMgProvider) Connect() (WinServiceManager, error) { +func (m *FakeMgProvider) connect() (winServiceManager, error) { if m.testData.mgrConnectError != nil { return nil, m.testData.mgrConnectError } return &FakeSvcMgr{m.testData}, nil } -type FakeWinSvc struct { +type fakeWinSvc struct { testData serviceTestInfo } -func (*FakeWinSvc) Close() error { +func (*fakeWinSvc) Close() error { return nil } -func (m *FakeWinSvc) Config() (mgr.Config, error) { + +func (m *fakeWinSvc) Config() (mgr.Config, error) { if m.testData.serviceConfigError != nil { return mgr.Config{}, m.testData.serviceConfigError } @@ -98,7 +99,8 @@ func (m *FakeWinSvc) Config() (mgr.Config, error) { Description: "", }, nil } -func (m *FakeWinSvc) Query() (svc.Status, error) { + +func (m *fakeWinSvc) Query() (svc.Status, error) { if m.testData.serviceQueryError != nil { return svc.Status{}, m.testData.serviceQueryError } diff --git a/plugins/inputs/win_wmi/method.go b/plugins/inputs/win_wmi/method.go index 12ed60490..b716568b7 100644 --- a/plugins/inputs/win_wmi/method.go +++ b/plugins/inputs/win_wmi/method.go @@ -15,8 +15,7 @@ import ( "github.com/influxdata/telegraf/internal" ) -// Method struct -type Method struct { +type method struct { Namespace string `toml:"namespace"` ClassName string `toml:"class_name"` Method string `toml:"method"` @@ -30,7 +29,7 @@ type Method struct { tagFilter filter.Filter } -func (m *Method) prepare(host string, username, password config.Secret) error { +func (m *method) prepare(host string, username, password config.Secret) error { // Compile the filter f, err := filter.Compile(m.TagPropertiesInclude) if err != nil { @@ -66,7 +65,7 @@ func (m *Method) prepare(host string, username, password config.Secret) error { return nil } -func (m *Method) execute(acc telegraf.Accumulator) error { +func (m *method) execute(acc telegraf.Accumulator) error { // The only way to run WMI queries in parallel while being thread-safe is to // ensure the CoInitialize[Ex]() call is bound to its current OS thread. // Otherwise, attempting to initialize and run parallel queries across diff --git a/plugins/inputs/win_wmi/query.go b/plugins/inputs/win_wmi/query.go index 89a664951..a7c9a2655 100644 --- a/plugins/inputs/win_wmi/query.go +++ b/plugins/inputs/win_wmi/query.go @@ -17,8 +17,7 @@ import ( "github.com/influxdata/telegraf/internal" ) -// Query struct -type Query struct { +type query struct { Namespace string `toml:"namespace"` ClassName string `toml:"class_name"` Properties []string `toml:"properties"` @@ -31,7 +30,7 @@ type Query struct { tagFilter filter.Filter } -func (q *Query) prepare(host string, username, password config.Secret) error { +func (q *query) prepare(host string, username, password config.Secret) error { // Compile the filter f, err := filter.Compile(q.TagPropertiesInclude) if err != nil { @@ -74,7 +73,7 @@ func (q *Query) prepare(host string, username, password config.Secret) error { return nil } -func (q *Query) execute(acc telegraf.Accumulator) error { +func (q *query) execute(acc telegraf.Accumulator) error { // The only way to run WMI queries in parallel while being thread-safe is to // ensure the CoInitialize[Ex]() call is bound to its current OS thread. // Otherwise, attempting to initialize and run parallel queries across @@ -143,7 +142,7 @@ func (q *Query) execute(acc telegraf.Accumulator) error { return nil } -func (q *Query) extractProperties(acc telegraf.Accumulator, itemRaw *ole.VARIANT) error { +func (q *query) extractProperties(acc telegraf.Accumulator, itemRaw *ole.VARIANT) error { tags, fields := make(map[string]string), make(map[string]interface{}) if q.host != "" { diff --git a/plugins/inputs/win_wmi/win_wmi.go b/plugins/inputs/win_wmi/win_wmi.go index 77a236a34..b9f4539dc 100644 --- a/plugins/inputs/win_wmi/win_wmi.go +++ b/plugins/inputs/win_wmi/win_wmi.go @@ -16,20 +16,22 @@ import ( //go:embed sample.conf var sampleConfig string -// Wmi struct +// S_FALSE is returned by CoInitializeEx if it was already called on this thread. +const sFalse = 0x00000001 + type Wmi struct { Host string `toml:"host"` Username config.Secret `toml:"username"` Password config.Secret `toml:"password"` - Queries []Query `toml:"query"` - Methods []Method `toml:"method"` + Queries []query `toml:"query"` + Methods []method `toml:"method"` Log telegraf.Logger `toml:"-"` } -// S_FALSE is returned by CoInitializeEx if it was already called on this thread. -const sFalse = 0x00000001 +func (*Wmi) SampleConfig() string { + return sampleConfig +} -// Init function func (w *Wmi) Init() error { for i := range w.Queries { q := &w.Queries[i] @@ -48,28 +50,22 @@ func (w *Wmi) Init() error { return nil } -// SampleConfig function -func (*Wmi) SampleConfig() string { - return sampleConfig -} - -// Gather function func (w *Wmi) Gather(acc telegraf.Accumulator) error { var wg sync.WaitGroup - for _, query := range w.Queries { + for _, q := range w.Queries { wg.Add(1) - go func(q Query) { + go func(q query) { defer wg.Done() acc.AddError(q.execute(acc)) - }(query) + }(q) } - for _, method := range w.Methods { + for _, m := range w.Methods { wg.Add(1) - go func(m Method) { + go func(m method) { defer wg.Done() acc.AddError(m.execute(acc)) - }(method) + }(m) } wg.Wait() diff --git a/plugins/inputs/win_wmi/win_wmi_notwindows.go b/plugins/inputs/win_wmi/win_wmi_notwindows.go index 1e85a2fe5..240ed4e10 100644 --- a/plugins/inputs/win_wmi/win_wmi_notwindows.go +++ b/plugins/inputs/win_wmi/win_wmi_notwindows.go @@ -17,12 +17,14 @@ type Wmi struct { Log telegraf.Logger `toml:"-"` } +func (*Wmi) SampleConfig() string { return sampleConfig } + func (w *Wmi) Init() error { - w.Log.Warn("current platform is not supported") + w.Log.Warn("Current platform is not supported") return nil } -func (*Wmi) SampleConfig() string { return sampleConfig } -func (*Wmi) Gather(_ telegraf.Accumulator) error { return nil } + +func (*Wmi) Gather(telegraf.Accumulator) error { return nil } func init() { inputs.Add("win_wmi", func() telegraf.Input { return &Wmi{} }) diff --git a/plugins/inputs/win_wmi/win_wmi_test.go b/plugins/inputs/win_wmi/win_wmi_test.go index a5222e777..56469bf0e 100644 --- a/plugins/inputs/win_wmi/win_wmi_test.go +++ b/plugins/inputs/win_wmi/win_wmi_test.go @@ -19,7 +19,7 @@ var sysDrive = os.Getenv("SystemDrive") + `\` // C:\ func TestBuildWqlStatements(t *testing.T) { plugin := &Wmi{ - Queries: []Query{ + Queries: []query{ { Namespace: "ROOT\\cimv2", ClassName: "Win32_Volume", @@ -53,7 +53,7 @@ func TestQueryIntegration(t *testing.T) { } plugin := &Wmi{ - Queries: []Query{ + Queries: []query{ { Namespace: "ROOT\\cimv2", ClassName: "Win32_Volume", @@ -84,7 +84,7 @@ func TestMethodIntegration(t *testing.T) { } plugin := &Wmi{ - Methods: []Method{ + Methods: []method{ { Namespace: "ROOT\\default", ClassName: "StdRegProv",