New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New module windows for metricbeat #3758
Changes from 4 commits
43ee390
569e7f4
a02bdc9
331a56f
30a1966
d287fa9
7e6b88c
9047b36
8ab1da4
793bc1b
24aa90d
6c01c1b
251bc9c
f670912
267bf17
88b0a79
6cadedf
dd2b539
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
- module: windows | ||
metricsets: ["perfmon"] | ||
enabled: true | ||
period: 1s | ||
counters: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For metricset specific configs we (recently) created the convention to have it under a namespace. Means here it would be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In source i then have to write this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes |
||
- group: "processor" | ||
collectors: | ||
- alias: "processor_perfomance" | ||
query: "\\Processor Information(_Total)\\% Processor Performance" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you use single quotes here, can the double backslashes be replaced with a single backslash? I would prefer that, unless of course using double backslashes is common in the perfmon world. |
||
- group: "disk" | ||
collectors: | ||
- alias: "bytes_written" | ||
query: "\\FileSystem Disk Activity(_Total)\\FileSystem Bytes Written" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
== windows Module | ||
|
||
This is the windows Module. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
- key: windows | ||
title: "Windows" | ||
description: > | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please mark this as beta: https://github.com/elastic/beats/blob/master/metricbeat/module/jolokia/_meta/fields.yml#L4 |
||
Module for Windows | ||
fields: | ||
- name: windows | ||
type: group | ||
description: > | ||
fields: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/* | ||
Package windows is a Metricbeat module that contains MetricSets. | ||
*/ | ||
package windows |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"@timestamp":"2016-05-23T08:05:34.853Z", | ||
"beat":{ | ||
"hostname":"beathost", | ||
"name":"beathost" | ||
}, | ||
"metricset":{ | ||
"host":"localhost", | ||
"module":"mysql", | ||
"name":"status", | ||
"rtt":44269 | ||
}, | ||
"windows":{ | ||
"perfmon":{ | ||
"example": "perfmon" | ||
} | ||
}, | ||
"type":"metricsets" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
=== windows perfmon MetricSet | ||
|
||
This is the perfmon metricset of the module windows. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
- name: perfmon | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For dynamic metricsets, this will change so what we nomrally do is just define windows (module) part and leave the rest empty. Check the jmx metricset as an example. |
||
type: group | ||
fields: | ||
- name: counters | ||
type: group | ||
description: > | ||
Grouping of different counters | ||
fields: | ||
- name: group | ||
type: string | ||
description: > | ||
Name of the group. For example `processor` or `disk` | ||
|
||
- name: collectors | ||
type: group | ||
fields: | ||
- name: alias | ||
type: string | ||
description: > | ||
Short form for the query | ||
|
||
- name: query | ||
type: string | ||
description: > | ||
The query. For example `\\Processor Information(_Total)\\% Processor Performance`. Backslashes have to be escaped. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// +build ignore | ||
|
||
package perfmon | ||
|
||
/* | ||
#include <windows.h> | ||
#include <stdio.h> | ||
#include <conio.h> | ||
#include <pdh.h> | ||
#include <pdhmsg.h> | ||
#cgo LDFLAGS: -lpdh | ||
*/ | ||
import "C" | ||
|
||
const ( | ||
ERROR_SUCCESS = C.ERROR_SUCCESS | ||
PDH_STATUS_VALID_DATA = C.PDH_CSTATUS_VALID_DATA | ||
PDH_STATUS_NEW_DATA = C.PDH_CSTATUS_NEW_DATA | ||
PDH_NO_DATA = C.PDH_NO_DATA | ||
PDH_STATUS_NO_OBJECT = C.PDH_CSTATUS_NO_OBJECT | ||
PDH_STATUS_NO_COUNTER = C.PDH_CSTATUS_NO_COUNTER | ||
PDH_STATUS_INVALID_DATA = C.PDH_CSTATUS_INVALID_DATA | ||
PDH_INVALID_HANDLE = C.PDH_INVALID_HANDLE | ||
PDH_INVALID_DATA = C.PDH_INVALID_DATA | ||
PDH_NO_MORE_DATA = C.PDH_NO_MORE_DATA | ||
PdhFmtDouble = C.PDH_FMT_DOUBLE | ||
PdhFmtLarge = C.PDH_FMT_LARGE | ||
PdhFmtLong = C.PDH_FMT_LONG | ||
) | ||
|
||
type PdhCounterValue C.PDH_FMT_COUNTERVALUE |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package perfmon | ||
|
||
const ( | ||
ERROR_SUCCESS = 0x0 | ||
PDH_STATUS_VALID_DATA = 0x0 | ||
PDH_STATUS_NEW_DATA = 0x1 | ||
PDH_NO_DATA = 0x800007d5 | ||
PDH_STATUS_NO_OBJECT = 0xc0000bb8 | ||
PDH_STATUS_NO_COUNTER = 0xc0000bb9 | ||
PDH_STATUS_INVALID_DATA = 0xc0000bba | ||
PDH_INVALID_HANDLE = 0xc0000bbc | ||
PDH_INVALID_DATA = 0xc0000bc6 | ||
PDH_NO_MORE_DATA = 0xc0000bcc | ||
PdhFmtDouble = 0x00000200 | ||
PdhFmtLarge = 0x00000400 | ||
PdhFmtLong = 0x00000100 | ||
) | ||
|
||
type PdhCounterValue struct { | ||
CStatus uint32 | ||
Pad_cgo_0 [4]byte | ||
LongValue int32 | ||
Pad_cgo_1 [4]byte | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package perfmon | ||
|
||
const ( | ||
ERROR_SUCCESS = 0x0 | ||
PDH_STATUS_VALID_DATA = 0x0 | ||
PDH_STATUS_NEW_DATA = 0x1 | ||
PDH_NO_DATA = 0x800007d5 | ||
PDH_STATUS_NO_OBJECT = 0xc0000bb8 | ||
PDH_STATUS_NO_COUNTER = 0xc0000bb9 | ||
PDH_STATUS_INVALID_DATA = 0xc0000bba | ||
PDH_INVALID_HANDLE = 0xc0000bbc | ||
PDH_INVALID_DATA = 0xc0000bc6 | ||
PDH_NO_MORE_DATA = 0xc0000bcc | ||
PdhFmtDouble = 0x00000200 | ||
PdhFmtLarge = 0x00000400 | ||
PdhFmtLong = 0x00000100 | ||
) | ||
|
||
type PdhCounterValue struct { | ||
CStatus uint32 | ||
Pad_cgo_0 [4]byte | ||
LongValue int32 | ||
Pad_cgo_1 [4]byte | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package perfmon | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use |
||
|
||
import ( | ||
"unsafe" | ||
|
||
"github.com/elastic/beats/libbeat/common" | ||
) | ||
|
||
type Handle struct { | ||
Status error | ||
Query uintptr | ||
CounterType int | ||
Counters []CounterGroup | ||
} | ||
|
||
type CounterGroup struct { | ||
GroupName string | ||
Counters []Counter | ||
} | ||
|
||
type Counter struct { | ||
CounterName string | ||
Counter uintptr | ||
CounterPath string | ||
DisplayValue PdhCounterValue | ||
} | ||
|
||
func getHandle(config []CounterConfig) (*Handle, int) { | ||
q := &Handle{} | ||
err := _PdhOpenQuery(0, 0, &q.Query) | ||
if err != ERROR_SUCCESS { | ||
return nil, err | ||
} | ||
|
||
counterGroups := make([]CounterGroup, len(config)) | ||
q.Counters = counterGroups | ||
|
||
for i, v := range config { | ||
counterGroups[i] = CounterGroup{GroupName: v.Name, Counters: make([]Counter, len(v.Group))} | ||
for j, v1 := range v.Group { | ||
counterGroups[i].Counters[j] = Counter{CounterName: v1.Alias, CounterPath: v1.Query} | ||
err := _PdhAddCounter(q.Query, counterGroups[i].Counters[j].CounterPath, 0, &counterGroups[i].Counters[j].Counter) | ||
if err != ERROR_SUCCESS { | ||
return q, err | ||
} | ||
} | ||
} | ||
|
||
return q, 0 | ||
} | ||
|
||
func (q *Handle) readData() (common.MapStr, int) { | ||
|
||
err := _PdhCollectQueryData(q.Query) | ||
|
||
if err != ERROR_SUCCESS { | ||
return nil, err | ||
} | ||
|
||
result := common.MapStr{} | ||
|
||
for _, v := range q.Counters { | ||
groupVal := make(map[string]interface{}) | ||
for _, v1 := range v.Counters { | ||
err := _PdhGetFormattedCounterValue(v1.Counter, PdhFmtDouble, q.CounterType, &v1.DisplayValue) | ||
if err != ERROR_SUCCESS { | ||
return nil, err | ||
} | ||
doubleValue := (*float64)(unsafe.Pointer(&v1.DisplayValue.LongValue)) | ||
groupVal[v1.CounterName] = *doubleValue | ||
|
||
} | ||
result[v.GroupName] = groupVal | ||
} | ||
return result, 0 | ||
} | ||
|
||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output pdh_windows.go pdh.go | ||
// Windows API calls | ||
//sys _PdhOpenQuery(dataSource uintptr, userData uintptr, query *uintptr) (err int) = pdh.PdhOpenQuery | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I recommend changing the method signature of all these functions to return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have change the signature to func _PdhOpenQuery(dataSource uintptr, userData uintptr, query *uintptr) (err error) {
r1, _, e1 := syscall.Syscall(procPdhOpenQuery.Addr(), 3, uintptr(dataSource), uintptr(userData), uintptr(unsafe.Pointer(query)))
if r1 == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
} Now i always get There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
//sys _PdhAddCounter(query uintptr, counterPath string, userData uintptr, counter *uintptr) (err int) = pdh.PdhAddEnglishCounterW | ||
//sys _PdhCollectQueryData(query uintptr) (err int) = pdh.PdhCollectQueryData | ||
//sys _PdhGetFormattedCounterValue(counter uintptr, format uint32, counterType int, value *PdhCounterValue) (err int) = pdh.PdhGetFormattedCounterValue |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT | ||
|
||
package perfmon | ||
|
||
import ( | ||
"syscall" | ||
"unsafe" | ||
) | ||
|
||
var _ unsafe.Pointer | ||
|
||
var ( | ||
modpdh = syscall.NewLazyDLL("pdh.dll") | ||
|
||
procPdhOpenQuery = modpdh.NewProc("PdhOpenQuery") | ||
procPdhAddEnglishCounterW = modpdh.NewProc("PdhAddEnglishCounterW") | ||
procPdhCollectQueryData = modpdh.NewProc("PdhCollectQueryData") | ||
procPdhGetFormattedCounterValue = modpdh.NewProc("PdhGetFormattedCounterValue") | ||
) | ||
|
||
func _PdhOpenQuery(dataSource uintptr, userData uintptr, query *uintptr) (err int) { | ||
r0, _, _ := syscall.Syscall(procPdhOpenQuery.Addr(), 3, uintptr(dataSource), uintptr(userData), uintptr(unsafe.Pointer(query))) | ||
err = int(r0) | ||
return | ||
} | ||
|
||
func _PdhAddCounter(query uintptr, counterPath string, userData uintptr, counter *uintptr) (err int) { | ||
var _p0 *uint16 | ||
_p0, e := syscall.UTF16PtrFromString(counterPath) | ||
if e != nil { | ||
return | ||
} | ||
return __PdhAddCounter(query, _p0, userData, counter) | ||
} | ||
|
||
func __PdhAddCounter(query uintptr, counterPath *uint16, userData uintptr, counter *uintptr) (err int) { | ||
r0, _, _ := syscall.Syscall6(procPdhAddEnglishCounterW.Addr(), 4, uintptr(query), uintptr(unsafe.Pointer(counterPath)), uintptr(userData), uintptr(unsafe.Pointer(counter)), 0, 0) | ||
err = int(r0) | ||
return | ||
} | ||
|
||
func _PdhCollectQueryData(query uintptr) (err int) { | ||
r0, _, _ := syscall.Syscall(procPdhCollectQueryData.Addr(), 1, uintptr(query), 0, 0) | ||
err = int(r0) | ||
return | ||
} | ||
|
||
func _PdhGetFormattedCounterValue(counter uintptr, format uint32, counterType int, value *PdhCounterValue) (err int) { | ||
r0, _, _ := syscall.Syscall6(procPdhGetFormattedCounterValue.Addr(), 4, uintptr(counter), uintptr(format), uintptr(counterType), uintptr(unsafe.Pointer(value)), 0, 0) | ||
err = int(r0) | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our default is 10s