# Metricbeat WMI CPU usage

**URL:** <https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553>\
**Category:** Beats\
**Tags:** metricbeat\
**Created:** [December 20, 2016, 10:27am UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553 "2016-12-20T10:27:37Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![aalesh](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@aalesh](https://discuss.elastic.co/u/aalesh)\
**Post date:** [December 20, 2016, 10:27am UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553/1 "2016-12-20T10:27:37Z")

</div>

We want to use metricbeat to monitor processes on our Windows servers.  
The problem is that we have 200+ processes which seems to cause peformance issues:

1. `WmiPrvSE.exe` consumes 90%+ of one CPU core.
2. Metricbeat freezes completely for first couple of minutes after starting the processes.
3. At least when using Topbeat 1.3.1 we see that its log is full of `WARN Ignoring tick(s) due to processing taking longer than one period` (we have `period: 10s`). Not sure if Metricbeat 5.2.1 still has the problem.  
We see that the high CPU usage is caused by obtaining processes' command line via WMI (as discussed in [Windows Topbeat Causes High CPU Utilization in WMI Provider Host [Solved]](https://discuss.elastic.co/t/windows-topbeat-causes-high-cpu-utilization-in-wmi-provider-host-solved/42649)).

**It would be great if Metricbeat somehow allowed user to specify (s)he does not need the `system.process.cmdline` in order to avoid that dramatic WMI performance overhead**.

Note this does not have the desired effect:

> processors:
> 
> - drop\_fields:  
> fields: [system.process.cmdline]

Also note it may be the case that the problem only manifests itself when processes have pretty long command lines (which our PROD processes do). So, the `spawn_dummy_processes.bat` batch file given below has some quick-and-dirty procedure of spawning processes with long command lines.

As a proof-of-concept we've patched the Metricbeat to not query WMI. Here are the results:

**Original version**

 ![](https://us1.discourse-cdn.com/elastic/original/2X/6/6948b0b6b3ff99ed2498830a5206d1773403087b.png)

**Patched version**

 ![](https://us1.discourse-cdn.com/elastic/original/2X/b/b52531ae2a98040f0942ac6cf50e61f9c4001385.png)

**spawn\_dummy\_processes.bat** to use for testing

> echo off  
> set childrenLifeDuration=180  
> set childrenCount=300  
> call :generateRandomString 300  
> echo Spawning %childrenCount% processes that will live for %childrenLifeDuration% seconds...  
> FOR /L %%X IN (1,1,%childrenCount%) DO call :spawn %%X  
> echo Press any key to terminate spawned processes prematurely...  
> pause \> NUL  
> echo Killing processes...  
> FOR /L %%X IN (1,1,%childrenCount%) DO waitfor /SI XXX%%X \> NUL 2\>&1  
> echo Done.  
> GOTO :EOF

> :spawn  
> ::call :generateRandomString 400  
> :: add randomized preffix, so that processes have different command lines  
> set longString=%random% %longString%  
> start /MIN cmd "/c echo %longString%& waitfor /T %childrenLifeDuration% XXX%1"  
> ::waitfor /T 1 ZZZZ \> NUL 2\>&1  
> GOTO :EOF

> :generateRandomString  
> call :generateRandomStringImpl "longString" %1  
> set longString=%accumString%  
> set accumString=  
> GOTO :EOF

> :generateRandomStringImpl  
> set accumString=%~1  
> set remainingSteps=%2  
> IF 0==%remainingSteps% GOTO :EOF  
> set /A remainingSteps = %remainingSteps% - 1  
> set accumString=%accumString% %random% %random% %random%  
> call :generateRandomStringImpl "%accumString%" %remainingSteps%  
> GOTO :EOF

---

<div class="post-metadata">

**Author:** ![andrewkroh](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrewkroh/32/3784_2.png) [@andrewkroh](https://discuss.elastic.co/u/andrewkroh)\
**Post date:** [December 20, 2016, 2:53pm UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553/2 "2016-12-20T14:53:28Z")

</div>

The drop\_fields processors is applied after the event is created so it won't save on CPU cycles.You could limit what processes are collected with the `processes: ["some regex"]` option.

Metricbeat should be using a cached copy of the cmdline after the first fetch for a given PID. Are you seeing this reflected in your testing? But that won't help with the initial fetch.

Personally I would be ok with adding a `processes.cmdline: true/false` option to toggle the cmdline collection. Probably a better solution would be to find a way that doesn't require WMI to get the cmdline.

---

<div class="post-metadata">

**Author:** ![aalesh](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@aalesh](https://discuss.elastic.co/u/aalesh)\
**Post date:** [December 20, 2016, 3:29pm UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553/3 "2016-12-20T15:29:46Z")

</div>

> [@andrewkroh](#):
>
> drop\_fields processors is applied after the event is created so it won't save on CPU cycles

Yep. That is understandable.

> [@andrewkroh](#):
>
> limit what processes are collected with the `processes: ["some regex"]` option

Does not solve our problem since we do need CPU usage info on each of those 200+ processes ☹

> [@andrewkroh](#):
>
> Metricbeat should be using a cached copy of the cmdline after the first fetch for a given PID. Are you seeing this reflected in your testing? But that won't help with the initial fetch.

Just tried it: indeed in 3-4 minutes CPU usage is back to normal. 👍 Well, in fact **this seems to be just good enough for us to use**. I wonder why we experienced lots of `WARN Ignoring tick(s) due to processing taking longer than one period` with Topbeat...

[quote="andrewkroh, post:2, topic:69553"]  
Probably a better solution would be to find a way that doesn't require WMI to get the cmdline.[/quote]  
Totally agree.

---

<div class="post-metadata">

**Author:** ![andrewkroh](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrewkroh/32/3784_2.png) [@andrewkroh](https://discuss.elastic.co/u/andrewkroh)\
**Post date:** [December 20, 2016, 3:49pm UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553/4 "2016-12-20T15:49:40Z")

</div>

> [@aalesh](#):
>
> I wonder why we experienced lots of WARN Ignoring tick(s) due to processing taking longer than one period with Topbeat...

This message was logged anytime the collection took longer than 10 seconds or whatever the collection period was. I don't think there is an equivalent message in Metricbeat, but the same thing probably occurs on your first collection interval. Each MetricSet does its collection on it own goroutine so it cannot block the collection of metrics from other modules. And if the collection takes longer than 10 seconds it will just resume collection at the fixed interval.

---

<div class="post-metadata">

**Author:** ![aalesh](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@aalesh](https://discuss.elastic.co/u/aalesh)\
**Post date:** [December 26, 2016, 4:18pm UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553/5 "2016-12-26T16:18:19Z")

</div>

> [@andrewkroh](#):
>
> Personally I would be ok with adding a processes.cmdline: true/false option to toggle the cmdline collection

Can we add a feature request for this? While CPU usage indeed decreases in 3-4 minutes after processes are started there still can be - pretty rare I admit it - situations when we don't have those 3-4 minutes. So, if it's not a big change and there is a simple and clean way to add such a config option we'd like to have it.

---

<div class="post-metadata">

**Author:** ![andrewkroh](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrewkroh/32/3784_2.png) [@andrewkroh](https://discuss.elastic.co/u/andrewkroh)\
**Post date:** [December 26, 2016, 4:22pm UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553/6 "2016-12-26T16:22:44Z")

</div>

Yes, please open a request for it. It probably would be relatively easy to add such an option because the `ProcArgs` are requested on their own from the sigar library. So it would just mean adding a conditional around that call.

---

<div class="post-metadata">

**Author:** ![aalesh](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@aalesh](https://discuss.elastic.co/u/aalesh)\
**Post date:** [December 26, 2016, 4:27pm UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553/7 "2016-12-26T16:27:35Z")

</div>

Great! And thank you so much for prompt, friendly and professional responses! 🙂

---

<div class="post-metadata">

**Author:** ![aalesh](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@aalesh](https://discuss.elastic.co/u/aalesh)\
**Post date:** [December 27, 2016, 11:39am UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553/8 "2016-12-27T11:39:38Z")

</div>

JFYI here's the feature request: [https://github.com/elastic/beats/issues/3249](https://github.com/elastic/beats/issues/3249)

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [January 24, 2017, 11:40am UTC](https://discuss.elastic.co/t/metricbeat-wmi-cpu-usage/69553/9 "2017-01-24T11:40:02Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
