#!/usr/bin/php * --protocol * --site-key * --api-key must have system.check permission. Use a key that has "Administer CiviCRM" permission, or better yet install https://github.com/MegaphoneJon/com.megaphonetech.monitoring * * Optional arguments: * --cms * --rest-path NOTE: either --cms OR --path is required * --warning-threshold Checks that report back this severity_id or higher are considered Nagios/Icinga warnings. * --critical-threshold Checks that report back this severity_id or higher are considered Nagios/Icinga errors. * --show-hidden <0|1> If set to "0", checks that are hidden in the CiviCRM Status Console will be hidden from Nagios/Icinga. * --exclude Any checks listed here will be excluded. E.g. --exclude checkPhpVersion,checkLastCron will suppress the PHP version check and the cron check * --only-these-checks If specified, only these checks will be run. Unlike "--exclude", which simply hides results, this prevents other checks from running. * --include-disabled <0|1> If set to 1, it will run status checks that have been marked inactive in the CiviCRM database. */ $shortopts = ''; $longopts = ['exclude:', 'api-key:', 'site-key:', 'protocol:', 'cms:', 'rest-path:', 'show-hidden:', 'hostname:', 'warning-threshold:', 'critical-threshold:', 'include-disabled:', 'only-these-checks:']; $options = getopt($shortopts, $longopts); checkRequired($options); $prot = $options['protocol']; $api_key = $options['api-key']; $site_key = $options['site-key']; $host_address = $options['hostname']; // $show_hidden will evaluate to true unless it's a zero. $show_hidden = $options['show-hidden'] ?? TRUE; $warning_threshold = $options['warning-threshold'] ?? 2; $critical_threshold = $options['critical-threshold'] ?? 4; $path = $options['path'] ?? NULL; $cms = $options['cms'] ?? NULL; $exclude = $options['exclude'] ?? FALSE ? explode(',', $options['exclude']) : []; $onlyTheseChecks = $options['only-these-checks'] ?? FALSE ? explode(',', $options['only-these-checks']) : []; $include_disabled = $options['include-disabled'] ?? FALSE; switch (strtolower($cms)) { case 'joomla': $path = 'administrator/components/com_civicrm/civicrm/extern/rest.php'; // This assumes WP has Clean URLs enabled. case 'wordpress': case 'backdrop': case 'drupal': case 'drupal8': $path = 'civicrm/ajax/api4'; break; } if (!$path) { echo "You must specify either a valid CMS or a REST endpoint path."; exit(3); } systemCheck($prot, $host_address, $path, $site_key, $api_key, $show_hidden, $warning_threshold, $critical_threshold, $include_disabled, $exclude, $onlyTheseChecks); /** * Given an array of command-line options, do some sanity checks, bail if missing required fields etc. * @param array $options */ function checkRequired($options) { $requiredArguments = ['hostname', 'protocol', 'site-key', 'api-key']; $arguments = array_keys($options); $missing = NULL; foreach ($requiredArguments as $required) { if (!in_array($required, $arguments)) { $missing .= " $required"; } } if (isset($missing)) { echo "You are missing the following required arguments:$missing"; exit(3); } if (!in_array($options['protocol'], ['http', 'https'])) { echo '"protocol" argument must be "http" or "https"' . exit(3); } } function systemCheck($prot, $host_address, $path, $site_key, $api_key, $show_hidden, $warning_threshold, $critical_threshold, $include_disabled, $exclude = [], $onlyTheseChecks = []) { $url = "$prot://$host_address/$path/System/check"; $params['includeDisabled'] = $include_disabled; if ($onlyTheseChecks) { $params['where'] = [['name', 'IN', $onlyTheseChecks]]; }; $context = stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => [ 'Content-Type: application/x-www-form-urlencoded', "X-Civi-Auth: Bearer $api_key", "X-Civi-Key: $site_key", "X-Requested-With: XMLHttpRequest", "User-Agent: CiviMonitor", ], 'content' => http_build_query(['params' => json_encode($params)]), ], ]); $result = file_get_contents($url, FALSE, $context); $a = json_decode($result, TRUE); $isError = $a['is_error'] ?? $a['error_code'] ?? FALSE; if ($isError) { echo $a['error_message'] ?? ''; exit(2); } if (!isset($a['values'])) { echo 'Unknown error - no values returned from CiviCRM'; exit(3); } $message = []; $max_severity = 0; foreach ($a["values"] as $attrib) { // Remove excluded checks. if (in_array($attrib['name'], $exclude)) { continue; } // first check for missing info $neededKeys = [ 'title' => TRUE, 'message' => TRUE, 'name' => TRUE, ]; if (array_intersect_key($neededKeys, $attrib) != $neededKeys) { $message[] = 'Missing keys: ' . implode(', ', array_diff($neededKeys, array_intersect_key($neededKeys, $attrib))) . '.'; $max_severity = 3; continue; } // Skip this item if it's hidden and we're hiding hidden items if ($attrib['is_visible'] == 0 && !$show_hidden) { continue; } // Skip this item if it doesn't meet the warning threshold if ($attrib['severity_id'] < $warning_threshold) { continue; } $allowed_tags = ['

', '
', '', '', '', '
', '
']; $message[] = strip_tags($attrib['title'], $allowed_tags) . ': ' . strip_tags($attrib['message'], $allowed_tags); if ($attrib['severity_id'] >= $warning_threshold) { $max_severity = max(1, $max_severity); }; if ($attrib['severity_id'] >= $critical_threshold) { $max_severity = max(2, $max_severity); }; } echo implode(' / ', $message); exit($max_severity); }