-
Notifications
You must be signed in to change notification settings - Fork 813
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
[wmi] Significant performance improvements on default Windows checks #1952
Comments
@TheCloudlessSky very nice work 🙇 |
Oh wow. Awesome work @TheCloudlessSky . We were actually talking about porting the new WMI check to the system check as well. Thanks a lot for this contribution and feedback, we'll review this very shortly. |
Thanks a lot for the nice work and the detailed explanations @TheCloudlessSky ! As you mentionned, we recently worked on a new WMI AgentCheck after stating the same slowness issues with the Looking at your summary, the results you are getting are even more impressive 🚀. I am looking forward to spend some time reading and diving into your work. In particular I am curious to compare/benchmark the results we are getting by querying and computing from Best, Yann |
@yannmh Awesome. It's very exciting seeing the huge performance differences between |
I've also found that other Windows checks (e.g. IIS) use I think what would be best is to use the |
I've updated the Gist:
|
A lightweight Python WMI module wrapper built on top of `pywin32` and `win32com` extensions. **Specifications** * Based on top of the `pywin32` and `win32com` third party extensions * only * Compatible with `Raw`* and `Formatted` Performance Data classes * Dynamically resolve properties' counter types * Hold the previous/current `Raw` samples to compute/format new * values* * Fast and lightweight * Avoid queries overhead * Cache connections and qualifiers * Use `wbemFlagForwardOnly` flag to improve enumeration/memory * performance *\* `Raw` data formatting relies on the avaibility of the corresponding calculator. Please refer to `checks.lib.wmi.counter_type` for more information* Original discussion thread: #1952 Credits to @TheCloudlessSky (https://github.com/TheCloudlessSky) """
I put everything together and made a proper PR #2011 against Datadog Agent. I'd appreciate having your feedback on it. Again thank you so much for the hard work ! I had a really great time reviewing your work. The performances gain are very impressive (similar to the one you described) and I can't wait to see the changes deployed with the new Datadog Agent release. |
Great! I'm closing this in favor of your PR. |
A lightweight Python WMI module wrapper built on top of `pywin32` and `win32com` extensions. **Specifications** * Based on top of the `pywin32` and `win32com` third party extensions * only * Compatible with `Raw`* and `Formatted` Performance Data classes * Dynamically resolve properties' counter types * Hold the previous/current `Raw` samples to compute/format new * values* * Fast and lightweight * Avoid queries overhead * Cache connections and qualifiers * Use `wbemFlagForwardOnly` flag to improve enumeration/memory * performance *\* `Raw` data formatting relies on the avaibility of the corresponding calculator. Please refer to `checks.lib.wmi.counter_type` for more information* Original discussion thread: #1952 Credits to @TheCloudlessSky (https://github.com/TheCloudlessSky) """
A lightweight Python WMI module wrapper built on top of `pywin32` and `win32com` extensions. **Specifications** * Based on top of the `pywin32` and `win32com` third party extensions * only * Compatible with `Raw`* and `Formatted` Performance Data classes * Dynamically resolve properties' counter types * Hold the previous/current `Raw` samples to compute/format new * values* * Fast and lightweight * Avoid queries overhead * Cache connections and qualifiers * Use `wbemFlagForwardOnly` flag to improve enumeration/memory * performance *\* `Raw` data formatting relies on the avaibility of the corresponding calculator. Please refer to `checks.lib.wmi.counter_type` for more information* Original discussion thread: #1952 Credits to @TheCloudlessSky (https://github.com/TheCloudlessSky) """
A lightweight Python WMI module wrapper built on top of `pywin32` and `win32com` extensions. **Specifications** * Based on top of the `pywin32` and `win32com` third party extensions * only * Compatible with `Raw`* and `Formatted` Performance Data classes * Dynamically resolve properties' counter types * Hold the previous/current `Raw` samples to compute/format new * values* * Fast and lightweight * Avoid queries overhead * Cache connections and qualifiers * Use `wbemFlagForwardOnly` flag to improve enumeration/memory * performance *\* `Raw` data formatting relies on the avaibility of the corresponding calculator. Please refer to `checks.lib.wmi.counter_type` for more information* Original discussion thread: #1952 Credits to @TheCloudlessSky (https://github.com/TheCloudlessSky) """
A lightweight Python WMI module wrapper built on top of `pywin32` and `win32com` extensions. **Specifications** * Based on top of the `pywin32` and `win32com` third party extensions * only * Compatible with `Raw`* and `Formatted` Performance Data classes * Dynamically resolve properties' counter types * Hold the previous/current `Raw` samples to compute/format new * values* * Fast and lightweight * Avoid queries overhead * Cache connections and qualifiers * Use `wbemFlagForwardOnly` flag to improve enumeration/memory * performance *\* `Raw` data formatting relies on the avaibility of the corresponding calculator. Please refer to `checks.lib.wmi.counter_type` for more information* Original discussion thread: #1952 Credits to @TheCloudlessSky (https://github.com/TheCloudlessSky) """
A lightweight Python WMI module wrapper built on top of `pywin32` and `win32com` extensions. **Specifications** * Based on top of the `pywin32` and `win32com` third party extensions * only * Compatible with `Raw`* and `Formatted` Performance Data classes * Dynamically resolve properties' counter types * Hold the previous/current `Raw` samples to compute/format new * values* * Fast and lightweight * Avoid queries overhead * Cache connections and qualifiers * Use `wbemFlagForwardOnly` flag to improve enumeration/memory * performance *\* `Raw` data formatting relies on the avaibility of the corresponding calculator. Please refer to `checks.lib.wmi.counter_type` for more information* Original discussion thread: #1952 Credits to @TheCloudlessSky (https://github.com/TheCloudlessSky) """
A lightweight Python WMI module wrapper built on top of `pywin32` and `win32com` extensions. **Specifications** * Based on top of the `pywin32` and `win32com` third party extensions * only * Compatible with `Raw`* and `Formatted` Performance Data classes * Dynamically resolve properties' counter types * Hold the previous/current `Raw` samples to compute/format new * values* * Fast and lightweight * Avoid queries overhead * Cache connections and qualifiers * Use `wbemFlagForwardOnly` flag to improve enumeration/memory * performance *\* `Raw` data formatting relies on the avaibility of the corresponding calculator. Please refer to `checks.lib.wmi.counter_type` for more information* Original discussion thread: DataDog#1952 Credits to @TheCloudlessSky (https://github.com/TheCloudlessSky) """
We're just starting out with Datadog and it's great. After a week of testing, I deployed the Datadog Agent to a couple of test Windows hosts (m3.medium EC2 instances). I noticed the CPU of the hosts jumping to 20-30% for 1-2 seconds every ~15 seconds (only the default checks were enabled). I checked and found that
WmiPrvSE.exe
andddagent.exe
were the culprits. This was reported to the support team. In the mean time, I wanted to investigate on my own.Because the
shell.exe
is shipped, it allowed me to easily debug the problems. I narrowed it down to the default Windows checks and the WMI calls.Problems
wmi
Python package has lots of overhead to the queries.Win32_PerfFormattedData_*
(which are really slow).Solutions
wmi
package because of the large overhead.Win32_PerfRawData_*
classes and compute the values our self (this is the main performance gain). The MSDN documentation is a pain to work with, but once you understand how to calculate the values, it's easy and has huge performance improvements.DISCLAIMER: I'm not primarily a Python programmer, so the code may not be idiomatic Python (sorry).
I originally implemented the changes before I learned about doing COM directly (from #1917). I found the
wmi
package still had a large amount of overhead. I re-implemented with direct COM and that's what I'm presenting to you today.I created this sample gist. It shows the use of COM, explicit properties, and
Win32_PerfRawData_*
classes to improve performance. If this looks good, I'll create a PR integrating this with the real Windows checks. I created a_WMISampler
class that holds the previous/current sample taken from the raw performance counter and does the calculation of the value.Results
On my dev laptop (Intel i7-3520M), the default Windows checks take:
Here's a graph of 10 samples for each version (original and my fixed wmi version):
This leads to an almost nil performance impact to run the default Windows checks.
Questions
Win32_PerfRawData_*
classes overWin32_PerfFormattedData_*
classes? The formatted classes are computed from multiple samples. So re-measuring might return an inaccurate value since the default Datadog Agent check time is 15 seconds. Using the raw values should give a much more accurate measurement.Happy Friday 😄
The text was updated successfully, but these errors were encountered: