Advertisement
Guest User

Untitled

a guest
Jul 13th, 2016
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.67 KB | None | 0 0
  1. #!/usr/bin/php
  2. <?php
  3.  
  4. ############################################################################
  5. #
  6. # check_mssql - Checks various aspect of MSSQL servers
  7. #
  8. # Version 0.6.6, Copyright (c) 2008 Gary Danko <gdanko@gmail.com>
  9. # Version 0.6.7,0.6.8 2012 Nicholas Scott <nscott@nagios.com>
  10. # Notes:
  11. #
  12. # Version 0.1.0 - 2008/08/14
  13. # Initial release. Accepts hostname, username, password, port,
  14. # database name, and an optional query to run.
  15. #
  16. # Version 0.2.0 - 2008/08/15
  17. # You can now execute a query or stored procedure and report
  18. # on expected results. Queries should be simplistic since
  19. # only the first row is returned.
  20. #
  21. # Version 0.2.2 - 2008/08/18
  22. # Nothing major. Just a couple of cosmetic fixes.
  23. #
  24. # Version 0.5.0 - 2008/09/29
  25. # Major rewrite. No new functionality. RegEx added to
  26. # validate command line options.
  27. #
  28. # Version 0.6.0 - 2008/10/23
  29. # Allows the user to specify a SQL file with --query
  30. #
  31. # Version 0.6.3 - 2008/10/26
  32. # Removed the -r requirement with -q.
  33. #
  34. # Version 0.6.4 - 2008/10/31
  35. # Fixed a bug that would nullify an expected result of "0"
  36. #
  37. # Version 0.6.5 - 2008/10/31
  38. # Minor fix for better display of error output.
  39. #
  40. # Version 0.6.6 - 2008/10/31
  41. # Prepends "exec " to --storedproc if it doesn't exist.
  42. #
  43. # Version 0.6.7 - 2012/07/05
  44. # Enabled instances to be used
  45. #
  46. # Version 0.6.8 - 2012/08/30
  47. # Enabled returning of perfdata
  48. # Warning and crits may be decimal values
  49. #
  50. # This plugin will check the general health of an MSSQL
  51. # server. It will also report the query duration and allows
  52. # you to set warning and critical thresholds based on the
  53. # duration.
  54. #
  55. # Requires:
  56. # yphp_cli-5.2.5_1 *
  57. # yphp_mssql-5.2.5_1 *
  58. # freetds *
  59. #
  60. # License Information:
  61. # This program is free software; you can redistribute it and/or modify
  62. # it under the terms of the GNU General Public License as published by
  63. # the Free Software Foundation; either version 2 of the License, or
  64. # (at your option) any later version.
  65. #
  66. # This program is distributed in the hope that it will be useful,
  67. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  68. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  69. # GNU General Public License for more details.
  70. #
  71. # You should have received a copy of the GNU General Public License
  72. # along with this program; if not, write to the Free Software
  73. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  74. #
  75. ############################################################################
  76.  
  77. $progname = "check_mssql";
  78. $version = "0.6.8";
  79.  
  80. // Parse the command line options
  81. for ($i = 1; $i < $_SERVER['argc']; $i++) {
  82. $arg = $_SERVER["argv"][$i];
  83. switch($arg) {
  84. case '-h':
  85. case '--help':
  86. help();
  87. break;
  88.  
  89. case '-V':
  90. case '--version':
  91. version();
  92. break;
  93.  
  94. case '-I':
  95. case '--instance':
  96. $db_inst = check_command_line_option($_SERVER["argv"][$i], $i);
  97. break;
  98.  
  99. case '-H':
  100. case '--hostname':
  101. $db_host = check_command_line_option($_SERVER["argv"][$i], $i);
  102. break;
  103.  
  104. case '-u':
  105. case '-U':
  106. case '--username':
  107. $db_user = check_command_line_option($_SERVER["argv"][$i], $i);
  108. break;
  109.  
  110. case '-P':
  111. case '--password':
  112. $db_pass = check_command_line_option($_SERVER["argv"][$i], $i);
  113. break;
  114.  
  115. case '-p':
  116. case '--port':
  117. $db_port = check_command_line_option($_SERVER["argv"][$i], $i);
  118. break;
  119.  
  120. case '-d':
  121. case '--database':
  122. $db_name = check_command_line_option($_SERVER["argv"][$i], $i);
  123. break;
  124.  
  125. case '-q':
  126. case '--query':
  127. $query = check_command_line_option($_SERVER["argv"][$i], $i);
  128. $querytype = "query";
  129. break;
  130.  
  131. case '-s':
  132. case '--storedproc':
  133. $storedproc = check_command_line_option($_SERVER["argv"][$i], $i);
  134. $querytype = "stored procedure";
  135. break;
  136.  
  137. case '-r':
  138. case '--result':
  139. $expected_result = check_command_line_option($_SERVER["argv"][$i], $i);
  140. break;
  141.  
  142. case '-w':
  143. case '--warning':
  144. $warning = check_command_line_option($_SERVER["argv"][$i], $i);
  145. break;
  146.  
  147. case '-c':
  148. case '--critical':
  149. $critical = check_command_line_option($_SERVER["argv"][$i], $i);
  150. break;
  151. }
  152. }
  153.  
  154. // Error out if mssql support is not present.
  155. if (!function_exists('mssql_connect')) {
  156. print "UNKNOWN: MSSQL support is not installed on this server.\n";
  157. exit(3);
  158. }
  159.  
  160. // If no options are set, display the help
  161. if ($_SERVER['argc'] == 1) {
  162. print "$progname: Could not parse arguments\n";
  163. usage();
  164. exit;
  165. }
  166.  
  167. // Determine if the query is a SQL file or a text query
  168. if (isset($query)) {
  169. if (file_exists($query)) {
  170. $query = file_get_contents($query);
  171. }
  172. }
  173.  
  174. // Add "exec" to the beginning of the stored proc if it doesnt exist.
  175. if (isset($storedproc)) {
  176. if (substr($storedproc, 0, 5) != "exec ") {
  177. $storedproc = "exec $storedproc";
  178. }
  179. }
  180.  
  181. // Do not allow both -q and -s
  182. if (isset($query) && isset($storedproc)) {
  183. print "UNKNOWN: The -q and -s switches are mutually exclusive. You may not select both.\n";
  184. exit(3);
  185. }
  186.  
  187. // -r demands -q and -q demands -r
  188. if (isset($expected_result) && !isset($query)) {
  189. print "UNKNOWN: The -r switch requires the -q switch. Please specify a query.\n";
  190. exit(3);
  191. }
  192.  
  193. // Validate the hostname
  194. if (isset($db_host)) {
  195. if (!preg_match("/^([a-zA-Z0-9-]+[\.])+([a-zA-Z0-9]+)$/", $db_host)) {
  196. print "UNKNOWN: Invalid characters in the hostname.\n";
  197. exit(3);
  198. }
  199. } else {
  200. print "UNKNOWN: The required hostname field is missing.\n";
  201. exit(3);
  202. }
  203.  
  204. // Validate the port
  205. if (isset($db_port)) {
  206. if (!preg_match("/^([0-9]{4,5})$/", $db_port)) {
  207. print "UNKNOWN: The port field should be numeric and in the range 1000-65535.\n";
  208. exit(3);
  209. }
  210. } else {
  211. $db_port = 1433;
  212. }
  213.  
  214. // Validate the username
  215. if (isset($db_user)) {
  216. if (!preg_match("/^[a-zA-Z0-9-]{2,32}$/", $db_user)) {
  217. print "UNKNOWN: Invalid characters in the username.\n";
  218. exit(3);
  219. }
  220. } else {
  221. print "UNKNOWN: You must specify a username for this DB connection.\n";
  222. exit(3);
  223. }
  224.  
  225. // Validate the password
  226. if (empty($db_pass)) {
  227. print "UNKNOWN: You must specify a password for this DB connection.\n";
  228. exit(3);
  229. }
  230.  
  231. // Validate the warning threshold
  232. if (isset($warning)) {
  233. if (!preg_match("/^[0-9]\d*(\.\d+)?$/", $warning)) {
  234. print "UNKNOWN: Invalid warning threshold.\n";
  235. exit(3);
  236. }
  237. } else {
  238. $warning = 2;
  239. }
  240.  
  241. // Validate the critical threshold
  242. if (isset($critical)) {
  243. if (!preg_match("/^[0-9]\d*(\.\d+)?$/", $critical)) {
  244. print "UNKNOWN: Invalid critical threshold.\n";
  245. exit(3);
  246. }
  247. } else {
  248. $critical = 5;
  249. }
  250.  
  251. // Is warning greater than critical?
  252. if ($warning > $critical) {
  253. $exit_code = 3;
  254. $output_msg = "UNKNOWN: warning value should be lower than critical value.\n";
  255. display_output($exit_code, $output_msg);
  256. }
  257.  
  258. // Attempt to connect to the server
  259. $time_start = microtime(true);
  260. $db_connstr = $db_host;
  261. if ( isset($db_inst) ) $db_connstr .= "\\$db_inst";
  262. else $db_connstr .= ":$db_port";
  263. if (!$connection = @mssql_connect( $db_connstr , $db_user, $db_pass)) {
  264. $exit_code = 2;
  265. $output_msg = "CRITICAL: Could not connect to $db_connstr as $db_user.\n";
  266. display_output($exit_code, $output_msg);
  267. } else {
  268. $time_end = microtime(true);
  269. $query_duration = round(($time_end - $time_start), 6);
  270. // Exit now if no query or stored procedure is specified
  271. if (empty($storedproc) && empty($query)) {
  272. $output_msg = "Connect time=$query_duration seconds.";
  273. process_results($query_duration, $warning, $critical, $output_msg);
  274. }
  275. }
  276.  
  277. if (empty($db_name)) {
  278. $exit_code = 3;
  279. $output_msg = "UNKNOWN: You must specify a database with the -q or -s switches.\n";
  280. display_output($exit_code, $output_msg);
  281. }
  282.  
  283. // Attempt to select the database
  284. if(!@mssql_select_db($db_name, $connection)) {
  285. $exit_code = 2;
  286. $output_msg = "CRITICAL: Could not connect to $db_name on $db_host.\n";
  287. display_output($exit_code, $output_msg);
  288. }
  289.  
  290. // Attempt to execute the query/stored procedure
  291. $time_start = microtime(true);
  292. if (!$query_data = @mssql_query("$query")) {
  293. $exit_code = 2;
  294. $output_msg = "CRITICAL: Could not execute the $querytype.\n";
  295. display_output($exit_code, $output_msg);
  296. } else {
  297. $time_end = microtime(true);
  298. $query_duration = round(($time_end - $time_start), 6);
  299. $output_msg = "Query duration=$query_duration seconds.";
  300. }
  301.  
  302. if ($querytype == "query" && isset($expected_result)) {
  303. if (mssql_num_rows($query_data) > 0 ) {
  304. while ($row = mssql_fetch_row($query_data)) {
  305. $query_result = $row[0];
  306. }
  307. }
  308. if ($query_result == $expected_result) {
  309. $output_msg = "Query results matched, query duration=$query_duration seconds.\n";
  310. } else {
  311. $exit_code = 2;
  312. $output_msg = "CRITICAL: Query expected \"$expected_result\" but got \"$query_result\".";
  313. }
  314. }
  315. process_results($query_duration, $warning, $critical, $output_msg, $exit_code);
  316.  
  317. //-----------//
  318. // Functions //
  319. //-----------//
  320.  
  321. // Function to validate a command line option
  322. function check_command_line_option($option, $i) {
  323. // If the option requires an argument but one isn't sent, bail out
  324. $next_offset = $i + 1;
  325. if (!isset($_SERVER['argv'][$next_offset]) || substr($_SERVER['argv'][$next_offset], 0, 1) == "-") {
  326. print "UNKNOWN: The \"$option\" option requires a value.\n";
  327. exit(3);
  328. } else {
  329. ${$option} = $_SERVER['argv'][++$i];
  330. return ${$option};
  331. }
  332. }
  333.  
  334. // Function to process the results
  335. function process_results($query_duration, $warning, $critical, $output_msg, $exit_code = null) {
  336. if ($query_duration > $critical || $exit_code == 2) {
  337. $state = "CRITICAL";
  338. $exit_code = 2;
  339. } elseif ($query_duration > $warning || $exit_code == 1) {
  340. $state = "WARNING";
  341. $exit_code = 1;
  342. } else {
  343. $state = "OK";
  344. $exit_code = 0;
  345. }
  346. $statdata = "$state: $output_msg";
  347. $perfdata = "query_duration={$query_duration}s;{$warning};{$critical};0;";
  348. $output_msg = "{$statdata}|{$perfdata}\n";
  349. display_output($exit_code, $output_msg);
  350. }
  351.  
  352. // Function to display the output
  353. function display_output($exit_code, $output_msg) {
  354. print $output_msg;
  355. exit($exit_code);
  356. }
  357.  
  358. // Function to display usage information
  359. function usage() {
  360. global $progname, $version;
  361. print <<<EOF
  362. Usage: $progname -H <hostname> --username <username> --password <password>
  363. [--port <port> | --instance <instance>] [--database <database>]
  364. [--query <"text">|filename] [--storeproc <"text">] [--result <text>]
  365. [--warning <warn time>] [--critical <critical time>] [--help] [--version]
  366.  
  367. EOF;
  368. }
  369.  
  370. // Function to display copyright information
  371. function copyright() {
  372. global $progname, $version;
  373. print <<<EOF
  374. Copyright (c) 2008 Gary Danko (gdanko@gmail.com)
  375. 2012 Nicholas Scott (nscott@nagios.com)
  376. This plugin checks various aspect of an MSSQL server. It will also
  377. execute queries or stored procedures and return results based on
  378. query execution times and expected query results.
  379.  
  380. EOF;
  381. }
  382.  
  383. // Function to display detailed help
  384. function help() {
  385. global $progname, $version;
  386. print "$progname, $version\n";
  387. copyright();
  388. print <<<EOF
  389.  
  390. Options:
  391. -h, --help
  392. Print detailed help screen.
  393. -V, --version
  394. Print version information.
  395. -H, --hostname
  396. Hostname of the MSSQL server.
  397. -U, --username
  398. Username to use when logging into the MSSQL server.
  399. -P, --password
  400. Password to use when logging into the MSSQL server.
  401. -p, --port
  402. Optional MSSQL server port. (Default is 1433).
  403. -I, --instance
  404. Optional MSSQL Instance
  405. -d, --database
  406. Optional DB name to connect to.
  407. -q, --query
  408. Optional query or SQL file to execute against the MSSQL server.
  409. -s, --storedproc
  410. Optional stored procedure to execute against the MSSQL server.
  411. -r, --result
  412. Expected result from the specified query, requires -q. The query
  413. pulls only the first row for comparison, so you should limit
  414. yourself to small, simple queries.
  415. -w, --warning
  416. Warning threshold in seconds on duration of check (Default is 2).
  417. Accepts decimal values, note however that there must be at least a
  418. leading 0. Example, .0023 is not a valid entry, but 0.0023 is.
  419. -c, --critical
  420. Critical threshold in seconds on duration of check (Default is 5).
  421. Accepts decimal values, note however that there must be at least a
  422. leading 0. Example, .0023 is not a valid entry, but 0.0023 is.
  423.  
  424. Example: $progname -H myserver -U myuser -P mypass -q /tmp/query.sql -w 2 -c 5
  425. Example: $progname -H myserver -U myuser -P mypass -q "select count(*) from mytable" -r "632" -w 2 -c 5
  426. Send any questions regarding this utility to gdanko@gmail.com or scot0357@gmail.com.
  427.  
  428. EOF;
  429. exit(0);
  430. }
  431.  
  432. // Function to display version information
  433. function version() {
  434. global $version;
  435. print <<<EOF
  436. $version
  437.  
  438. EOF;
  439. exit(0);
  440. }
  441. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement