How to retrieve WMI metrics

What is WMI?

In the Windows world, operating systems and applications metrics are exposed using the Windows Management Instrumentation. The Datadog Agent for Windows comes with a WMI Integration out of the box, so you can monitor the information that matters to you.

Data in WMI is grouped into classes. There are several hundreds classes that come by default, and each additional role and feature brings its own. Some Applications can also add classes such as Microsoft SQL Server, Microsoft Exchange along with various 3rd party apps.

Microsoft Powershell is considered the standard way to interact with a Windows system programmatically, and it comes with the tools to manage WMI.

To list all classes available on a computer, run:


PS C:\> Get-WmiObject -List

NameSpace: ROOT\cimv2

Name Methods Properties
---- ------- ----------
__SystemClass {} {}
__thisNAMESPACE {} {SECURITY_DESCRIPTOR}
__Provider {} {Name}
__Win32Provider {} {ClientLoadableCLSID, CLSID, Concurrency, DefaultMachineNam...
__IndicationRelated {} {}

[...]

To count how many classes are available, run:


PS C:\> (Get-WmiObject -List).count
931

We can find classes about a specific topic by using the where statement. To display classes that hold processes information, run:

PS C:\> Get-WmiObject -List | where {$_.name -match "process"} | select Name

Name
----
Win32_ProcessTrace
Win32_ProcessStartTrace
Win32_ProcessStopTrace
CIM_Process
Win32_Process
CIM_Processor
Win32_Processor
Win32_PerfFormattedData_PerfOS_Processor
Win32_PerfFormattedData_PerfProc_Process
[...]

To browse the data exposed by a class, we can use a syntax similar to SQL called WQL: https://msdn.microsoft.com/en-us/library/aa392902%28v=vs.85%29.aspx.
Many performance related metrics are reported by the PerfMon tool, and are called Win32_PerfFormattedData_. In this example we want to look at processes information so we'll query the Win32_PerfFormattedData_PerfProc_Process class:

PS C:\> Get-WmiObject -Query "select * from Win32_PerfFormattedData_PerfProc_Process where Name = 'Powershell'"


__GENUS                 : 2
__CLASS                 : Win32_PerfFormattedData_PerfProc_Process
__SUPERCLASS            : Win32_PerfFormattedData
__DYNASTY               : CIM_StatisticalInformation
__RELPATH               : Win32_PerfFormattedData_PerfProc_Process.Name="powershell"
__PROPERTY_COUNT        : 36
__DERIVATION            : {Win32_PerfFormattedData, Win32_Perf, CIM_StatisticalInformation}
__SERVER                : DATADOG-9A675BB
__NAMESPACE             : root\cimv2
__PATH                  : \\DATADOG-9A675BB\root\cimv2:Win32_PerfFormattedData_PerfProc_Process.Name="powershell"
Caption                 :
CreatingProcessID       : 2560
Description             :
ElapsedTime             : 3333
Frequency_Object        :
Frequency_PerfTime      :
Frequency_Sys100NS      :
HandleCount             : 655
IDProcess               : 4024
IODataBytesPersec       : 0
IODataOperationsPersec  : 0
IOOtherBytesPersec      : 0
IOOtherOperationsPersec : 0
IOReadBytesPersec       : 0
IOReadOperationsPersec  : 0
IOWriteBytesPersec      : 0
IOWriteOperationsPersec : 0
Name                    : powershell
PageFaultsPersec        : 0
PageFileBytes           : 39415808
PageFileBytesPeak       : 43970560
PercentPrivilegedTime   : 0
PercentProcessorTime    : 0
PercentUserTime         : 0
PoolNonpagedBytes       : 7132
PoolPagedBytes          : 206292
PriorityBase            : 8
PrivateBytes            : 39415808
ThreadCount             : 7
Timestamp_Object        :
Timestamp_PerfTime      :
Timestamp_Sys100NS      :
VirtualBytes            : 162775040
VirtualBytesPeak        : 170778624
WorkingSet              : 41054208
WorkingSetPeak          : 45273088

This command returns details about the Powershell process. It includes a lot of information including memory usage and I/O operations.

For those who can run third-party applications on their machine the tool WMI Explorer will make it very easy to browse the information exposed by WMI. It's available here https://www.ks-soft.net/hostmon.eng/wmi/, it's a self-contained .exe file so you don't have to install it, and it's virus-freehttps://www.virustotal.com/en/file/df8e909491da38556a6c9a50abf42b3b906127e0d4b35d0198ef491139d1622c/analysis/.

Leveraging WMI in Datadog

Now that we understand WMI better, let's see how we can get this data into Datadog. Open the Datagog Agent Manager and click on the WMI Check integration in the left panel.

Let's start with a simple example: monitoring the number of processes on the machine:

init_config:

# Each WMI query has 2 required options, `class` and `metrics`
# `class` is the name of the WMI class, for example Win32_OperatingSystem
# `metrics` is a list of metrics you want to capture, with each item in the
# list being a set of [WMI property name, metric name, metric type].

instances:

  # Fetch the number of processes 
  - class: Win32_OperatingSystem
    metrics:
      - [NumberOfProcesses, system.proc.count, gauge]

Save the configuration, enable the integration and restart then go to 'Logs and Status -> Agent Status'. Under the 'Checks' section you should see the following:

wmi_check Instance #0 OK Collected 1 metrics, 0 events and 1 service check 

Now let's monitor the Windows Powershell process we were looking at earlier:

init_config:

#   Fetch metrics for a single running application
instances:
  - class: Win32_PerfFormattedData_PerfProc_Process
    metrics:
      - [ThreadCount, powershell.threads.count, gauge]
      - [VirtualBytes, powershell.mem.virtual, gauge]

  # `filters` is a list of filters on the WMI query you may want. For example,
  # for a process-based WMI class you may want metrics for only certain
  # processes running on your machine, so you could add a filter for each
  # process name. See below for an example of this case.
    filters:
      - Name: powershell
 

In your Metrics Explorer you should find 2 metrics called powershell.threads.count and powershell.mem.virtual. But what happens if you have 2 Powershell consoles opened? You will find the following error in the 'Checks section':

wmi_check
  Instance #0
    ERROR 
  Error
    Exception("WMI query returned multiple rows but no `tag_by` value was given. metrics=[['ThreadCount',
    'powershell.threads.count', 'gauge'], ['VirtualBytes', 'powershell.mem.virtual', 'gauge']]",) 
  Collected 0 metrics, 0 events and 1 service check 

