ASP.NET web application monitoring in Zabbix, part 2

Monitor ASP.NET web applications performance in Zabbix. Take advantage of Windows Server performance counters using Zabbix functions “perf_counter” and “perf_counter_en” in your templates.

When you host multiple websites in IIS, and you need to monitor them, Zabbix is one of your options. In Zabbix, you can take advantage of Windows Server performance counters. And in this article I show you some important Windows performance counters you can use to monitor your ASP.NET web application in Zabbix.

Zabbix is a great method of monitoring ASP.NET web applications in Windows Server IIS. You can monitor performance, number of exceptions, memory usage, request execution time, requests per second, and so on. In this post you find ready to use Zabbix template parts for ASP.NET web application monitoring to use in your own Zabbix templates.

The difference between perf_counter and perf_counter_en is: the first returns a value of any Windows performance counter, and the second does the same, but in English. Learn more about Windows-specific item keys in Zabbix’ documentation. I’ll be using perf_counter_en.

Performance counters for .NET, ASP.NET, Exceptions and performance

Some important performance counters for the overall performance status of your web server and ASP.NET web application are, in random order:

  • .NET CLR Exceptions(*)\# of Exceps Thrown
  • .NET CLR Memory(*)\% Time in GC
  • .NET CLR Memory(*)\Gen 0 heap size
  • .NET CLR Memory(*)\Gen 1 heap size
  • .NET CLR Memory(*)\Gen 2 heap size
  • ASP.NET\Application Restarts
  • ASP.NET\Applications Running
  • ASP.NET\Request Execution Time
  • ASP.NET\Worker Process Restarts
  • ASP.NET Applications(*)\Errors Total
  • ASP.NET Applications(*)\Requests/Sec

Use PowerShell‘s Get-Counter cmdlet to try them out.

Add Windows Performance Counters to your Zabbix IIS template

It is not that hard to add these performance counters to your Zabbix template. For example a normal item:

<applications>
	<application>
		<name>Global .NET</name>
	</application>
</applications>
<!-- ... -->
<item>
	<name>.NET CLR Exceptions</name>
	<type>ZABBIX_ACTIVE</type>
	<key>perf_counter_en["\.NET CLR Exceptions(*)\# of Exceps Thrown"]</key>
	<history>7d</history>
	<value_type>FLOAT</value_type>
	<description>Displays the total number of exceptions thrown since the application started. This includes both .NET exceptions and unmanaged exceptions that are converted into .NET exceptions. For example, an HRESULT returned from unmanaged code is converted to an exception in managed code.</description>
	<applications>
		<application>
			<name>Global .NET</name>
		</application>
	</applications>
</item>

Other items can take an application pool name, you can add that in an appropriate discovery_rule item_prototype. For example APP_POOL_WAS(*)\Current Application Pool State, which returns the current state of your application pool:

<item_prototype>
	<name>IIS: AppPool {#APPPOOL} state</name>
	<type>ZABBIX_ACTIVE</type>
	<key>perf_counter_en["\APP_POOL_WAS({#APPPOOL})\Current Application Pool State"]</key>
	<history>7d</history>
	<description>The state of the application pool.</description>
	<application_prototypes>
		<application_prototype>
			<name>{#APPPOOL}</name>
		</application_prototype>
	</application_prototypes>
	<valuemap>
		<name>Application pool state</name>
	</valuemap>
	<preprocessing>
		<step>
			<type>DISCARD_UNCHANGED_HEARTBEAT</type>
			<params>10m</params>
		</step>
	</preprocessing>
	<trigger_prototypes>
		<trigger_prototype>
			<expression>{last()}&lt;&gt;3 and {$IIS.APPPOOL.MONITORED:"{#APPPOOL}"}=1</expression>
			<name>IIS: Application pool {#APPPOOL} is not in Running state</name>
			<priority>AVERAGE</priority>
	</trigger_prototype>
<!- ... -->

Be sure to set a correct value_map:

<value_map>
	<name>Application pool state</name>
	<mappings>
		<mapping>
			<value>1</value>
			<newvalue>Uninitialized</newvalue>
		</mapping>
		<mapping>
			<value>2</value>
			<newvalue>Initialized</newvalue>
		</mapping>
		<mapping>
			<value>3</value>
			<newvalue>Running</newvalue>
		</mapping>
		<mapping>
			<value>4</value>
			<newvalue>Disabling</newvalue>
		</mapping>
		<mapping>
			<value>5</value>
			<newvalue>Disabled</newvalue>
		</mapping>
		<mapping>
			<value>6</value>
			<newvalue>Shutdown Pending</newvalue>
		</mapping>
		<mapping>
			<value>7</value>
			<newvalue>Delete Pending</newvalue>
		</mapping>
	</mappings>
</value_map>

Leave a Comment