From ca31aaad85c267ac6ae20a8217d4c81333e232d2 Mon Sep 17 00:00:00 2001 From: Jeff Ashton Date: Wed, 9 Nov 2016 13:43:39 -0500 Subject: [PATCH] Importing pdh from github.com/lxn/win closes #1763 closes #2017 --- CHANGELOG.md | 1 + Godeps_windows | 1 - plugins/inputs/win_perf_counters/pdh.go | 419 ++++++++++++++++++ .../win_perf_counters/win_perf_counters.go | 45 +- 4 files changed, 442 insertions(+), 24 deletions(-) create mode 100644 plugins/inputs/win_perf_counters/pdh.go diff --git a/CHANGELOG.md b/CHANGELOG.md index d53e46093..e69a1004e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ in their config file. - [#2078](https://github.com/influxdata/telegraf/pull/2078): Ping input: add standard deviation field. - [#2121](https://github.com/influxdata/telegraf/pull/2121): Add GC pause metric to InfluxDB input plugin. - [#2006](https://github.com/influxdata/telegraf/pull/2006): Added response_timeout property to prometheus input plugin. +- [#1763](https://github.com/influxdata/telegraf/issues/1763): Pulling github.com/lxn/win's pdh wrapper into telegraf ### Bugfixes diff --git a/Godeps_windows b/Godeps_windows index 067c98c1c..129fce1a2 100644 --- a/Godeps_windows +++ b/Godeps_windows @@ -1,7 +1,6 @@ github.com/Microsoft/go-winio ce2922f643c8fd76b46cadc7f404a06282678b34 github.com/StackExchange/wmi f3e2bae1e0cb5aef83e319133eabfee30013a4a5 github.com/go-ole/go-ole be49f7c07711fcb603cff39e1de7c67926dc0ba7 -github.com/lxn/win 950a0e81e7678e63d8e6cd32412bdecb325ccd88 github.com/shirou/w32 3c9377fc6748f222729a8270fe2775d149a249ad golang.org/x/sys a646d33e2ee3172a661fc09bca23bb4889a41bc8 github.com/go-ini/ini 9144852efba7c4daf409943ee90767da62d55438 diff --git a/plugins/inputs/win_perf_counters/pdh.go b/plugins/inputs/win_perf_counters/pdh.go new file mode 100644 index 000000000..36563d6b7 --- /dev/null +++ b/plugins/inputs/win_perf_counters/pdh.go @@ -0,0 +1,419 @@ +// Copyright (c) 2010 The win Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. The names of the authors may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// This is the official list of 'win' authors for copyright purposes. +// +// Alexander Neumann +// Joseph Watson +// Kevin Pors + +// +build windows + +package win_perf_counters + +import ( + "syscall" + "unsafe" +) + +// Error codes +const ( + ERROR_SUCCESS = 0 + ERROR_INVALID_FUNCTION = 1 +) + +type ( + HANDLE uintptr +) + +// PDH error codes, which can be returned by all Pdh* functions. Taken from mingw-w64 pdhmsg.h +const ( + PDH_CSTATUS_VALID_DATA = 0x00000000 // The returned data is valid. + PDH_CSTATUS_NEW_DATA = 0x00000001 // The return data value is valid and different from the last sample. + PDH_CSTATUS_NO_MACHINE = 0x800007D0 // Unable to connect to the specified computer, or the computer is offline. + PDH_CSTATUS_NO_INSTANCE = 0x800007D1 + PDH_MORE_DATA = 0x800007D2 // The PdhGetFormattedCounterArray* function can return this if there's 'more data to be displayed'. + PDH_CSTATUS_ITEM_NOT_VALIDATED = 0x800007D3 + PDH_RETRY = 0x800007D4 + PDH_NO_DATA = 0x800007D5 // The query does not currently contain any counters (for example, limited access) + PDH_CALC_NEGATIVE_DENOMINATOR = 0x800007D6 + PDH_CALC_NEGATIVE_TIMEBASE = 0x800007D7 + PDH_CALC_NEGATIVE_VALUE = 0x800007D8 + PDH_DIALOG_CANCELLED = 0x800007D9 + PDH_END_OF_LOG_FILE = 0x800007DA + PDH_ASYNC_QUERY_TIMEOUT = 0x800007DB + PDH_CANNOT_SET_DEFAULT_REALTIME_DATASOURCE = 0x800007DC + PDH_CSTATUS_NO_OBJECT = 0xC0000BB8 + PDH_CSTATUS_NO_COUNTER = 0xC0000BB9 // The specified counter could not be found. + PDH_CSTATUS_INVALID_DATA = 0xC0000BBA // The counter was successfully found, but the data returned is not valid. + PDH_MEMORY_ALLOCATION_FAILURE = 0xC0000BBB + PDH_INVALID_HANDLE = 0xC0000BBC + PDH_INVALID_ARGUMENT = 0xC0000BBD // Required argument is missing or incorrect. + PDH_FUNCTION_NOT_FOUND = 0xC0000BBE + PDH_CSTATUS_NO_COUNTERNAME = 0xC0000BBF + PDH_CSTATUS_BAD_COUNTERNAME = 0xC0000BC0 // Unable to parse the counter path. Check the format and syntax of the specified path. + PDH_INVALID_BUFFER = 0xC0000BC1 + PDH_INSUFFICIENT_BUFFER = 0xC0000BC2 + PDH_CANNOT_CONNECT_MACHINE = 0xC0000BC3 + PDH_INVALID_PATH = 0xC0000BC4 + PDH_INVALID_INSTANCE = 0xC0000BC5 + PDH_INVALID_DATA = 0xC0000BC6 // specified counter does not contain valid data or a successful status code. + PDH_NO_DIALOG_DATA = 0xC0000BC7 + PDH_CANNOT_READ_NAME_STRINGS = 0xC0000BC8 + PDH_LOG_FILE_CREATE_ERROR = 0xC0000BC9 + PDH_LOG_FILE_OPEN_ERROR = 0xC0000BCA + PDH_LOG_TYPE_NOT_FOUND = 0xC0000BCB + PDH_NO_MORE_DATA = 0xC0000BCC + PDH_ENTRY_NOT_IN_LOG_FILE = 0xC0000BCD + PDH_DATA_SOURCE_IS_LOG_FILE = 0xC0000BCE + PDH_DATA_SOURCE_IS_REAL_TIME = 0xC0000BCF + PDH_UNABLE_READ_LOG_HEADER = 0xC0000BD0 + PDH_FILE_NOT_FOUND = 0xC0000BD1 + PDH_FILE_ALREADY_EXISTS = 0xC0000BD2 + PDH_NOT_IMPLEMENTED = 0xC0000BD3 + PDH_STRING_NOT_FOUND = 0xC0000BD4 + PDH_UNABLE_MAP_NAME_FILES = 0x80000BD5 + PDH_UNKNOWN_LOG_FORMAT = 0xC0000BD6 + PDH_UNKNOWN_LOGSVC_COMMAND = 0xC0000BD7 + PDH_LOGSVC_QUERY_NOT_FOUND = 0xC0000BD8 + PDH_LOGSVC_NOT_OPENED = 0xC0000BD9 + PDH_WBEM_ERROR = 0xC0000BDA + PDH_ACCESS_DENIED = 0xC0000BDB + PDH_LOG_FILE_TOO_SMALL = 0xC0000BDC + PDH_INVALID_DATASOURCE = 0xC0000BDD + PDH_INVALID_SQLDB = 0xC0000BDE + PDH_NO_COUNTERS = 0xC0000BDF + PDH_SQL_ALLOC_FAILED = 0xC0000BE0 + PDH_SQL_ALLOCCON_FAILED = 0xC0000BE1 + PDH_SQL_EXEC_DIRECT_FAILED = 0xC0000BE2 + PDH_SQL_FETCH_FAILED = 0xC0000BE3 + PDH_SQL_ROWCOUNT_FAILED = 0xC0000BE4 + PDH_SQL_MORE_RESULTS_FAILED = 0xC0000BE5 + PDH_SQL_CONNECT_FAILED = 0xC0000BE6 + PDH_SQL_BIND_FAILED = 0xC0000BE7 + PDH_CANNOT_CONNECT_WMI_SERVER = 0xC0000BE8 + PDH_PLA_COLLECTION_ALREADY_RUNNING = 0xC0000BE9 + PDH_PLA_ERROR_SCHEDULE_OVERLAP = 0xC0000BEA + PDH_PLA_COLLECTION_NOT_FOUND = 0xC0000BEB + PDH_PLA_ERROR_SCHEDULE_ELAPSED = 0xC0000BEC + PDH_PLA_ERROR_NOSTART = 0xC0000BED + PDH_PLA_ERROR_ALREADY_EXISTS = 0xC0000BEE + PDH_PLA_ERROR_TYPE_MISMATCH = 0xC0000BEF + PDH_PLA_ERROR_FILEPATH = 0xC0000BF0 + PDH_PLA_SERVICE_ERROR = 0xC0000BF1 + PDH_PLA_VALIDATION_ERROR = 0xC0000BF2 + PDH_PLA_VALIDATION_WARNING = 0x80000BF3 + PDH_PLA_ERROR_NAME_TOO_LONG = 0xC0000BF4 + PDH_INVALID_SQL_LOG_FORMAT = 0xC0000BF5 + PDH_COUNTER_ALREADY_IN_QUERY = 0xC0000BF6 + PDH_BINARY_LOG_CORRUPT = 0xC0000BF7 + PDH_LOG_SAMPLE_TOO_SMALL = 0xC0000BF8 + PDH_OS_LATER_VERSION = 0xC0000BF9 + PDH_OS_EARLIER_VERSION = 0xC0000BFA + PDH_INCORRECT_APPEND_TIME = 0xC0000BFB + PDH_UNMATCHED_APPEND_COUNTER = 0xC0000BFC + PDH_SQL_ALTER_DETAIL_FAILED = 0xC0000BFD + PDH_QUERY_PERF_DATA_TIMEOUT = 0xC0000BFE +) + +// Formatting options for GetFormattedCounterValue(). +const ( + PDH_FMT_RAW = 0x00000010 + PDH_FMT_ANSI = 0x00000020 + PDH_FMT_UNICODE = 0x00000040 + PDH_FMT_LONG = 0x00000100 // Return data as a long int. + PDH_FMT_DOUBLE = 0x00000200 // Return data as a double precision floating point real. + PDH_FMT_LARGE = 0x00000400 // Return data as a 64 bit integer. + PDH_FMT_NOSCALE = 0x00001000 // can be OR-ed: Do not apply the counter's default scaling factor. + PDH_FMT_1000 = 0x00002000 // can be OR-ed: multiply the actual value by 1,000. + PDH_FMT_NODATA = 0x00004000 // can be OR-ed: unknown what this is for, MSDN says nothing. + PDH_FMT_NOCAP100 = 0x00008000 // can be OR-ed: do not cap values > 100. + PERF_DETAIL_COSTLY = 0x00010000 + PERF_DETAIL_STANDARD = 0x0000FFFF +) + +type ( + PDH_HQUERY HANDLE // query handle + PDH_HCOUNTER HANDLE // counter handle +) + +// Union specialization for double values +type PDH_FMT_COUNTERVALUE_DOUBLE struct { + CStatus uint32 + DoubleValue float64 +} + +// Union specialization for 64 bit integer values +type PDH_FMT_COUNTERVALUE_LARGE struct { + CStatus uint32 + LargeValue int64 +} + +// Union specialization for long values +type PDH_FMT_COUNTERVALUE_LONG struct { + CStatus uint32 + LongValue int32 + padding [4]byte +} + +// Union specialization for double values, used by PdhGetFormattedCounterArrayDouble() +type PDH_FMT_COUNTERVALUE_ITEM_DOUBLE struct { + SzName *uint16 // pointer to a string + FmtValue PDH_FMT_COUNTERVALUE_DOUBLE +} + +// Union specialization for 'large' values, used by PdhGetFormattedCounterArrayLarge() +type PDH_FMT_COUNTERVALUE_ITEM_LARGE struct { + SzName *uint16 // pointer to a string + FmtValue PDH_FMT_COUNTERVALUE_LARGE +} + +// Union specialization for long values, used by PdhGetFormattedCounterArrayLong() +type PDH_FMT_COUNTERVALUE_ITEM_LONG struct { + SzName *uint16 // pointer to a string + FmtValue PDH_FMT_COUNTERVALUE_LONG +} + +var ( + // Library + libpdhDll *syscall.DLL + + // Functions + pdh_AddCounterW *syscall.Proc + pdh_AddEnglishCounterW *syscall.Proc + pdh_CloseQuery *syscall.Proc + pdh_CollectQueryData *syscall.Proc + pdh_GetFormattedCounterValue *syscall.Proc + pdh_GetFormattedCounterArrayW *syscall.Proc + pdh_OpenQuery *syscall.Proc + pdh_ValidatePathW *syscall.Proc +) + +func init() { + // Library + libpdhDll = syscall.MustLoadDLL("pdh.dll") + + // Functions + pdh_AddCounterW = libpdhDll.MustFindProc("PdhAddCounterW") + pdh_AddEnglishCounterW, _ = libpdhDll.FindProc("PdhAddEnglishCounterW") // XXX: only supported on versions > Vista. + pdh_CloseQuery = libpdhDll.MustFindProc("PdhCloseQuery") + pdh_CollectQueryData = libpdhDll.MustFindProc("PdhCollectQueryData") + pdh_GetFormattedCounterValue = libpdhDll.MustFindProc("PdhGetFormattedCounterValue") + pdh_GetFormattedCounterArrayW = libpdhDll.MustFindProc("PdhGetFormattedCounterArrayW") + pdh_OpenQuery = libpdhDll.MustFindProc("PdhOpenQuery") + pdh_ValidatePathW = libpdhDll.MustFindProc("PdhValidatePathW") +} + +// 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 PDH_COUNTER_INFO structure. +// +// Examples of szFullCounterPath (in an English version of Windows): +// +// \\Processor(_Total)\\% Idle Time +// \\Processor(_Total)\\% Processor Time +// \\LogicalDisk(C:)\% Free Space +// +// To view all (internationalized...) counters on a system, there are three non-programmatic ways: perfmon utility, +// the typeperf command, and the the registry editor. perfmon.exe is perhaps the easiest way, because it's basically a +// full implemention of the pdh.dll API, except with a GUI and all that. The registry setting also provides an +// interface to the available counters, and can be found at the following key: +// +// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage +// +// This registry key contains several values as follows: +// +// 1 +// 1847 +// 2 +// System +// 4 +// Memory +// 6 +// % Processor Time +// ... many, many more +// +// Somehow, these numeric values can be used as szFullCounterPath too: +// +// \2\6 will correspond to \\System\% Processor Time +// +// The typeperf command may also be pretty easy. To find all performance counters, simply execute: +// +// typeperf -qx +func PdhAddCounter(hQuery PDH_HQUERY, szFullCounterPath string, dwUserData uintptr, phCounter *PDH_HCOUNTER) uint32 { + ptxt, _ := syscall.UTF16PtrFromString(szFullCounterPath) + ret, _, _ := pdh_AddCounterW.Call( + uintptr(hQuery), + uintptr(unsafe.Pointer(ptxt)), + dwUserData, + uintptr(unsafe.Pointer(phCounter))) + + return uint32(ret) +} + +// 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 PDH_HQUERY, szFullCounterPath string, dwUserData uintptr, phCounter *PDH_HCOUNTER) uint32 { + if pdh_AddEnglishCounterW == nil { + return ERROR_INVALID_FUNCTION + } + + ptxt, _ := syscall.UTF16PtrFromString(szFullCounterPath) + ret, _, _ := pdh_AddEnglishCounterW.Call( + uintptr(hQuery), + uintptr(unsafe.Pointer(ptxt)), + dwUserData, + uintptr(unsafe.Pointer(phCounter))) + + return uint32(ret) +} + +// 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 PDH_HQUERY) uint32 { + ret, _, _ := pdh_CloseQuery.Call(uintptr(hQuery)) + + return uint32(ret) +} + +// 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) +// var derp win.PDH_FMT_COUNTERVALUE_DOUBLE +// +// 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.PdhCollectQueryData(handle) +// fmt.Printf("Collect return code is %x\n", ret) // return code will be ERROR_SUCCESS +// ret = win.PdhGetFormattedCounterValueDouble(counterHandle, 0, &derp) +// +// 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 PDH_HQUERY) uint32 { + ret, _, _ := pdh_CollectQueryData.Call(uintptr(hQuery)) + + return uint32(ret) +} + +// 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 PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_FMT_COUNTERVALUE_DOUBLE) uint32 { + ret, _, _ := pdh_GetFormattedCounterValue.Call( + uintptr(hCounter), + uintptr(PDH_FMT_DOUBLE), + uintptr(unsafe.Pointer(lpdwType)), + uintptr(unsafe.Pointer(pValue))) + + return uint32(ret) +} + +// 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 PDH_FMT_COUNTERVALUE_ITEM_DOUBLE. +// An example of how this function can be used: +// +// okPath := "\\Process(*)\\% Processor Time" // notice the wildcard * character +// +// // ommitted all necessary stuff ... +// +// var bufSize uint32 +// var bufCount uint32 +// var size uint32 = uint32(unsafe.Sizeof(win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE{})) +// var emptyBuf [1]win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE // need at least 1 addressable null ptr. +// +// for { +// // collect +// ret := win.PdhCollectQueryData(queryHandle) +// if ret == win.ERROR_SUCCESS { +// 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]) +// for i := 0; i < int(bufCount); i++ { +// c := filledBuf[i] +// var s string = win.UTF16PtrToString(c.SzName) +// fmt.Printf("Index %d -> %s, value %v\n", i, s, c.FmtValue.DoubleValue) +// } +// +// filledBuf = nil +// // Need to at least set bufSize to zero, because if not, the function will not +// // return PDH_MORE_DATA and will not set the bufSize. +// bufCount = 0 +// bufSize = 0 +// } +// +// time.Sleep(2000 * time.Millisecond) +// } +// } +func PdhGetFormattedCounterArrayDouble(hCounter PDH_HCOUNTER, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *PDH_FMT_COUNTERVALUE_ITEM_DOUBLE) uint32 { + ret, _, _ := pdh_GetFormattedCounterArrayW.Call( + uintptr(hCounter), + uintptr(PDH_FMT_DOUBLE), + uintptr(unsafe.Pointer(lpdwBufferSize)), + uintptr(unsafe.Pointer(lpdwBufferCount)), + uintptr(unsafe.Pointer(itemBuffer))) + + return uint32(ret) +} + +// 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 PDH_COUNTER_INFO structure. phQuery is +// the handle to the query, and must be used in subsequent calls. This function returns a PDH_ +// constant error code, or ERROR_SUCCESS if the call succeeded. +func PdhOpenQuery(szDataSource uintptr, dwUserData uintptr, phQuery *PDH_HQUERY) uint32 { + ret, _, _ := pdh_OpenQuery.Call( + szDataSource, + dwUserData, + uintptr(unsafe.Pointer(phQuery))) + + return uint32(ret) +} + +// Validates a path. Will return ERROR_SUCCESS when ok, or PDH_CSTATUS_BAD_COUNTERNAME when the path is +// erroneous. +func PdhValidatePath(path string) uint32 { + ptxt, _ := syscall.UTF16PtrFromString(path) + ret, _, _ := pdh_ValidatePathW.Call(uintptr(unsafe.Pointer(ptxt))) + + return uint32(ret) +} + +func UTF16PtrToString(s *uint16) string { + if s == nil { + return "" + } + return syscall.UTF16ToString((*[1 << 29]uint16)(unsafe.Pointer(s))[0:]) +} diff --git a/plugins/inputs/win_perf_counters/win_perf_counters.go b/plugins/inputs/win_perf_counters/win_perf_counters.go index 1f233a3d4..691f67a01 100644 --- a/plugins/inputs/win_perf_counters/win_perf_counters.go +++ b/plugins/inputs/win_perf_counters/win_perf_counters.go @@ -10,7 +10,6 @@ import ( "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/inputs" - "github.com/lxn/win" ) var sampleConfig string = ` @@ -103,8 +102,8 @@ type item struct { instance string measurement string include_total bool - handle win.PDH_HQUERY - counterHandle win.PDH_HCOUNTER + handle PDH_HQUERY + counterHandle PDH_HCOUNTER } var sanitizedChars = strings.NewReplacer("/sec", "_persec", "/Sec", "_persec", @@ -113,10 +112,10 @@ var sanitizedChars = strings.NewReplacer("/sec", "_persec", "/Sec", "_persec", func (m *Win_PerfCounters) AddItem(metrics *itemList, query string, objectName string, counter string, instance string, measurement string, include_total bool) { - var handle win.PDH_HQUERY - var counterHandle win.PDH_HCOUNTER - ret := win.PdhOpenQuery(0, 0, &handle) - ret = win.PdhAddCounter(handle, query, 0, &counterHandle) + var handle PDH_HQUERY + var counterHandle PDH_HCOUNTER + ret := PdhOpenQuery(0, 0, &handle) + ret = PdhAddCounter(handle, query, 0, &counterHandle) _ = ret temp := &item{query, objectName, counter, instance, measurement, @@ -131,14 +130,14 @@ func (m *Win_PerfCounters) AddItem(metrics *itemList, query string, objectName s } func (m *Win_PerfCounters) InvalidObject(exists uint32, query string, PerfObject perfobject, instance string, counter string) error { - if exists == 3221228472 { // win.PDH_CSTATUS_NO_OBJECT + if exists == 3221228472 { // PDH_CSTATUS_NO_OBJECT if PerfObject.FailOnMissing { err := errors.New("Performance object does not exist") return err } else { fmt.Printf("Performance Object '%s' does not exist in query: %s\n", PerfObject.ObjectName, query) } - } else if exists == 3221228473 { //win.PDH_CSTATUS_NO_COUNTER + } else if exists == 3221228473 { // PDH_CSTATUS_NO_COUNTER if PerfObject.FailOnMissing { err := errors.New("Counter in Performance object does not exist") @@ -146,7 +145,7 @@ func (m *Win_PerfCounters) InvalidObject(exists uint32, query string, PerfObject } else { fmt.Printf("Counter '%s' does not exist in query: %s\n", counter, query) } - } else if exists == 2147485649 { //win.PDH_CSTATUS_NO_INSTANCE + } else if exists == 2147485649 { // PDH_CSTATUS_NO_INSTANCE if PerfObject.FailOnMissing { err := errors.New("Instance in Performance object does not exist") return err @@ -189,9 +188,9 @@ func (m *Win_PerfCounters) ParseConfig(metrics *itemList) error { query = "\\" + objectname + "(" + instance + ")\\" + counter } - var exists uint32 = win.PdhValidatePath(query) + var exists uint32 = PdhValidatePath(query) - if exists == win.ERROR_SUCCESS { + if exists == ERROR_SUCCESS { if m.PrintValid { fmt.Printf("Valid: %s\n", query) } @@ -218,7 +217,7 @@ func (m *Win_PerfCounters) Cleanup(metrics *itemList) { // Cleanup for _, metric := range metrics.items { - ret := win.PdhCloseQuery(metric.handle) + ret := PdhCloseQuery(metric.handle) _ = ret } } @@ -227,7 +226,7 @@ func (m *Win_PerfCounters) CleanupTestMode() { // Cleanup for the testmode. for _, metric := range gItemList { - ret := win.PdhCloseQuery(metric.handle) + ret := PdhCloseQuery(metric.handle) _ = ret } } @@ -256,26 +255,26 @@ func (m *Win_PerfCounters) Gather(acc telegraf.Accumulator) error { var bufSize uint32 var bufCount uint32 - var size uint32 = uint32(unsafe.Sizeof(win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE{})) - var emptyBuf [1]win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE // need at least 1 addressable null ptr. + var size uint32 = uint32(unsafe.Sizeof(PDH_FMT_COUNTERVALUE_ITEM_DOUBLE{})) + var emptyBuf [1]PDH_FMT_COUNTERVALUE_ITEM_DOUBLE // need at least 1 addressable null ptr. // For iterate over the known metrics and get the samples. for _, metric := range gItemList { // collect - ret := win.PdhCollectQueryData(metric.handle) - if ret == win.ERROR_SUCCESS { - ret = win.PdhGetFormattedCounterArrayDouble(metric.counterHandle, &bufSize, + ret := PdhCollectQueryData(metric.handle) + if ret == ERROR_SUCCESS { + ret = PdhGetFormattedCounterArrayDouble(metric.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) + if ret == PDH_MORE_DATA { + filledBuf := make([]PDH_FMT_COUNTERVALUE_ITEM_DOUBLE, bufCount*size) if len(filledBuf) == 0 { continue } - ret = win.PdhGetFormattedCounterArrayDouble(metric.counterHandle, + ret = PdhGetFormattedCounterArrayDouble(metric.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 = UTF16PtrToString(c.SzName) var add bool