This is because the agent cannot report on 2 different metrics that have the same set of name and tags. To be able to differentiate between the 2 we can use the tag_by: Instance_Property_Name statement to use the value of an instance's property as an additional tag:

init_config:

instances:

#   Fetch metrics for each instance of a running application
  - class: Win32_PerfFormattedData_PerfProc_Process
    metrics:
      - [ThreadCount, powershell.threads.count, gauge]
      - [VirtualBytes, powershell.mem.virtual, gauge]
    filters:
      - Name: powershell
# `tag_by` optionally lets you tag each metric with a property from the
# WMI class you're using. This is only useful when you will have multiple
# values for your WMI query. The examples below show how you can tag your
# process metrics with the process name (giving a tag of "name:app_name").
    tag_by: Name
# Please note that bellow works on Window >= 2008, as process names are appended a `#XYZ` where `XYZ` is an incremental numebr
# If running on Windows 2003, use a different uniq value like `tag_by: IDProcess`

Which will give you 2 metrics per Powershell console opened:

wmi_check
  Instance #0
    OK 
  Collected 4 metrics, 0 events and 1 service check 

If the information that you would like to use as a tag is not part of the class you're getting the data from, you have the possibility to use the tag_queries list to link data from different tables.

Let's say I want to report on PoolNonPagedBytes from Win32_PerfFormattedData_PerfProc_Process and I want to addCreationDate from Win32_Process as a tag. These 2 classes expose the PID with different names: IDProcess inWin32_PerfFormattedData_PerfProc_Process and Handle in Win32_Process. So the former will be thelink source property and the later the target property:

  # `tag_queries` optionally lets you specify a list of queries, to tag metrics
  # with a target class property. Each item in the list is a set of
  # [link source property, target class, link target class property, target property]
  # where:
  #
  # - 'link source property' contains the link value
  # - 'target class' is the class to link to
  # - 'link target class property' is the target class property to link to
  # - 'target property' contains the value to tag with
  #
  # It translates to a WMI query:
  # SELECT 'target property' FROM 'target class'
  #                 WHERE 'link target class property' = 'link source property'
  #
  # Note: setting this will cause any instance number to be removed from tag_by values
  # i.e. name:process#1 => name:process

init_config:

instances:

#   Fetch metrics for a single running application
  - class: Win32_PerfFormattedData_PerfProc_Process
    metrics:
      - [ThreadCount, powershell.threads.count, gauge]
      - [VirtualBytes, powershell.mem.virtual, gauge]
    filters:
      - Name: powershell
    tag_by: Name

    tag_queries:
      - [IDProcess, Win32_Process, Handle, CreationDate]
Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.
Powered by Zendesk