From da62eb99ea3a566190251f2a5f7b15502c916bea Mon Sep 17 00:00:00 2001 From: Rune Darrud Date: Fri, 31 Jul 2015 02:46:53 +0200 Subject: [PATCH] Updated args to be more consistent with check_services. ToDo: Update CommandDefinition ToDo: Write a QuickStart --- README.md | 486 ++++++++++++++++ Solution/README.md | 476 ---------------- Solution/check_iis/Program.cs | 535 +++++++++--------- Solution/check_iis/Properties/AssemblyInfo.cs | 2 +- 4 files changed, 756 insertions(+), 743 deletions(-) delete mode 100644 Solution/README.md diff --git a/README.md b/README.md index 22e4cae..061fbcd 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,488 @@ # check_iis Internet Information Server check plugin for Icinga2, Icinga, Centreon, Shinken, Naemon and other nagios like systems. + +## General Requirements + +* Windows OS with .NET Framework 3.5 SP1 or newer installed, this plugin comes in flavours for both 3.5 and 4.0+ +* IIS 7.0 or higher, this means Windows Server 2008 or newer. +* This plugin can only check Sites and AppPools locally on the same machine it runs from. Expects Icinga2 agent, NSCP or similar to execute it. +* To run this the agent/executor service must run as admin, user rights is not enough due to requiring admin with elevated rights to read the configuration store from IIS. +* Case sensitivity in matches for Sites and Application Pools. +* Use only the named switches, the single character shortcuts might change in the future or disappear completely. + +## Assumptions +This executable assumes the following: +* That the plugin is able to run as SYSTEM or with a user that has Administrative privileges. +* When you run inventory with the switch to only return running services, this assumes that the Sites and AppPools are in their correct states. The output from this can be used to correctly configure the arguments. + +## Usage: + + check_iis.exe - Windows Service Status plugin for Icinga2, Icinga, Centreon, Shinken, Naemon and other nagios like systems. + Version: 0.9.5690.4962 + + a:inventory-apppools Switch to use to provide inventory of AppPools. + A:inventory-websites Switch to use to provide inventory of Sites + B:check-websites Switch to use to check the health status of the local Sites + C:check-apppools Switch to use to check the health status of the local AppPools + E:inv-level Argument to change the level of output. Default is 'normal', available options are 'normal','full' + f:inv-format Argument to provide output of the inventory in other formats, valid options are 'readable', 'i2conf' and 'json' + F:excluded-sites Excludes Sites from checks and inventory. Provide multiple with spaces between + G:included-sites Includes Sites to check while all other Sites are excluded, affects both checks and inventory. Provide multiple with spaces between + h:stopped-sites The specified Sites are checked that they are stopped. Provide multiple with spaces between + H:warn-sites These specified Sites will return Warning if they are not in the expected state. Provide multiple with spaces between + i:perfcounter-sites Switch to use to get perfcounters from local Sites + I:excluded-apppools Excludes AppPools from checks and inventory. Provide multiple with spaces between + J:included-apppools Includes apppools to check while all other AppPools are excluded, affects both checks and inventory. Provide multiple with spaces between + k:stopped-apppools The specified AppPools are checked that they are stopped. Provide multiple with spaces between + K:warn-apppools The specified AppPools will return Warning if they are not in the expected state. Provide multiple with spaces between + l:perfcounter-apppools Switch to use to get perfcounters from local AppPools + L:skip-empty-apppools Switch which sets do not inventory AppPools which are empty or unused. + T:hide-long-output Switch to hide the long service output, only prints the summary output and any Sites or Services deviating from 'OK' + u:expected-state Argument to provide the expected State of the AppPool or Site, used together with --single-check + w:icinga2 Switch used in the Icinga2 CommandDefinition, returns output and perfcounter to the correct class. Do not use via command line. + W:single-check Switch used together with the Icinga2 Auto Apply rules, this is set when there is a single Site or AppPool to check. Do take great care if you use this outside of the auto apply rules. + x:split-by Argument used to specify what splits all Sites and AppPool arguments. Default is a single space, ' '. + X:inv-hide-empty Switch to hide empty vars from inventory output. + y:inv-running-only Switch to only inventory running Sites and/or AppPools, depending on what has been selected for inventory + z:verbose Switch to use when trying to figure out why a service is not included, excluded or similarly when the returned output is not as expected + Z:debug Switch to to get maximum verbosity (for debugging) + +## Examples + +### Monitoring + +#### Application Pools +Monitor Application Pools + + check_iis.exe --check-apppools + +Monitor Application Pools, only monitor Application Pool ".NET v4.5" + + check_iis.exe --check-apppools --included-apppools ".NET v4.5" + +Monitor Application Pools, all should be started but for ".NET v4.5", which is expected to be stopped + + check_iis.exe --check-apppools --stopped-apppools ".NET v4.5" + +Monitor Application Pools, all should be started, if AppPool ".NET v2.0" is in a different state it should only warn + + check_iis.exe --check-apppools --warn-apppools ".NET v2.0" + +Monitor Application Pools, monitor all AppPools but for ".NET v2.0" + + check_iis.exe --check-apppools --excluded-apppools ".NET v2.0" + +Monitor Application Pools, monitor all but for ".NET 2.0" and".NET v4.5", in addition AppPool ".NET v4.5 Classic" should be stopped instead of running + + check_iis.exe --check-apppools --excluded_apppools ".NET v2.0" ".NET v4.5" --stopped-apppools ".NET v4.5 Classic" + +Monitor Application Pools, all AppPools should be running, with performance data + + check_iis.exe --check-apppools --perfcounter-apppools + +Monitor Application Pools, all AppPools should be running, excluded AppPool ".NET v2.0", with performance data + + check_iis.exe --check-apppools --perfcounter-apppools --excluded-apppools ".NET v2.0" + +Monitor Application Pools, all AppPools should be running, excluded AppPools ".NET v2.0" and ".NET v4.5", default --split-by + + check_iis.exe --check-apppools --perfcounter-apppools --excluded-apppools ".NET v2.0" ".NET v4.5" + +Monitor Application Pools, all AppPools should be running, excluded AppPools ".NET v2.0" and ".NET v4.5", comma separates multiple values + + check_iis.exe --check-apppools --perfcounter-apppools --excluded-apppools ".NET v2.0",".NET v4.5" --split-by "," + +#### Sites +Monitor Sites + + check_iis.exe --check-websites + +Monitor Sites, only monitor Site ".NET v4.5" + + check_iis.exe --check-websites --included-sites ".NET v4.5" + +Monitor Sites, all should be started but for ".NET v4.5", which is expected to be stopped + + check_iis.exe --check-websites --stopped-sites ".NET v4.5" + +Monitor Sites, all should be started, if AppPool ".NET v2.0" is in a different state it should only warn + + check_iis.exe --check-websites --warn-sites ".NET v2.0" + +Monitor Sites, monitor all Sites but for ".NET v2.0" + + check_iis.exe --check-websites --excluded-sites ".NET v2.0" + +Monitor Sites, monitor all but for ".NET 2.0" and".NET v4.5", in addition AppPool ".NET v4.5 Classic" should be stopped instead of running + + check_iis.exe --check-websites --excluded-sites ".NET v2.0" ".NET v4.5" --stopped-sites ".NET v4.5 Classic" + +Monitor Sites, all Sites should be running, with performance data + + check_iis.exe --check-websites --perfcounter-sites + +Monitor Sites, all Sites should be running, excluded AppPool ".NET v2.0", with performance data + + check_iis.exe --check-websites --perfcounter-sites --excluded-sites ".NET v2.0" + +#### AppPools and Sites +Monitor Application Pools and Sites (all expected running) + + check_iis.exe --check-websites --apppools + +Monitor Application Pools and Sites with perfcounter + + check_iis.exe --apppools --perfcounter-apppools --check-websites --perfcounter-sites + +Monitor Application Pools (excluded ".NET v2.0") and Sites (excluded "WsusPool") + + check_iis.exe --apppools --perfcounter-apppools --check-websites --perfcounter-sites --excluded-apppools ".NET v2.0" --excluded-sites "WsusPool" + +### Inventory +#### AppPools +Inventory AppPools + + check_iis.exe --inventory-apppools + +Inventory AppPools, only inventory "DefaultAppPool" + + check_iis.exe --inventory-apppools --included-apppools "DefaultAppPool" + +Inventory AppPools, only return the running AppPools + + check_iis.exe --inventory-apppools --inv-running-only + +Inventory AppPools, only return the running AppPools, do not print empty arrays or keys with empty values + + check_iis.exe --inventory-apppools --inv-running-only --inv-hide-empty + +Inventory AppPools, all but ".NET v4.5" + + check_iis.exe --inventory-apppools --excluded-apppools ".NET v4.5" + +#### Sites +Inventory Sites + + check_iis.exe --inventory-websites + +Inventory Sites, only return the running Sites + + check_iis.exe --inventory-websites --inv-running-only + +Inventory Sites, all but "WsusPool" + + check_iis.exe --inventory-sites --excluded-sites "WsusPool" + +Inventory Sites, only inventory "Default Web Site", full inventory + + check_iis.exe --inventory-websites --included-sites "Default Web Site" --inv-level full + +Inventory Sites, only return the running Sites, do not print empty arrays or keys with empty values + + check_iis.exe --inventory-websites --inv-running-only --inv-hide-empty + +Inventory Sites, do not print empty arrays or keys with empty values, return it as icinga2 format configuration. + + check_iis.exe --inventory-websites --inv-hide-empty --inv-format i2conf + + +#### AppPools and Sites + +Inventory AppPools and Sites + + check_iis.exe --inventory-apppools --inventory-websites + +Inventory AppPools and Sites, only running + + check_iis.exe --inventory-apppools --inventory-websites --inv-running-only + +Inventory AppPools and Sites with all recognized details, as json + + check_iis.exe --inventory-apppools --inventory-websites --inv-level full --inv-format json + +Inventory AppPools and Sites with all recognized details, as json, only running + + check_iis.exe --inventory-apppools --inventory-websites --inv-level full --inv-format json --inv-running-only + +Inventory AppPools and Sites with all recognized details, as i2conf output, only running + + check_iis.exe --inventory-apppools --inventory-websites --inv-level full --inv-format i2conf --inv-running-only + +Inventory AppPools and Sites with all recognized details, as readable output, only running, hide empty vars + + check_iis.exe --inventory-apppools --inventory-websites --inv-level full --inv-format readable --inv-running-only --inv-hide-empty + + +## Configuration + +To make this plugin work with Icinga2, NSCP or others, it needs to be configured. +Below are some configuration examples on how to configure this plugin with Icinga2 (agent) and NSCP/NSClient++. + +### Icinga2 agent + +All configuration samples below assumes local configuration on agent, configuration for central use to come. + +#### Command Definition + + object CheckCommand "check_iis" { + import "plugin-check-command" + + command = [ PluginDir + "/check_iis.exe" ] + + arguments = { + "--check-apppools" = { + set_if = "$iis_check_apppools$" + description = "Parameter to use to check the health status of the local Sites" + } + "--check-websites" = { + set_if = "$iis_check_sites$" + description = "Parameter to use to check the health status of the local Sites" + } + "--inventory-apppools" = { + set_if = "$iis_inventory_apppools$" + description = "Parameter to use to provide inventory of apppools instead of checking for the health." + } + "--inventory-websites" = { + set_if = "$iis_inventory_sites$" + description = "Parameter to use to provide inventory of sites instead of checking for the health." + } + "--inv-level" = { + value = "$iis_inventory_level$" + description = "Optional parameter to change the level of output. Default is 'normal', available options are 'normal','full'" + } + "--inv-format" = { + value = "$iis_inventory_format$" + description = "Optional parameter to provide output of the inventory in other formats, valid options are 'readable', 'i2conf' and 'json'" + } + "--excluded-sites" = { + value = "$iis_excluded_sites$" + description = "Optional: Excludes sites from checks and inventory. Provide multiple with spaces between" + } + "--included-sites" = { + value = "$iis_included_sites$" + description = "Optional: Includes sites to check while all other sites are excluded, affects both checks and inventory. Provide multiple with spaces between" + } + "--warn-sites" = { + value = "$iis_warn_sites$" + description = "Optional: These sites will return Warning if they are not in the expected state. Provide multiple with spaces between" + } + "--stopped-sites" = { + value = "$iis_stopped_sites$" + description = "Optional: These sites are checked that they are stopped. Provide multiple with spaces between" + } + "--excluded-apppools" = { + value = "$iis_excluded_apppools$" + description = "Optional: Excludes apppools from checks and inventory. Provide multiple with spaces between" + } + "--included-apppools" = { + value = "$iis_included_apppools$" + description = "Optional: Includes apppools to check while all other apppools are excluded, affects both checks and inventory. Provide multiple with spaces between" + } + "--warn-apppools" = { + value = "$iis_warn_apppools$" + description = "Optional: These apppools will return Warning if they are not in the expected state. Provide multiple with spaces between" + } + "--stopped-apppools" = { + value = "$iis_stopped_apppools$" + description = "Optional: These apppools are checked that they are stopped. Provide multiple with spaces between" + } + "--perfcounter-sites" = { + set_if = "$iis_perfcounter_sites$" + description = "Parameter to use to get basic performance counters for the Sites" + } + "--perfcounter-apppools" = { + set_if = "$iis_perfcounter_apppools$" + description = "Parameter to use to get basic performance counters for the AppPools" + } + "--inv-running-only" = { + set_if = "$iis_inv_running_only$" + description = "Only inventory running Sites and/or AppPools, depending on what has been selected for inventory" + } + "--inv-hide-empty" = { + set_if = "$inv_hide_empty_vars$" + description = "Optional parameter for inventory: Only print returned data that has values in them, skip empty arrays and vars." + } + "--icinga2" = { + set_if = "$iis_icinga2$" + description = "Used in the Icinga2 CommandDefinition, returns output and perfdata to the correct class. Do not use via command line." + } + "--single-check" = { + set_if = "$iis_single_check$" + description = "Used together with the Icinga2 Auto Apply rules, this is set when there is a single Site or AppPool to check. Do take great care if you use this outside of the auto apply rules." + } + "--expected-state" = { + set_if = "$iis_single_check$" + value = "$iis_expected_state$" + description = "Optional: Parameter to provide the expected State of the AppPool or Site, used together with --single-check" + } + "--verbose" = { + set_if = "$iis_verbose$" + description = "Only inventory running Sites and/or AppPools, depending on what has been selected for inventory" + } + } + vars.iis_check_apppools = false + vars.iis_check_sites = false + vars.iis_perfcounter_apppools = false + vars.iis_perfcounter_sites = false + vars.iis_inventory_apppools = false + vars.iis_inventory_sites = false + vars.iis_inv_running_only = false + vars.iis_inv_hide_empty_vars = false + vars.iis_icinga2 = false + vars.iis_verbose = false + vars.iis_expected_state = "Started" + vars.iis_single_check = false + + } + +#### AppPool Monitoring +Monitor all AppPools, does not need any data from inventory. + + apply Service "IIS AppPools"{ + import "generic-service" + + check_command = "check_iis" + + assign where host.name == NodeName + + vars.iis_check_apppools = true + vars.iis_stopped_apppools = "" + } + +Monitor all AppPools, same as above, just added with perfcounter option. + + apply Service "IIS AppPools"{ + import "generic-service" + + check_command = "check_iis" + + assign where host.name == NodeName + + vars.iis_check_apppools = true + vars.iis_perfcounter_apppools = true + vars.iis_stopped_apppools = "" + } + +Monitors AppPools based on inventory data (stored in the host object), this specific apply rule only adds running apppools to monitoring, with perfcounters + + apply Service "IIS AppPoolR " for (name => config in host.vars.inv.iis.apppool) { + import "generic-service" + + check_command = "check_iis" + + vars += config + vars.iis_check_apppools = true + vars.iis_included_apppools = vars.Name + vars.iis_perfcounter_apppools = true + assign where config.State == "Started" + } + +Monitors AppPools based on inventory data (stored in the host object), this specific apply rule only adds stopped apppools to monitoring, with perfcounters + + apply Service "IIS AppPoolS " for (name => config in host.vars.inv.iis.apppool) { + import "generic-service" + + check_command = "check_iis" + + vars += config + vars.iis_check_apppools = true + vars.iis_included_apppools = vars.Name + vars.iis_stopped_apppools = vars.Name + vars.iis_perfcounter_apppools = true + assign where config.State == "Stopped" + } + +Recommended method: Monitors AppPools based on inventory data (stored in the host object), this specific apply rule adds uses the state from inventory, with perfcounters + + apply Service "IIS AppPool " for (name => config in host.vars.inv.iis.apppool) { + import "generic-service" + + check_command = "check_iis" + + vars += config + vars.iis_check_apppools = true + vars.iis_included_apppools = vars.Name + vars.iis_perfcounter_apppools = true + vars.iis_expected_state = vars.State + vars.iis_single_check = true + } + + +#### Monitor Sites +Monitors all Sites, does not use inventory data. + + apply Service "IIS Sites"{ + import "generic-service" + + check_command = "check_iis" + + vars.iis_check_sites = true + vars.iis_perfcounter_sites = true + + assign where host.name == NodeName + + } + +Monitors all Sites, does not use inventory data, the same as above, just added perfcounters. + + apply Service "IIS Sites"{ + import "generic-service" + + check_command = "check_iis" + + vars.iis_check_sites = true + vars.iis_perfcounter_sites = true + assign where host.name == NodeName + + } + +Monitors Sites based on inventory data (stored in the host object), this specific apply rule only adds running sites to monitoring, with perfcounters + + apply Service "IIS SiteR " for (name => config in host.vars.inv.iis.site) { + import "generic-service" + + check_command = "check_iis" + + vars += config + vars.iis_check_sites = true + vars.iis_included_sites = vars.Name + vars.iis_perfcounter_sites = true + assign where config.State == "Started" + } + +Monitors Sites based on inventory data (stored in the host object), this specific apply rule only adds stopped Sites to monitoring, with perfcounters + + apply Service "IIS SiteS " for (name => config in host.vars.inv.iis.site) { + import "generic-service" + + check_command = "check_iis" + + vars += config + vars.iis_check_sites = true + vars.iis_included_sites = vars.Name + vars.iis_stopped_sites = vars.Name + vars.iis_perfcounter_sites = true + assign where config.State == "Stopped" + } + +Recommended method: Monitors Sites based on inventory data (stored in the host object), this specific apply rule adds uses the state from inventory, with perfcounters + + apply Service "IIS Site " for (name => config in host.vars.inv.iis.site) { + import "generic-service" + + check_command = "check_iis" + + vars += config + vars.iis_check_sites = true + vars.iis_included_sites = vars.Name + vars.iis_perfcounter_sites = true + vars.iis_expected_state = vars.State + vars.iis_single_check = true + } + +### NSCP / NSClient++ +ToDo + +Add in nsclient.ini + +Test via check_nrpe or similar to verify. \ No newline at end of file diff --git a/Solution/README.md b/Solution/README.md deleted file mode 100644 index e4ccbdb..0000000 --- a/Solution/README.md +++ /dev/null @@ -1,476 +0,0 @@ -# check_iis -Internet Information Server check plugin for Icinga2, Icinga, Centreon, Shinken, Naemon and other nagios like systems. - -## General Requirements - -* Windows OS with .NET Framework 3.5 SP1 or newer installed, this plugin comes in flavours for both 3.5 and 4.0+ -* IIS 7.0 or higher, this means Windows Server 2008 or newer. -* This plugin can only check Sites and AppPools locally on the same machine it runs from. Expects Icinga2 agent, NSCP or similar to execute it. -* To run this the agent/executor service must run as admin, user rights is not enough due to requiring admin with elevated rights to read the configuration store from IIS. -* Case sensitivity in matches for Sites and Application Pools. -* Use only the named switches, the single character shortcuts might change in the future or disappear completely. - -## Assumptions -This executable assumes the following: -* That the plugin is able to run as SYSTEM or with a user that has Administrative privileges. -* When you run inventory with the switch to only return running services, this assumes that the Sites and AppPools are in their correct states. The output from this can be used to correctly configure the arguments. - -## Usage: - check_iis.exe - Windows Service Status plugin for Icinga2, Icinga, Centreon, Shinken, Naemon and other nagios like systems. - Version: 0.8 - - a:inventory-apppools Parameter to use to provide inventory instead of checking for the health. - A:inventory-websites Parameter to use to provide inventory instead of checking for the health. - B:check-websites Parameter to use to check the health status of the local Sites - C:check-apppools Parameter to use to check the health status of the local AppPools - E:inv-level Optional: Parameter to change the level of output. Default is 'normal', available options are 'normal','full' - f:inv-format Optional: Parameter to provide output of the inventory in other formats, valid options are 'readable', 'i2conf' and 'json' - F:excluded-sites Optional: Excludes sites from checks and inventory. Provide multiple with spaces between - G:included-sites Optional: Includes sites to check while all other sites are excluded, affects both checks and inventory. Provide multiple with spaces between - h:warn-sites Optional: These sites will return Warning if they are not in the expected state. Provide multiple with spaces between - H:stopped-sites Optional: These sites are checked that they are stopped. Provide multiple with spaces between - I:excluded-apppools Optional: Excludes apppools from checks and inventory. Provide multiple with spaces between - J:included-apppools Optional: Includes apppools to check while all other apppools are excluded, affects both checks and inventory. Provide multiple with spaces between - k:warn-apppools Optional: These apppools will return Warning if they are not in the expected state. Provide multiple with spaces between - K:stopped-apppools Optional: These apppools are checked that they are stopped. Provide multiple with spaces between - L:perfcounter-sites Parameter to use to get perfcounters from local Sites - M:perfcounter-apppools Parameter to use to get perfcounters from local AppPools - v:verbose Parameter to use when trying to figure out why a service is not included, excluded or similarly when the returned output is not as expected - V:single-check Used together with the Icinga2 Auto Apply rules, this is set when there is a single Site or AppPool to check. Do take great care if you use this outside of the auto apply rules. - w:expected-state Optional: Parameter to provide the expected State of the AppPool or Site, used together with --single-check - W:icinga2 Used in the Icinga2 CommandDefinition, returns output and perfcounter to the correct class. Do not use via command line. - x:hide-empty-vars Only print returned data that has values in them, skip empty arrays and vars. - X:inv-running-only Only inventory running Sites and/or AppPools, depending on what has been selected for inventory - -## Examples - -### Monitoring - -#### Application Pools -Monitor Application Pools - - check_iis.exe --check-apppools - -Monitor Application Pools, only monitor Application Pool ".NET v4.5" - - check_iis.exe --check-apppools --included-apppools ".NET v4.5" - -Monitor Application Pools, all should be started but for ".NET v4.5", which is expected to be stopped - - check_iis.exe --check-apppools --stopped-apppools ".NET v4.5" - -Monitor Application Pools, all should be started, if AppPool ".NET v2.0" is in a different state it should only warn - - check_iis.exe --check-apppools --warn-apppools ".NET v2.0" - -Monitor Application Pools, monitor all AppPools but for ".NET v2.0" - - check_iis.exe --check-apppools --excluded-apppools ".NET v2.0" - -Monitor Application Pools, monitor all but for ".NET 2.0" and".NET v4.5", in addition AppPool ".NET v4.5 Classic" should be stopped instead of running - - check_iis.exe --check-apppools --excluded_apppools ".NET v2.0" ".NET v4.5" --stopped-apppools ".NET v4.5 Classic" - -Monitor Application Pools, all AppPools should be running, with performance data - - check_iis.exe --check-apppools --perfcounter-apppools - -Monitor Application Pools, all AppPools should be running, excluded AppPool ".NET v2.0", with performance data - - check_iis.exe --check-apppools --perfcounter-apppools --excluded-apppools ".NET v2.0" - - -#### Sites -Monitor Sites - - check_iis.exe --check-websites - -Monitor Sites, only monitor Site ".NET v4.5" - - check_iis.exe --check-websites --included-sites ".NET v4.5" - -Monitor Sites, all should be started but for ".NET v4.5", which is expected to be stopped - - check_iis.exe --check-websites --stopped-sites ".NET v4.5" - -Monitor Sites, all should be started, if AppPool ".NET v2.0" is in a different state it should only warn - - check_iis.exe --check-websites --warn-sites ".NET v2.0" - -Monitor Sites, monitor all Sites but for ".NET v2.0" - - check_iis.exe --check-websites --excluded-sites ".NET v2.0" - -Monitor Sites, monitor all but for ".NET 2.0" and".NET v4.5", in addition AppPool ".NET v4.5 Classic" should be stopped instead of running - - check_iis.exe --check-websites --excluded-sites ".NET v2.0" ".NET v4.5" --stopped-sites ".NET v4.5 Classic" - -Monitor Sites, all Sites should be running, with performance data - - check_iis.exe --check-websites --perfcounter-sites - -Monitor Sites, all Sites should be running, excluded AppPool ".NET v2.0", with performance data - - check_iis.exe --check-websites --perfcounter-sites --excluded-sites ".NET v2.0" - -#### AppPools and Sites -Monitor Application Pools and Sites (all expected running) - - check_iis.exe --check-websites --apppools - -Monitor Application Pools and Sites with perfcounter - - check_iis.exe --apppools --perfcounter-apppools --check-websites --perfcounter-sites - -Monitor Application Pools (excluded ".NET v2.0") and Sites (excluded "WsusPool") - - check_iis.exe --apppools --perfcounter-apppools --check-websites --perfcounter-sites --excluded-apppools ".NET v2.0" --excluded-sites "WsusPool" - -### Inventory -#### AppPools -Inventory AppPools - - check_iis.exe --inventory-apppools - -Inventory AppPools, only inventory "DefaultAppPool" - - check_iis.exe --inventory-apppools --included-apppools "DefaultAppPool" - -Inventory AppPools, only return the running AppPools - - check_iis.exe --inventory-apppools --inv-running-only - -Inventory AppPools, only return the running AppPools, do not print empty arrays or keys with empty values - - check_iis.exe --inventory-apppools --inv-running-only --hide-empty-vars - -Inventory AppPools, all but ".NET v4.5" - - check_iis.exe --inventory-apppools --excluded-apppools ".NET v4.5" - -#### Sites -Inventory Sites - - check_iis.exe --inventory-websites - -Inventory Sites, only return the running Sites - - check_iis.exe --inventory-websites --inv-running-only - -Inventory Sites, all but "WsusPool" - - check_iis.exe --inventory-sites --excluded-sites "WsusPool" - -Inventory Sites, only inventory "Default Web Site", full inventory - - check_iis.exe --inventory-websites --included-sites "Default Web Site" --inv-level full - -Inventory Sites, only return the running Sites, do not print empty arrays or keys with empty values - - check_iis.exe --inventory-websites --inv-running-only --hide-empty-vars - -Inventory Sites, do not print empty arrays or keys with empty values, return it as icinga2 format configuration. - - check_iis.exe --inventory-websites --hide-empty-vars --inv-format i2conf - - -#### AppPools and Sites - -Inventory AppPools and Sites - - check_iis.exe --inventory-apppools --inventory-websites - -Inventory AppPools and Sites, only running - - check_iis.exe --inventory-apppools --inventory-websites --inv-running-only - -Inventory AppPools and Sites with all recognized details, as json - - check_iis.exe --inventory-apppools --inventory-websites --inv-level full --inv-format json - -Inventory AppPools and Sites with all recognized details, as json, only running - - check_iis.exe --inventory-apppools --inventory-websites --inv-level full --inv-format json --inv-running-only - -Inventory AppPools and Sites with all recognized details, as i2conf output, only running - - check_iis.exe --inventory-apppools --inventory-websites --inv-level full --inv-format i2conf --inv-running-only - -Inventory AppPools and Sites with all recognized details, as readable output, only running, hide empty vars - - check_iis.exe --inventory-apppools --inventory-websites --inv-level full --inv-format readable --inv-running-only --hide-empty-vars - - -## Configuration - -To make this plugin work with Icinga2, NSCP or others, it needs to be configured. -Below are some configuration examples on how to configure this plugin with Icinga2 (agent) and NSCP/NSClient++. - -### Icinga2 agent - -All configuration samples below assumes local configuration on agent, configuration for central use to come. - -#### Command Definition - - object CheckCommand "check_iis" { - import "plugin-check-command" - - command = [ PluginDir + "/check_iis.exe" ] - - arguments = { - "--check-apppools" = { - set_if = "$iis_check_apppools$" - description = "Parameter to use to check the health status of the local Sites" - } - "--check-websites" = { - set_if = "$iis_check_sites$" - description = "Parameter to use to check the health status of the local Sites" - } - "--inventory-apppools" = { - set_if = "$iis_inventory_apppools$" - description = "Parameter to use to provide inventory of apppools instead of checking for the health." - } - "--inventory-websites" = { - set_if = "$iis_inventory_sites$" - description = "Parameter to use to provide inventory of sites instead of checking for the health." - } - "--inv-level" = { - value = "$iis_inventory_level$" - description = "Optional parameter to change the level of output. Default is 'normal', available options are 'normal','full'" - } - "--inv-format" = { - value = "$iis_inventory_format$" - description = "Optional parameter to provide output of the inventory in other formats, valid options are 'readable', 'i2conf' and 'json'" - } - "--excluded-sites" = { - value = "$iis_excluded_sites$" - description = "Optional: Excludes sites from checks and inventory. Provide multiple with spaces between" - } - "--included-sites" = { - value = "$iis_included_sites$" - description = "Optional: Includes sites to check while all other sites are excluded, affects both checks and inventory. Provide multiple with spaces between" - } - "--warn-sites" = { - value = "$iis_warn_sites$" - description = "Optional: These sites will return Warning if they are not in the expected state. Provide multiple with spaces between" - } - "--stopped-sites" = { - value = "$iis_stopped_sites$" - description = "Optional: These sites are checked that they are stopped. Provide multiple with spaces between" - } - "--excluded-apppools" = { - value = "$iis_excluded_apppools$" - description = "Optional: Excludes apppools from checks and inventory. Provide multiple with spaces between" - } - "--included-apppools" = { - value = "$iis_included_apppools$" - description = "Optional: Includes apppools to check while all other apppools are excluded, affects both checks and inventory. Provide multiple with spaces between" - } - "--warn-apppools" = { - value = "$iis_warn_apppools$" - description = "Optional: These apppools will return Warning if they are not in the expected state. Provide multiple with spaces between" - } - "--stopped-apppools" = { - value = "$iis_stopped_apppools$" - description = "Optional: These apppools are checked that they are stopped. Provide multiple with spaces between" - } - "--perfcounter-sites" = { - set_if = "$iis_perfcounter_sites$" - description = "Parameter to use to get basic performance counters for the Sites" - } - "--perfcounter-apppools" = { - set_if = "$iis_perfcounter_apppools$" - description = "Parameter to use to get basic performance counters for the AppPools" - } - "--inv-running-only" = { - set_if = "$iis_inv_running_only$" - description = "Only inventory running Sites and/or AppPools, depending on what has been selected for inventory" - } - "--hide-empty-vars" = { - set_if = "$inv_hide_empty_vars$" - description = "Optional parameter for inventory: Only print returned data that has values in them, skip empty arrays and vars." - } - "--icinga2" = { - set_if = "$iis_icinga2$" - description = "Used in the Icinga2 CommandDefinition, returns output and perfdata to the correct class. Do not use via command line." - } - "--single-check" = { - set_if = "$iis_single_check$" - description = "Used together with the Icinga2 Auto Apply rules, this is set when there is a single Site or AppPool to check. Do take great care if you use this outside of the auto apply rules." - } - "--expected-state" = { - set_if = "$iis_single_check$" - value = "$iis_expected_state$" - description = "Optional: Parameter to provide the expected State of the AppPool or Site, used together with --single-check" - } - "--verbose" = { - set_if = "$iis_verbose$" - description = "Only inventory running Sites and/or AppPools, depending on what has been selected for inventory" - } - } - vars.iis_check_apppools = false - vars.iis_check_sites = false - vars.iis_perfcounter_apppools = false - vars.iis_perfcounter_sites = false - vars.iis_inventory_apppools = false - vars.iis_inventory_sites = false - vars.iis_inv_running_only = false - vars.iis_inv_hide_empty_vars = false - vars.iis_icinga2 = false - vars.iis_verbose = false - vars.iis_expected_state = "Started" - vars.iis_single_check = false - - } - -#### AppPool Monitoring -Monitor all AppPools, does not need any data from inventory. - - apply Service "IIS AppPools"{ - import "generic-service" - - check_command = "check_iis" - - assign where host.name == NodeName - - vars.iis_check_apppools = true - vars.iis_stopped_apppools = "" - } - -Monitor all AppPools, same as above, just added with perfcounter option. - - apply Service "IIS AppPools"{ - import "generic-service" - - check_command = "check_iis" - - assign where host.name == NodeName - - vars.iis_check_apppools = true - vars.iis_perfcounter_apppools = true - vars.iis_stopped_apppools = "" - } - -Monitors AppPools based on inventory data (stored in the host object), this specific apply rule only adds running apppools to monitoring, with perfcounters - - apply Service "IIS AppPoolR " for (name => config in host.vars.inv.iis.apppool) { - import "generic-service" - - check_command = "check_iis" - - vars += config - vars.iis_check_apppools = true - vars.iis_included_apppools = vars.Name - vars.iis_perfcounter_apppools = true - assign where config.State == "Started" - } - -Monitors AppPools based on inventory data (stored in the host object), this specific apply rule only adds stopped apppools to monitoring, with perfcounters - - apply Service "IIS AppPoolS " for (name => config in host.vars.inv.iis.apppool) { - import "generic-service" - - check_command = "check_iis" - - vars += config - vars.iis_check_apppools = true - vars.iis_included_apppools = vars.Name - vars.iis_stopped_apppools = vars.Name - vars.iis_perfcounter_apppools = true - assign where config.State == "Stopped" - } - -Recommended method: Monitors AppPools based on inventory data (stored in the host object), this specific apply rule adds uses the state from inventory, with perfcounters - - apply Service "IIS AppPool " for (name => config in host.vars.inv.iis.apppool) { - import "generic-service" - - check_command = "check_iis" - - vars += config - vars.iis_check_apppools = true - vars.iis_included_apppools = vars.Name - vars.iis_perfcounter_apppools = true - vars.iis_expected_state = vars.State - vars.iis_single_check = true - } - - -#### Monitor Sites -Monitors all Sites, does not use inventory data. - - apply Service "IIS Sites"{ - import "generic-service" - - check_command = "check_iis" - - vars.iis_check_sites = true - vars.iis_perfcounter_sites = true - - assign where host.name == NodeName - - } - -Monitors all Sites, does not use inventory data, the same as above, just added perfcounters. - - apply Service "IIS Sites"{ - import "generic-service" - - check_command = "check_iis" - - vars.iis_check_sites = true - vars.iis_perfcounter_sites = true - assign where host.name == NodeName - - } - -Monitors Sites based on inventory data (stored in the host object), this specific apply rule only adds running sites to monitoring, with perfcounters - - apply Service "IIS SiteR " for (name => config in host.vars.inv.iis.site) { - import "generic-service" - - check_command = "check_iis" - - vars += config - vars.iis_check_sites = true - vars.iis_included_sites = vars.Name - vars.iis_perfcounter_sites = true - assign where config.State == "Started" - } - -Monitors Sites based on inventory data (stored in the host object), this specific apply rule only adds stopped Sites to monitoring, with perfcounters - - apply Service "IIS SiteS " for (name => config in host.vars.inv.iis.site) { - import "generic-service" - - check_command = "check_iis" - - vars += config - vars.iis_check_sites = true - vars.iis_included_sites = vars.Name - vars.iis_stopped_sites = vars.Name - vars.iis_perfcounter_sites = true - assign where config.State == "Stopped" - } - -Recommended method: Monitors Sites based on inventory data (stored in the host object), this specific apply rule adds uses the state from inventory, with perfcounters - - apply Service "IIS Site " for (name => config in host.vars.inv.iis.site) { - import "generic-service" - - check_command = "check_iis" - - vars += config - vars.iis_check_sites = true - vars.iis_included_sites = vars.Name - vars.iis_perfcounter_sites = true - vars.iis_expected_state = vars.State - vars.iis_single_check = true - } - -### NSCP / NSClient++ -ToDo - -Add in nsclient.ini - -Test via check_nrpe or similar to verify. \ No newline at end of file diff --git a/Solution/check_iis/Program.cs b/Solution/check_iis/Program.cs index e8c8231..e22b05e 100644 --- a/Solution/check_iis/Program.cs +++ b/Solution/check_iis/Program.cs @@ -1,71 +1,79 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; -using Microsoft.Win32; -using Microsoft.Web.Administration; +using Fclp; using Icinga; -using Fclp; +using Microsoft.Web.Administration; +using Microsoft.Win32; using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; namespace MonitoringPluginsForWindows { - class check_iis + public class check_iis { - - static List listPerfData = new List(); - static List listSiteOutput = new List(); - static List listAppPoolOutput = new List(); - - static List listIISInventory = new List(); - static List listAppPoolsOnComputer = new List(); - static List listSitesOnComputer = new List(); - static List listStoppedSites = new List(); - static List listStartedSites = new List(); - static List listStoppedAppPools = new List(); - static List listStartedAppPools = new List(); - - static string outputAppPools = ""; - static string outputSites = ""; - static string iisVersion = "unspecified"; - - static bool errorAppPools = false; - static bool errorSites = false; - - static bool do_debug = false; - static bool do_verbose = false; - static bool do_i2 = false; - - static bool bDefaultSitesIncluded = false; - static bool bDefaultSitesExcluded = false; - static bool bDefaultSitesStopped = false; - static bool bDefaultSitesWarn = false; - - static bool bDefaultAppPoolsIncluded = false; - static bool bDefaultAppPoolsExcluded = false; - static bool bDefaultAppPoolsStopped = false; - static bool bDefaultAppPoolsWarn = false; - - static int iNumberOfAppPools = 0; - static int iNumberOfStartedAppPools = 0; - static int iNumberOfStoppedAppPools = 0; - static int iNumberOfStoppingAppPools = 0; - static int iNumberOfStartingAppPools = 0; - static int iNumberOfUnknownAppPools = 0; - static int iNumberOfCorrectAppPools = 0; - static int iNumberOfWrongAppPools = 0; - - static int iNumberOfSites = 0; - static int iNumberOfStartedSites = 0; - static int iNumberOfStoppedSites = 0; - static int iNumberOfStoppingSites = 0; - static int iNumberOfStartingSites = 0; - static int iNumberOfUnknownSites = 0; - static int iNumberOfCorrectSites = 0; - static int iNumberOfWrongSites = 0; - - static int Main(string[] args) + private static List listPerfData = new List(); + private static List listSiteOutput = new List(); + private static List listAppPoolOutput = new List(); + + private static List listIISInventory = new List(); + private static List listAppPoolsOnComputer = new List(); + private static List listSitesOnComputer = new List(); + private static List listStoppedSites = new List(); + private static List listStartedSites = new List(); + private static List listStoppedAppPools = new List(); + private static List listStartedAppPools = new List(); + + private static string[] excluded_sites = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; + private static string[] included_sites = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; + private static string[] stopped_sites = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; + private static string[] warn_sites = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; + + private static string[] excluded_apppools = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; + private static string[] included_apppools = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; + private static string[] stopped_apppools = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; + private static string[] warn_apppools = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; + + private static string outputAppPools = ""; + private static string outputSites = ""; + private static string iisVersion = "unspecified"; + + private static bool errorAppPools = false; + private static bool errorSites = false; + + private static bool do_debug = false; + private static bool do_verbose = false; + private static bool do_i2 = false; + + private static bool bDefaultSitesIncluded = false; + private static bool bDefaultSitesExcluded = false; + private static bool bDefaultSitesStopped = false; + private static bool bDefaultSitesWarn = false; + + private static bool bDefaultAppPoolsIncluded = false; + private static bool bDefaultAppPoolsExcluded = false; + private static bool bDefaultAppPoolsStopped = false; + private static bool bDefaultAppPoolsWarn = false; + + private static int iNumberOfAppPools = 0; + private static int iNumberOfStartedAppPools = 0; + private static int iNumberOfStoppedAppPools = 0; + private static int iNumberOfStoppingAppPools = 0; + private static int iNumberOfStartingAppPools = 0; + private static int iNumberOfUnknownAppPools = 0; + private static int iNumberOfCorrectAppPools = 0; + private static int iNumberOfWrongAppPools = 0; + + private static int iNumberOfSites = 0; + private static int iNumberOfStartedSites = 0; + private static int iNumberOfStoppedSites = 0; + private static int iNumberOfStoppingSites = 0; + private static int iNumberOfStartingSites = 0; + private static int iNumberOfUnknownSites = 0; + private static int iNumberOfCorrectSites = 0; + private static int iNumberOfWrongSites = 0; + + private static int Main(string[] args) { int returncode = 0; int temp = 3; @@ -80,20 +88,12 @@ static int Main(string[] args) bool do_skip_empty_vars = false; bool do_singluar_check = false; bool do_skip_empty_apppools = false; + bool do_hide_long_output = false; string inventory_format = "readable"; string inventory_level = "normal"; string expected_state = "NotSet"; - - string[] excluded_sites = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; - string[] included_sites = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; - string[] stopped_sites = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; - string[] warn_sites = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; - - string[] excluded_apppools = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; - string[] included_apppools = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; - string[] stopped_apppools = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; - string[] warn_apppools = new string[] { "thisshouldprobablyneverbeoverwrittenbysomething" }; + string split_by = " "; List temp_excluded_sites = new List(); List temp_included_sites = new List(); @@ -107,110 +107,118 @@ static int Main(string[] args) var p = GetP(); - p.Setup('Z', "debug") - .Callback(value => do_debug = value) - .WithDescription("\t\tParameter to to get maximum verbosity (for debugging)") - .SetDefault(false); - - p.Setup('v', "verbose") - .Callback(value => do_verbose = value) - .WithDescription("\tParameter to use when trying to figure out why a service is not included, excluded or similarly when the returned output is not as expected") - .SetDefault(false); + p.Setup('a', "inventory-apppools") + .WithDescription("Switch to use to provide inventory of AppPools.") + .Callback(value => do_inventory_apppools = value); p.Setup('A', "inventory-websites") - .WithDescription("Parameter to use to provide inventory instead of checking for the health.") + .WithDescription("Switch to use to provide inventory of Sites") .Callback(value => do_inventory_sites = value); - p.Setup('a', "inventory-apppools") - .WithDescription("Parameter to use to provide inventory instead of checking for the health.") - .Callback(value => do_inventory_apppools = value); - p.Setup('B', "check-websites") - .WithDescription("Parameter to use to check the health status of the local Sites") + .WithDescription("Switch to use to check the health status of the local Sites") .Callback(value => do_sites = value); p.Setup('C', "check-apppools") - .WithDescription("Parameter to use to check the health status of the local AppPools") + .WithDescription("Switch to use to check the health status of the local AppPools") .Callback(value => do_apppools = value); - p.Setup('f', "inv-format") - .Callback(value => inventory_format = value) - .WithDescription("\tOptional: Parameter to provide output of the inventory in other formats, valid options are 'readable', 'i2conf' and 'json'") - .SetDefault("readable"); - p.Setup('E', "inv-level") .Callback(value => inventory_level = value) - .WithDescription("\tOptional: Parameter to change the level of output. Default is 'normal', available options are 'normal','full'") + .WithDescription("\tArgument to change the level of output. Default is 'normal', available options are 'normal','full'") .SetDefault("normal"); - p.Setup('X', "inv-running-only") - .WithDescription("Only inventory running Sites and/or AppPools, depending on what has been selected for inventory") - .Callback(value => do_all_running_only = value); - - p.Setup('x', "hide-empty-vars") - .WithDescription("Only print returned data that has values in them, skip empty arrays and vars.") - .Callback(value => do_skip_empty_vars = value); - - p.Setup('W', "icinga2") - .WithDescription("\tUsed in the Icinga2 CommandDefinition, returns output and perfcounter to the correct class. Do not use via command line.") - .Callback(value => do_i2 = value); - - p.Setup('V', "single-check") - .WithDescription("\tUsed together with the Icinga2 Auto Apply rules, this is set when there is a single Site or AppPool to check. Do take great care if you use this outside of the auto apply rules.") - .Callback(value => do_singluar_check = value); - - p.Setup('U', "skip-empty-apppools") - .WithDescription("Optional: Do not inventory AppPools which are empty.") - .Callback(value => do_skip_empty_apppools = value); - - p.Setup('w', "expected-state") - .Callback(value => expected_state = value) - .WithDescription("Optional: Parameter to provide the expected State of the AppPool or Site, used together with --single-check"); + p.Setup('f', "inv-format") + .Callback(value => inventory_format = value) + .WithDescription("\tArgument to provide output of the inventory in other formats, valid options are 'readable', 'i2conf' and 'json'") + .SetDefault("readable"); p.Setup>('F', "excluded-sites") - .WithDescription("Optional: Excludes sites from checks and inventory. Provide multiple with spaces between") + .WithDescription("Excludes Sites from checks and inventory. Provide multiple with spaces between") .Callback(items => temp_excluded_sites = items); p.Setup>('G', "included-sites") - .WithDescription("Optional: Includes sites to check while all other sites are excluded, affects both checks and inventory. Provide multiple with spaces between") + .WithDescription("Includes Sites to check while all other Sites are excluded, affects both checks and inventory. Provide multiple with spaces between") .Callback(items => temp_included_sites = items); - p.Setup>('H', "stopped-sites") - .WithDescription("\tOptional: These sites are checked that they are stopped. Provide multiple with spaces between") + p.Setup>('h', "stopped-sites") + .WithDescription("\tThe specified Sites are checked that they are stopped. Provide multiple with spaces between") .Callback(items => temp_stopped_sites = items); - p.Setup>('h', "warn-sites") - .WithDescription("\tOptional: These sites will return Warning if they are not in the expected state. Provide multiple with spaces between") + p.Setup>('H', "warn-sites") + .WithDescription("\tThese specified Sites will return Warning if they are not in the expected state. Provide multiple with spaces between") .Callback(items => temp_warn_sites = items); + p.Setup('i', "perfcounter-sites") + .WithDescription("Switch to use to get perfcounters from local Sites") + .Callback(value => do_perfcounter_sites = value); + p.Setup>('I', "excluded-apppools") - .WithDescription("Optional: Excludes apppools from checks and inventory. Provide multiple with spaces between") + .WithDescription("Excludes AppPools from checks and inventory. Provide multiple with spaces between") .Callback(items => temp_excluded_apppools = items); p.Setup>('J', "included-apppools") - .WithDescription("Optional: Includes apppools to check while all other apppools are excluded, affects both checks and inventory. Provide multiple with spaces between") + .WithDescription("Includes apppools to check while all other AppPools are excluded, affects both checks and inventory. Provide multiple with spaces between") .Callback(items => temp_included_apppools = items); - p.Setup>('K', "stopped-apppools") - .WithDescription("Optional: These apppools are checked that they are stopped. Provide multiple with spaces between") + p.Setup>('k', "stopped-apppools") + .WithDescription("The specified AppPools are checked that they are stopped. Provide multiple with spaces between") .Callback(items => temp_stopped_apppools = items); - p.Setup>('k', "warn-apppools") - .WithDescription("\tOptional: These apppools will return Warning if they are not in the expected state. Provide multiple with spaces between") + p.Setup>('K', "warn-apppools") + .WithDescription("\tThe specified AppPools will return Warning if they are not in the expected state. Provide multiple with spaces between") .Callback(items => temp_warn_apppools = items); - p.Setup('L', "perfcounter-sites") - .WithDescription("Parameter to use to get perfcounters from local Sites") - .Callback(value => do_perfcounter_sites = value); - - p.Setup('M', "perfcounter-apppools") - .WithDescription("Parameter to use to get perfcounters from local AppPools") + p.Setup('l', "perfcounter-apppools") + .WithDescription("Switch to use to get perfcounters from local AppPools") .Callback(value => do_perfcounter_apppools = value); + p.Setup('L', "skip-empty-apppools") + .WithDescription("Switch which sets do not inventory AppPools which are empty or unused.") + .Callback(value => do_skip_empty_apppools = value); + + p.Setup('T', "hide-long-output") + .WithDescription("Switch to hide the long service output, only prints the summary output and any Sites or Services deviating from 'OK'") + .Callback(value => do_hide_long_output = value); + + p.Setup('u', "expected-state") + .Callback(value => expected_state = value) + .WithDescription("Argument to provide the expected State of the AppPool or Site, used together with --single-check"); + + p.Setup('w', "icinga2") + .WithDescription("\tSwitch used in the Icinga2 CommandDefinition, returns output and perfcounter to the correct class. Do not use via command line.") + .Callback(value => do_i2 = value); + + p.Setup('W', "single-check") + .WithDescription("\tSwitch used together with the Icinga2 Auto Apply rules, this is set when there is a single Site or AppPool to check. Do take great care if you use this outside of the auto apply rules.") + .Callback(value => do_singluar_check = value); + + p.Setup('x', "split-by") + .WithDescription("\tArgument used to specify what splits all Sites and AppPool arguments. Default is a single space, ' '.") + .Callback(value => split_by = value); + + p.Setup('X', "inv-hide-empty") + .WithDescription("Switch to hide empty vars from inventory output.") + .Callback(value => do_skip_empty_vars = value); + + p.Setup('y', "inv-running-only") + .WithDescription("Switch to only inventory running Sites and/or AppPools, depending on what has been selected for inventory") + .Callback(value => do_all_running_only = value); + + p.Setup('z', "verbose") + .Callback(value => do_verbose = value) + .WithDescription("\tSwitch to use when trying to figure out why a service is not included, excluded or similarly when the returned output is not as expected") + .SetDefault(false); + + p.Setup('Z', "debug") + .Callback(value => do_debug = value) + .WithDescription("\t\tSwitch to to get maximum verbosity (for debugging)") + .SetDefault(false); + p.SetupHelp("?", "help") .Callback(text => Console.WriteLine(text)) .UseForEmptyArgs() - .WithHeader("\t" + System.AppDomain.CurrentDomain.FriendlyName + " - Windows Service Status plugin for Icinga2, Icinga, Centreon, Shinken, Naemon and other nagios like systems.\n\tVersion: " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); + .WithHeader(System.AppDomain.CurrentDomain.FriendlyName + " - Windows Service Status plugin for Icinga2, Icinga, Centreon, Shinken, Naemon and other nagios like systems.\n\tVersion: " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); var result = p.Parse(args); @@ -220,82 +228,105 @@ static int Main(string[] args) return (int)ServiceState.ServiceUnknown; } + // Lets see which of the supplied switches changed anything in the include/exclude/stopped context + HandleArguments(temp_excluded_sites, temp_included_sites, temp_stopped_sites, temp_warn_sites, + temp_excluded_apppools, temp_included_apppools, temp_stopped_apppools, temp_warn_apppools, split_by); + + // Inventory is blocked from running at the same time as other checks, thus it is run first if specified. + if (do_inventory_apppools == true || do_inventory_sites == true) + { + temp = IisInventory(do_sites, do_apppools, do_inventory_sites, do_inventory_apppools, inventory_format, inventory_level, do_all_running_only, do_skip_empty_vars, do_skip_empty_apppools); + return temp; + } + + if (do_apppools == true) + { + returncode = CheckAllAppPools(returncode, do_perfcounter_apppools, do_singluar_check, expected_state); + } + if (do_sites == true) + { + returncode = CheckAllSites(returncode, do_perfcounter_sites, do_singluar_check, expected_state); + } + + returncode = HandleExitText(returncode, do_hide_long_output); + + return (int)returncode; + } + + private static FluentCommandLineParser GetP() + { + return new FluentCommandLineParser(); + } + + private static string[] SplitList(List items, string split_by) + { + if (split_by == null) + { + throw new ArgumentNullException("split_by"); + } + else if (split_by == " ") + { + return items.ToArray(); + } + else + { + return items.Select(item => item.Split(split_by.ToCharArray())) + .SelectMany(str => str) + .ToArray(); + } + } + + private static void HandleArguments(List temp_excluded_sites, List temp_included_sites, List temp_stopped_sites, List temp_warn_sites, + List temp_excluded_apppools, List temp_included_apppools, List temp_stopped_apppools, List temp_warn_apppools, string split_by) + { if (temp_excluded_sites.Count > 0) { - excluded_sites = temp_excluded_sites.Select(i => i.ToString()).ToArray(); + excluded_sites = SplitList(temp_excluded_sites, split_by); PrintArray("excluded_sites", excluded_sites); } + if (temp_included_sites.Count > 0) { - included_sites = temp_included_sites.Select(i => i.ToString()).ToArray(); + included_sites = SplitList(temp_included_sites, split_by); PrintArray("included_sites", included_sites); } + if (temp_stopped_sites.Count > 0) { - stopped_sites = temp_stopped_sites.Select(i => i.ToString()).ToArray(); + stopped_sites = SplitList(temp_stopped_sites, split_by); PrintArray("stopped_sites", stopped_sites); } + if (temp_warn_sites.Count > 0) { - warn_sites = temp_warn_sites.Select(i => i.ToString()).ToArray(); + warn_sites = SplitList(temp_warn_sites, split_by); PrintArray("warn_sites", warn_sites); } + if (temp_excluded_apppools.Count > 0) { - excluded_apppools = temp_excluded_apppools.Select(i => i.ToString()).ToArray(); + excluded_apppools = SplitList(temp_excluded_apppools, split_by); PrintArray("excluded_apppools", excluded_apppools); } + if (temp_included_apppools.Count > 0) { - included_apppools = temp_included_apppools.Select(i => i.ToString()).ToArray(); + included_apppools = SplitList(temp_included_apppools, split_by); PrintArray("included_apppools", included_apppools); } + if (temp_stopped_apppools.Count > 0) { - stopped_apppools = temp_stopped_apppools.Select(i => i.ToString()).ToArray(); + stopped_apppools = SplitList(temp_stopped_apppools, split_by); PrintArray("stopped_apppools", stopped_apppools); } + if (temp_warn_apppools.Count > 0) { - warn_apppools = temp_warn_apppools.Select(i => i.ToString()).ToArray(); + warn_apppools = SplitList(temp_warn_apppools, split_by); PrintArray("warn_apppools", warn_apppools); } - - // Lets see which of the supplied switches changed anything in the include/exclude/stopped context - CalculateDefaultValues(excluded_sites, included_sites, stopped_sites, warn_sites, excluded_apppools, included_apppools, stopped_apppools, warn_apppools); - - // Inventory is blocked from running at the same time as other checks, thus it is run first if specified. - if (do_inventory_apppools == true || do_inventory_sites == true) - { - temp = IisInventory(do_sites, do_apppools, do_inventory_sites, do_inventory_apppools, excluded_apppools, included_apppools, - excluded_sites, included_sites, inventory_format, inventory_level, do_all_running_only, do_skip_empty_vars, do_skip_empty_apppools); - return temp; - } - - if (do_apppools == true) - { - returncode = CheckAllAppPools(returncode, do_perfcounter_apppools, excluded_apppools, included_apppools, stopped_apppools, warn_apppools, do_singluar_check, expected_state); - } - if (do_sites == true) - { - returncode = CheckAllSites(returncode, do_perfcounter_sites, excluded_sites, included_sites, stopped_sites, warn_sites, do_singluar_check, expected_state); - } - - returncode = HandleExitText(returncode); - - return (int)returncode; - - } - - private static FluentCommandLineParser GetP() - { - return new FluentCommandLineParser(); - } - - private static void CalculateDefaultValues(string[] excluded_sites, string[] included_sites, string[] stopped_sites, string[] warn_sites, - string[] excluded_apppools, string[] included_apppools, string[] stopped_apppools, string[] warn_apppools) - { if (excluded_sites.Contains("thisshouldprobablyneverbeoverwrittenbysomething")) { if (do_verbose == true) @@ -354,9 +385,8 @@ private static void CalculateDefaultValues(string[] excluded_sites, string[] inc return; } - private static int HandleExitText(int returncode) + private static int HandleExitText(int returncode, bool do_hide_long_output) { - // ORDER the output string output = ""; if ((errorAppPools == true) && (errorSites == false)) @@ -395,38 +425,39 @@ private static int HandleExitText(int returncode) } string outputLong = ""; - - int x = 1; - if (iNumberOfSites > 1) - { - foreach (string outputW in listSiteOutput) + if (do_hide_long_output == false) { + int x = 1; + if (iNumberOfSites > 1) { - if (x < listSiteOutput.Count) + foreach (string outputW in listSiteOutput) { - outputLong = outputLong + outputW + "\n"; + if (x < listSiteOutput.Count) + { + outputLong = outputLong + outputW + "\n"; + } + else + { + outputLong = outputLong + outputW; + } + x++; } - else - { - outputLong = outputLong + outputW; - } - x++; } - } - int y = 1; - if (iNumberOfAppPools > 1) - { - foreach (string outputA in listAppPoolOutput) + int y = 1; + if (iNumberOfAppPools > 1) { - if (y < listAppPoolOutput.Count) + foreach (string outputA in listAppPoolOutput) { - outputLong = outputLong + outputA + "\n"; + if (y < listAppPoolOutput.Count) + { + outputLong = outputLong + outputA + "\n"; + } + else + { + outputLong = outputLong + outputA; + } + y++; } - else - { - outputLong = outputLong + outputA; - } - y++; } } string perfdata = ""; @@ -439,15 +470,23 @@ private static int HandleExitText(int returncode) { CheckResult IcingaOutput = new CheckResult(); IcingaOutput.State = (ServiceState)returncode; - IcingaOutput.Output = output + outputLong; + if (do_hide_long_output == false) + { + IcingaOutput.Output = output + outputLong; + } + else + { + IcingaOutput.Output = output; + } + IcingaOutput.PerformanceData = perfdata; } else { - Console.WriteLine(output); - if (iNumberOfAppPools > 1 || iNumberOfSites > 1) - Console.WriteLine(outputLong); - Console.WriteLine(" | " + perfdata); + Console.Write(output); + if ((iNumberOfAppPools > 1 || iNumberOfSites > 1) && do_hide_long_output == false) + Console.Write("\n" + outputLong); + Console.Write(" | " + perfdata); } return returncode; @@ -490,12 +529,10 @@ private static int ReturnCodeMagic(int current_returncode, int suggested_returnc } return suggested_returncode; } - } - private static int IisInventory(bool do_sites, bool do_apppools, bool do_inventory_sites, bool do_inventory_apppools, string[] excluded_apppools, - string[] included_apppools, string[] excluded_sites, string[] included_sites, string inventory_format, string inventory_level, bool do_running_only, - bool do_skip_empty_vars, bool do_skip_empty_apppools) + private static int IisInventory(bool do_sites, bool do_apppools, bool do_inventory_sites, bool do_inventory_apppools, + string inventory_format, string inventory_level, bool do_running_only, bool do_skip_empty_vars, bool do_skip_empty_apppools) { var iisManager = new ServerManager(); @@ -517,11 +554,10 @@ private static int IisInventory(bool do_sites, bool do_apppools, bool do_invento if (do_verbose) Console.WriteLine("INFO: Inventory of Sites to check later"); - temp = InventorySites(iisManager, excluded_sites, included_sites, false, false, false); + temp = InventorySites(iisManager, false, false, false); if (temp == false) return (int)ServiceState.ServiceUnknown; - } if (do_inventory_sites) @@ -529,11 +565,10 @@ private static int IisInventory(bool do_sites, bool do_apppools, bool do_invento if (do_verbose) Console.WriteLine("INFO: Inventory of Sites"); - temp = InventorySites(iisManager, excluded_sites, included_sites, bVerboseInventory, do_running_only, true); + temp = InventorySites(iisManager, bVerboseInventory, do_running_only, true); if (temp == false) return (int)ServiceState.ServiceUnknown; - } if (do_apppools) @@ -541,11 +576,10 @@ private static int IisInventory(bool do_sites, bool do_apppools, bool do_invento if (do_verbose) Console.WriteLine("INFO: Inventory of AppPools to check later"); - temp = InventoryAppPools(iisManager, excluded_apppools, included_apppools, false, false, false, false); + temp = InventoryAppPools(iisManager, false, false, false, false); if (temp == false) return (int)ServiceState.ServiceUnknown; - } if (do_inventory_apppools) @@ -553,11 +587,10 @@ private static int IisInventory(bool do_sites, bool do_apppools, bool do_invento if (do_verbose) Console.WriteLine("INFO: Inventory of AppPools"); - temp = InventoryAppPools(iisManager, excluded_apppools, included_apppools, bVerboseInventory, do_running_only, true, do_skip_empty_apppools); + temp = InventoryAppPools(iisManager, bVerboseInventory, do_running_only, true, do_skip_empty_apppools); if (temp == false) return (int)ServiceState.ServiceUnknown; - } if (do_inventory_apppools || do_inventory_sites) @@ -588,7 +621,6 @@ private static int IisInventory(bool do_sites, bool do_apppools, bool do_invento private static bool InventoryOutputJSON() { - string json = JsonConvert.SerializeObject(listIISInventory, Formatting.Indented); Console.WriteLine(json); @@ -606,7 +638,6 @@ private static bool InventoryOutputI2Conf(bool do_inventory_apppools, bool do_in string i2conf1 = ""; if (do_inventory_sites == true) { - i2conf1 = IcingaSerializer.Serialize(listStoppedSites.ToArray(), do_skip_empty_vars); Console.WriteLine("vars.inv.iis.sites.stopped = " + i2conf1); @@ -623,7 +654,6 @@ private static bool InventoryOutputI2Conf(bool do_inventory_apppools, bool do_in if (do_inventory_apppools == true) { - i2conf1 = IcingaSerializer.Serialize(listStoppedAppPools.ToArray(), do_skip_empty_vars); Console.WriteLine("vars.inv.iis.apppools.stopped = " + i2conf1); @@ -636,7 +666,6 @@ private static bool InventoryOutputI2Conf(bool do_inventory_apppools, bool do_in Console.WriteLine("vars.inv.iis.apppool[\"" + AppPool.Name + "\"] = " + i2conf); Console.WriteLine(""); } - } return true; @@ -667,13 +696,10 @@ private static bool InventoryOutputReadable(bool do_inventory_apppools, bool do_ { string readable = ReadableSerializer.Serialize(AppPool, do_skip_empty_vars); Console.WriteLine(readable); - } - } return true; - } public static int IisInstalled() @@ -694,9 +720,8 @@ public static int IisInstalled() } } - private static bool InventorySites(ServerManager iisManager, string[] excluded_sites, string[] included_sites, bool bVerboseInventory, bool do_running_only, bool do_inventory) + private static bool InventorySites(ServerManager iisManager, bool bVerboseInventory, bool do_running_only, bool do_inventory) { - SiteCollection sites = iisManager.Sites; foreach (Site Site in sites) { @@ -740,7 +765,6 @@ private static bool InventorySites(ServerManager iisManager, string[] excluded_s continue; } - } if (do_inventory == true && Site.State == ObjectState.Started) @@ -756,18 +780,16 @@ private static bool InventorySites(ServerManager iisManager, string[] excluded_s Console.WriteLine("AppPool in a bad state during inventory!"); } - Array SiteBindings = InventorySiteBindings(Site, bVerboseInventory); Array SiteApplications = InventorySiteApplications(Site, bVerboseInventory); listSitesOnComputer.Add(new WebSite(Site.Id, Site.Name, Site.ServerAutoStart, Site.IsLocallyStored, Site.State.ToString(), Site.LogFile.Directory, Site.LogFile.Enabled, SiteBindings, SiteApplications)); - } return true; } - private static bool InventoryAppPools(ServerManager iisManager, string[] excluded_apppools, string[] included_apppools, bool bVerboseInventory, bool do_running_only, bool do_inventory, bool do_skip_empty_apppools) + private static bool InventoryAppPools(ServerManager iisManager, bool bVerboseInventory, bool do_running_only, bool do_inventory, bool do_skip_empty_apppools) { ApplicationPoolCollection appPools = iisManager.ApplicationPools; @@ -819,7 +841,7 @@ private static bool InventoryAppPools(ServerManager iisManager, string[] exclude { int NumberOfTimesUsed = GetNumberApplicationsInAppPool(iisManager, sAppPoolName); if (NumberOfTimesUsed == 0) - { + { if (do_verbose) Console.WriteLine("INFO: AppPool '" + sAppPoolName + "' is not used by any Applications, this is being skipped due to skip-empty-apppools set"); // Skip, this AppPool is not used anywhere @@ -848,11 +870,11 @@ private static bool InventoryAppPools(ServerManager iisManager, string[] exclude AppPool.ProcessModel.IdleTimeout, AppPool.ProcessModel.LoadUserProfile, AppPool.ProcessModel.MaxProcesses, AppPool.ProcessModel.PingingEnabled, AppPool.ProcessModel.UserName, AppPool.Cpu.SmpAffinitized, Enum.GetName(typeof(LoadBalancerCapabilities), AppPool.Failure.LoadBalancerCapabilities) , ArrWorkerProcesses)); - } return true; } - private static int GetNumberApplicationsInAppPool(ServerManager iisManager , string AppPoolName) + + private static int GetNumberApplicationsInAppPool(ServerManager iisManager, string AppPoolName) { int NumberOfTimesUsed = 0; foreach (Site site in iisManager.Sites) @@ -865,6 +887,7 @@ private static int GetNumberApplicationsInAppPool(ServerManager iisManager , str } return NumberOfTimesUsed; } + private static Array InventoryWorkerProcesses(ApplicationPool AppPool, bool bVerboseInventory) { List listAppPoolWorkerProcesses = new List(); @@ -875,7 +898,6 @@ private static Array InventoryWorkerProcesses(ApplicationPool AppPool, bool bVer foreach (var WorkerProcess in AppPool.WorkerProcesses) { - Array temp_AppPoolWorkerProcessAppDomains = InventoryWPAppDomains(WorkerProcess.ApplicationDomains, AppPool, bVerboseInventory); listAppPoolWorkerProcesses.Add(new AppPoolWorkerProcesses(WorkerProcess.AppPoolName, WorkerProcess.IsLocallyStored, @@ -896,12 +918,10 @@ private static Array InventoryWPAppDomains(ApplicationDomainCollection WPAppDoma foreach (var ApplicationDomain in WPAppDomains) { - //Array ArrWorkerProcesses = InventoryWorkerProcesses(AppPool, bVerboseInventory); Array ArrWorkerProcesses = new Array[] { null }; listAppPoolWPApplicationDomains.Add(new AppPoolWPAppDomains(ApplicationDomain.Id, ApplicationDomain.Idle, ApplicationDomain.IsLocallyStored, ApplicationDomain.PhysicalPath, ApplicationDomain.VirtualPath, ArrWorkerProcesses)); - } Array ArrWPAppDomains = listAppPoolWPApplicationDomains.ToArray(); @@ -923,7 +943,7 @@ private static Array InventorySiteBindings(Site site, bool bVerboseInventory) } string certificateStore = null; - if (Binding.CertificateStoreName != null) + if (Binding.CertificateStoreName != null) certificateStore = Binding.CertificateStoreName.ToString(); string bindingInformation = null; @@ -947,7 +967,6 @@ private static Array InventorySiteBindings(Site site, bool bVerboseInventory) { Console.WriteLine("Error in reading sitebinding for site '" + site.Name.ToString() + "', protocol '" + protocol + "', error: " + e); } - } Array ArrSiteBindings = listSiteBindings.ToArray(); @@ -967,7 +986,6 @@ private static Array InventorySiteApplications(Site site, bool bVerboseInventory Array VirtualDirectories = InventorySiteAppVirtualDirectories(Application.VirtualDirectories, bVerboseInventory); listSiteApplications.Add(new SiteApplications(Application.ApplicationPoolName, Application.EnabledProtocols, Application.IsLocallyStored, Application.Path, VirtualDirectories)); - } Array ArrSiteApplications = listSiteApplications.ToArray(); @@ -992,14 +1010,12 @@ private static Array InventorySiteAppVirtualDirectories(VirtualDirectoryCollecti return ArrSiteAppVirtDirs; } - public static int CheckAllSites(int returncode, bool do_perfcounter_sites, string[] excluded_sites, - string[] included_sites, string[] stopped_sites, string[] warn_sites, bool do_singluar_check, - string expected_state) + public static int CheckAllSites(int returncode, bool do_perfcounter_sites, bool do_singluar_check, string expected_state) { var iisManager = new ServerManager(); bool temp = false; - temp = InventorySites(iisManager, excluded_sites, included_sites, false, false, false); + temp = InventorySites(iisManager, false, false, false); if (temp == false) return (int)ServiceState.ServiceUnknown; @@ -1011,7 +1027,7 @@ public static int CheckAllSites(int returncode, bool do_perfcounter_sites, strin string output; Dictionary listOverSites = listSitesOnComputer.ToDictionary(o => o.Name, o => o); - + // Loop for each site in sites foreach (var site in listOverSites.Values) { @@ -1051,7 +1067,6 @@ public static int CheckAllSites(int returncode, bool do_perfcounter_sites, strin if (site.ServerAutoStart == true) { output = "Site '" + sSiteName + "' set to AutoStart and site state is '" + site.State.ToString() + "'"; - } else { @@ -1138,13 +1153,11 @@ public static int CheckAllSites(int returncode, bool do_perfcounter_sites, strin errorSites = true; } - if (do_perfcounter_sites) output = PerfCounterSites(sSiteName, output, do_singluar_check); listSiteOutput.Add(output); iNumberOfSites++; - } if (errorSites == false) @@ -1176,14 +1189,12 @@ public static int CheckAllSites(int returncode, bool do_perfcounter_sites, strin return returncode; } - public static int CheckAllAppPools(int returncode, bool do_perfcounter_apppools, string[] excluded_apppools, - string[] included_apppools, string[] stopped_apppools, string[] warn_apppools, bool do_singluar_check, - string expected_state) + public static int CheckAllAppPools(int returncode, bool do_perfcounter_apppools, bool do_singluar_check, string expected_state) { var iisManager = new ServerManager(); bool temp = false; - temp = InventoryAppPools(iisManager, excluded_apppools, included_apppools, false, false, false, false); + temp = InventoryAppPools(iisManager, false, false, false, false); if (temp == false) return (int)ServiceState.ServiceUnknown; @@ -1195,7 +1206,7 @@ public static int CheckAllAppPools(int returncode, bool do_perfcounter_apppools, string output; Dictionary listOverAppPools = listAppPoolsOnComputer.ToDictionary(o => o.Name, o => o); - + // Loop for each AppPool in appPools list foreach (var apppool in listOverAppPools.Values) { @@ -1229,13 +1240,12 @@ public static int CheckAllAppPools(int returncode, bool do_perfcounter_apppools, } bAppPoolShouldBeWarned = true; } - + output = ""; if (apppool.AutoStart == true) { output = "AppPool '" + sAppPoolName + "' set to AutoStart and apppool state is '" + apppool.State.ToString() + "'"; - } else { @@ -1327,7 +1337,6 @@ public static int CheckAllAppPools(int returncode, bool do_perfcounter_apppools, listAppPoolOutput.Add(output); iNumberOfAppPools++; - } if (errorAppPools == false) @@ -1361,7 +1370,6 @@ public static int CheckAllAppPools(int returncode, bool do_perfcounter_apppools, public static void CountSiteState(string status) { - if (status == ObjectState.Started.ToString()) { iNumberOfStartedSites++; @@ -1386,7 +1394,6 @@ public static void CountSiteState(string status) public static void CountAppPoolState(string status) { - if (status == ObjectState.Started.ToString()) { iNumberOfStartedAppPools++; @@ -1409,7 +1416,6 @@ public static void CountAppPoolState(string status) } } - private static string PerfCounterSites(string sSiteName, string output, bool do_singluar_check) { try @@ -1479,8 +1485,5 @@ private static string PerfCounterAppPools(string sAppPoolName, string output, bo return output; } - - } - } \ No newline at end of file diff --git a/Solution/check_iis/Properties/AssemblyInfo.cs b/Solution/check_iis/Properties/AssemblyInfo.cs index 9acb2b0..97300df 100644 --- a/Solution/check_iis/Properties/AssemblyInfo.cs +++ b/Solution/check_iis/Properties/AssemblyInfo.cs @@ -32,4 +32,4 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.8.*")] +[assembly: AssemblyVersion("0.9.*")]