Fix multiple plugin loading in win_perf_counters (#2800)

This commit is contained in:
Steven Burgart 2017-05-22 14:58:00 -04:00 committed by Daniel Nelson
parent 8fdc2aec80
commit 9ab688d62c
1 changed files with 13 additions and 61 deletions

View File

@ -65,18 +65,13 @@ var sampleConfig = `
Measurement = "win_mem" Measurement = "win_mem"
` `
// Valid queries end up in this map.
var gItemList = make(map[int]*item)
var configParsed bool
var testConfigParsed bool
var testObject string
type Win_PerfCounters struct { type Win_PerfCounters struct {
PrintValid bool PrintValid bool
TestName string
PreVistaSupport bool PreVistaSupport bool
Object []perfobject Object []perfobject
configParsed bool
itemCache []*item
} }
type perfobject struct { type perfobject struct {
@ -89,12 +84,6 @@ type perfobject struct {
IncludeTotal bool IncludeTotal bool
} }
// Parsed configuration ends up here after it has been validated for valid
// Performance Counter paths
type itemList struct {
items map[int]*item
}
type item struct { type item struct {
query string query string
objectName string objectName string
@ -109,7 +98,7 @@ type item struct {
var sanitizedChars = strings.NewReplacer("/sec", "_persec", "/Sec", "_persec", var sanitizedChars = strings.NewReplacer("/sec", "_persec", "/Sec", "_persec",
" ", "_", "%", "Percent", `\`, "") " ", "_", "%", "Percent", `\`, "")
func (m *Win_PerfCounters) AddItem(metrics *itemList, query string, objectName string, counter string, instance string, func (m *Win_PerfCounters) AddItem(query string, objectName string, counter string, instance string,
measurement string, include_total bool) error { measurement string, include_total bool) error {
var handle PDH_HQUERY var handle PDH_HQUERY
@ -128,15 +117,10 @@ func (m *Win_PerfCounters) AddItem(metrics *itemList, query string, objectName s
return errors.New(PdhFormatError(ret)) return errors.New(PdhFormatError(ret))
} }
temp := &item{query, objectName, counter, instance, measurement, newItem := &item{query, objectName, counter, instance, measurement,
include_total, handle, counterHandle} include_total, handle, counterHandle}
index := len(gItemList) m.itemCache = append(m.itemCache, newItem)
gItemList[index] = temp
if metrics.items == nil {
metrics.items = make(map[int]*item)
}
metrics.items[index] = temp
return nil return nil
} }
@ -148,11 +132,9 @@ func (m *Win_PerfCounters) SampleConfig() string {
return sampleConfig return sampleConfig
} }
func (m *Win_PerfCounters) ParseConfig(metrics *itemList) error { func (m *Win_PerfCounters) ParseConfig() error {
var query string var query string
configParsed = true
if len(m.Object) > 0 { if len(m.Object) > 0 {
for _, PerfObject := range m.Object { for _, PerfObject := range m.Object {
for _, counter := range PerfObject.Counters { for _, counter := range PerfObject.Counters {
@ -165,7 +147,7 @@ func (m *Win_PerfCounters) ParseConfig(metrics *itemList) error {
query = "\\" + objectname + "(" + instance + ")\\" + counter query = "\\" + objectname + "(" + instance + ")\\" + counter
} }
err := m.AddItem(metrics, query, objectname, counter, instance, err := m.AddItem(query, objectname, counter, instance,
PerfObject.Measurement, PerfObject.IncludeTotal) PerfObject.Measurement, PerfObject.IncludeTotal)
if err == nil { if err == nil {
@ -191,41 +173,11 @@ func (m *Win_PerfCounters) ParseConfig(metrics *itemList) error {
} }
} }
func (m *Win_PerfCounters) Cleanup(metrics *itemList) {
// Cleanup
for _, metric := range metrics.items {
ret := PdhCloseQuery(metric.handle)
_ = ret
}
}
func (m *Win_PerfCounters) CleanupTestMode() {
// Cleanup for the testmode.
for _, metric := range gItemList {
ret := PdhCloseQuery(metric.handle)
_ = ret
}
}
func (m *Win_PerfCounters) Gather(acc telegraf.Accumulator) error { func (m *Win_PerfCounters) Gather(acc telegraf.Accumulator) error {
metrics := itemList{} // Parse the config once
if !m.configParsed {
// Both values are empty in normal use. err := m.ParseConfig()
if m.TestName != testObject { m.configParsed = true
// Cleanup any handles before emptying the global variable containing valid queries.
m.CleanupTestMode()
gItemList = make(map[int]*item)
testObject = m.TestName
testConfigParsed = true
configParsed = false
}
// We only need to parse the config during the init, it uses the global variable after.
if configParsed == false {
err := m.ParseConfig(&metrics)
if err != nil { if err != nil {
return err return err
} }
@ -237,7 +189,7 @@ func (m *Win_PerfCounters) Gather(acc telegraf.Accumulator) error {
var emptyBuf [1]PDH_FMT_COUNTERVALUE_ITEM_DOUBLE // need at least 1 addressable null ptr. 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 iterate over the known metrics and get the samples.
for _, metric := range gItemList { for _, metric := range m.itemCache {
// collect // collect
ret := PdhCollectQueryData(metric.handle) ret := PdhCollectQueryData(metric.handle)
if ret == ERROR_SUCCESS { if ret == ERROR_SUCCESS {