View source
<?php
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Unicode;
use Drupal\monitoring\Result\SensorResult;
use Drupal\monitoring\Result\SensorResultInterface;
use Drupal\monitoring\Sensor\DisabledSensorException;
use Drupal\monitoring\Sensor\NonExistingSensorException;
define('MONITORING_DRUSH_SENSOR_STATUS_CRITICAL', 3);
define('MONITORING_DRUSH_SENSOR_STATUS_UNKNOWN', 2);
define('MONITORING_DRUSH_SENSOR_STATUS_WARNING', 1);
define('MONITORING_DRUSH_SENSOR_STATUS_OK', 0);
function monitoring_drush_command() {
$items = array();
$items['monitoring-info'] = array(
'callback' => 'monitoring_drush_info',
'description' => 'Displays information about available sensors. If a sensor name provided as argument a detailed sensor info is provided.',
'arguments' => array(
'sensor_name' => 'Specific sensor name for which we want to display info.',
),
'examples' => array(
'drush monitoring-info' => 'Prints sensor info for all available sensors.',
'drush monitoring-info node_new' => 'Prints info of the node_new sensor.',
),
'drupal dependencies' => array(
'monitoring',
),
);
$items['monitoring-run'] = array(
'callback' => 'monitoring_drush_run',
'description' => 'Runs specific sensor and provides verbose data.',
'arguments' => array(
'sensor_name' => 'Sensor name to invoke.',
),
'options' => array(
'verbose' => 'Display verbose information.',
'force' => 'If the sensor execution should be forced in case cached result is available.',
'output' => 'The output format. Currently "table", "json" and "sensu" available. Defaults to "table".',
'expand' => 'Relevant only for the json output. Currently "sensor" value supported.',
'show-exec-time' => 'Relevant for the table output listing all results. Will expand the table with execution time info.',
'sensu-source' => 'Relevant only for sensu output. The sensu source. Defaults to the host name.',
'sensu-ttl' => 'Relevant only for sensu output. Sensu TTL (Time to live)',
'sensu-handlers' => 'Relevant only for sensu output. A comma separated list of Sensu handlers (names).',
'sensu-metric-handlers' => 'Relevant only for sensu output. Defaults to the Sensu handlers.',
'sensu-metrics' => 'Relevant only for sensu output. Expose numeric sensors additionally as metrics. Enabled by default.',
),
'examples' => array(
'drush monitoring-run monitoring_git_dirty_tree' => 'Runs sensor to monitor the git status.',
'drush monitoring-run --verbose monitoring_git_dirty_tree' => 'Runs sensor to monitor the git status and displays verbose information.',
'drush monitoring-run --output=json --watchdog=disable' => 'Will output the sensor results in json format. The option --watchdog=disable will suppress watchdog output to console.',
'drush monitoring-run --output=sensu --sensu-source=example.org --sensu-ttl=600 --sensu-handlers=email,pagerduty' => 'Will output the sensor results in sensu format. The option --sensu-source=example.org will provide the sensu source. The option --sensu-ttl=600 will provide the sensor 600 seconds time to live.',
),
'drupal dependencies' => array(
'monitoring',
),
);
$items['monitoring-enable'] = array(
'callback' => 'monitoring_drush_enable',
'description' => 'Enable specified monitoring sensor.',
'arguments' => array(
'sensor_name' => 'Sensor name to enable.',
),
'required-arguments' => TRUE,
'examples' => array(
'drush monitoring-enable monitoring_git_dirty_tree' => 'Enables monitoring_git_dirty_tree sensor.',
),
'drupal dependencies' => array(
'monitoring',
),
);
$items['monitoring-disable'] = array(
'callback' => 'monitoring_drush_disable',
'description' => 'Disable specified monitoring sensor.',
'arguments' => array(
'sensor_name' => 'Sensor name to disable.',
),
'required-arguments' => TRUE,
'examples' => array(
'drush monitoring-disable monitoring_git_dirty_tree' => 'Disables monitoring_git_dirty_tree sensor.',
),
'drupal dependencies' => array(
'monitoring',
),
);
$items['monitoring-purge-settings'] = array(
'callback' => 'monitoring_drush_purge_settings',
'description' => 'Purges settings for a specific sensor, or all sensors.',
'arguments' => array(
'sensor_name' => 'Sensor name for which to purge settings.',
),
'examples' => array(
'drush monitoring-purge-settings monitoring_git_dirty_tree' => 'Enables monitoring_git_dirty_tree sensor.',
),
'drupal dependencies' => array(
'monitoring',
),
);
return $items;
}
function monitoring_drush_info($sensor_name = NULL) {
if (empty($sensor_name)) {
monitoring_drush_info_all();
}
else {
monitoring_drush_info_single($sensor_name);
}
}
function monitoring_drush_info_all() {
$sensors_info = monitoring_sensor_manager()
->getSensorInfo();
$rows[] = array(
dt('Label'),
dt('Name'),
dt('Category'),
dt('Enabled'),
);
$rows[] = array(
'----',
'----',
'----',
);
foreach ($sensors_info as $name => $info) {
$rows[] = array(
$info
->getLabel(),
$name,
$info
->getCategory(),
$info
->isEnabled() ? t('Yes') : t('No'),
);
}
drush_print_table($rows, TRUE);
}
function monitoring_drush_info_single($sensor_name) {
$sensor_info = NULL;
try {
$sensor_info = monitoring_sensor_manager()
->getSensorInfoByName($sensor_name);
} catch (NonExistingSensorException $e) {
return drush_set_error('MONITORING_SENSOR_INVALID_NAME', dt('Sensor "@name" does not exist.', array(
'@name' => $sensor_name,
)));
}
$rows[] = array(
format_string("@label (@name)", array(
'@label' => $sensor_info
->getLabel(),
'@name' => $sensor_info
->getName(),
)),
'====================',
);
$rows[] = array(
dt('Category'),
$sensor_info
->getCategory(),
);
$rows[] = array(
dt('Description'),
$sensor_info
->getDescription(),
);
$rows[] = array(
dt('Value info'),
format_string('type: @type, label: @label, numeric: @numeric', array(
'@type' => $sensor_info
->getValueType() ? $sensor_info
->getValueType() : dt('N/A'),
'@label' => $sensor_info
->getValueLabel() ? $sensor_info
->getValueLabel() : dt('N/A'),
'@numeric' => $sensor_info
->isNumeric() ? dt('Yes') : dt('No'),
)),
);
$rows[] = array(
dt('Caching time'),
format_interval($sensor_info
->getCachingTime()),
);
$rows[] = array(
dt('Enabled'),
$sensor_info
->isEnabled() ? dt('Yes') : dt('No'),
);
$rows[] = array(
dt('Has thresholds'),
$sensor_info
->isDefiningThresholds() ? dt('Yes') : dt('No'),
);
$rows[] = array(
dt('Is configurable'),
$sensor_info
->isConfigurable() ? dt('Yes') : dt('No'),
);
drush_print_table($rows);
}
function monitoring_drush_run($sensor_name = NULL) {
global $base_root;
$force_run = (bool) drush_get_option('force');
$verbose = (bool) drush_get_option('verbose');
$output = drush_get_option('output', 'table');
$expand = drush_get_option('expand');
$show_exec_time = drush_get_option('show-exec-time');
try {
$sensor_names = array();
if (!empty($sensor_name)) {
$sensor_names = array(
$sensor_name,
);
}
$results = monitoring_sensor_run_multiple($sensor_names, $force_run, $verbose);
} catch (NonExistingSensorException $e) {
drush_set_error('MONITORING_SENSOR_INVALID_NAME', dt('Sensor "@name" does not exist.', array(
'@name' => $sensor_name,
)));
return MONITORING_DRUSH_SENSOR_STATUS_UNKNOWN;
} catch (DisabledSensorException $e) {
drush_set_error('MONITORING_SENSOR_DISABLED', dt('Sensor "@name" is not enabled.', array(
'@name' => $sensor_name,
)));
return MONITORING_DRUSH_SENSOR_STATUS_UNKNOWN;
}
if ($output == 'table') {
monitoring_drush_result_output_table($results, $show_exec_time);
}
elseif ($output == 'json') {
monitoring_drush_result_output_json($results, $expand);
}
elseif ($output == 'sensu') {
$source = drush_get_option('sensu-source', $_SERVER['HTTP_HOST']);
$ttl = (int) drush_get_option('sensu-ttl');
$handlers = array();
if (drush_get_option('sensu-handlers')) {
$handlers = explode(',', drush_get_option('sensu-handlers'));
}
$metric_handlers = array();
if (drush_get_option('sensu-metric-handlers')) {
$metric_handlers = explode(',', drush_get_option('sensu-metric-handlers'));
}
$metrics = drush_get_option('sensu-metrics', 1);
monitoring_drush_result_output_sensu($results, $source, $ttl, $handlers, $metric_handlers, $metrics);
}
else {
drush_set_error('MONITORING_UNKNOWN_OUTPUT', dt('Unknown output @output.', array(
'@output' => $output,
)));
return MONITORING_DRUSH_SENSOR_STATUS_UNKNOWN;
}
$status = MONITORING_DRUSH_SENSOR_STATUS_OK;
foreach ($results as $result) {
if ($result
->isCritical() && in_array($status, array(
MONITORING_DRUSH_SENSOR_STATUS_UNKNOWN,
MONITORING_DRUSH_SENSOR_STATUS_WARNING,
MONITORING_DRUSH_SENSOR_STATUS_OK,
))) {
$status = MONITORING_DRUSH_SENSOR_STATUS_CRITICAL;
}
elseif ($result
->isUnknown() && in_array($status, array(
MONITORING_DRUSH_SENSOR_STATUS_WARNING,
MONITORING_DRUSH_SENSOR_STATUS_OK,
))) {
$status = MONITORING_DRUSH_SENSOR_STATUS_UNKNOWN;
}
elseif ($result
->isWarning() && $status == MONITORING_DRUSH_SENSOR_STATUS_OK) {
$status = MONITORING_DRUSH_SENSOR_STATUS_WARNING;
}
}
return $status;
}
function monitoring_drush_result_output_sensu($results, $source, $ttl, $handlers, $metric_handlers, $metrics) {
$status_codes = array(
SensorResultInterface::STATUS_OK => 0,
SensorResultInterface::STATUS_WARNING => 1,
SensorResultInterface::STATUS_CRITICAL => 2,
SensorResultInterface::STATUS_UNKNOWN => 3,
SensorResultInterface::STATUS_INFO => 0,
);
foreach ($results as $name => $result) {
$sensu_output = array();
$sensu_output['name'] = $name;
$sensu_output['status'] = $status_codes[$result
->getStatus()];
if ($ttl) {
$sensu_output['ttl'] = $ttl;
}
if ($handlers) {
$sensu_output['handlers'] = $handlers;
}
$sensu_output['output'] = $result
->getMessage();
$sensu_output['interval'] = $result
->getSensorInfo()
->getCachingTime();
$sensu_output['duration'] = $result
->getExecutionTime();
$sensu_output['source'] = $source;
drush_print(drupal_json_encode($sensu_output));
if ($result
->getSensorInfo()
->isNumeric() && $metrics) {
$sensu_metric_output = $sensu_output;
$sensu_metric_output['name'] = $name . '_metric';
$sensu_metric_output['type'] = 'metric';
if ($metric_handlers) {
$sensu_metric_output['handlers'] = $metric_handlers;
}
$reversed_source = implode('.', array_reverse(explode('.', $sensu_output['source'])));
$value = $result
->getValue();
$executed = $result
->getTimestamp();
$sensu_metric_output['output'] = $reversed_source . '.' . $name . ' ' . $value . ' ' . $executed;
drush_print(drupal_json_encode($sensu_metric_output));
}
}
}
function monitoring_drush_result_output_json(array $results, $expand = NULL) {
$json_output = array();
foreach ($results as $result) {
$json_output[$result
->getSensorName()] = $result
->toArray();
if ($expand == 'sensor_info') {
$json_output[$result
->getSensorName()]['sensor_info'] = $result
->getSensorInfo()
->toArray();
}
}
drush_print(drupal_json_encode($json_output));
}
function monitoring_drush_result_output_table(array $results, $show_exec_time = FALSE) {
if (count($results) == 1) {
monitoring_drush_result_output_table_single(reset($results));
}
else {
monitoring_drush_result_output_table_multiple($results, $show_exec_time);
}
}
function monitoring_drush_result_output_table_single(SensorResultInterface $result) {
$rows[] = array(
dt('Name'),
$result
->getSensorInfo()
->getName(),
);
$rows[] = array(
dt('Label'),
$result
->getSensorInfo()
->getLabel(),
);
$rows[] = array(
dt('Status'),
$result
->getStatusLabel(),
);
$rows[] = array(
dt('Message'),
$result
->getMessage(),
);
$rows[] = array(
dt('Execution time'),
$result
->getExecutionTime() . 'ms',
);
$rows[] = array(
dt('Result age'),
format_interval(time() - $result
->getTimestamp()),
);
if ($result
->getVerboseOutput()) {
$rows[] = array(
dt('Verbose output'),
$result
->getVerboseOutput(),
);
}
drush_print_table($rows);
}
function monitoring_drush_result_output_table_multiple(array $results, $show_exec_time = FALSE) {
$rows['header'] = array(
dt('Sensor'),
dt('Status'),
dt('Message'),
dt('Result age'),
);
if ($show_exec_time) {
$rows['header'][] = dt('Execution time');
}
foreach ($results as $result) {
$rows[$result
->getSensorName()] = array(
format_string("@label\n(@name)", array(
'@label' => truncate_utf8($result
->getSensorInfo()
->getLabel(), 40, TRUE, TRUE),
'@name' => $result
->getSensorName(),
)),
$result
->getStatusLabel(),
truncate_utf8($result
->getMessage(), 40, TRUE, TRUE),
format_interval(time() - $result
->getTimestamp()),
);
if ($show_exec_time) {
$rows[$result
->getSensorName()][] = $result
->getExecutionTime() . 'ms';
}
}
drush_print_table($rows);
}
function monitoring_drush_enable($sensor_name) {
$sensor_manager = monitoring_sensor_manager();
try {
$sensor_info = $sensor_manager
->getSensorInfoByName($sensor_name);
if (!$sensor_info
->isEnabled()) {
$sensor_manager
->enableSensor($sensor_name);
drush_log(dt('The sensor @name was enabled.', array(
'@name' => $sensor_info
->getLabel(),
)), 'ok');
}
else {
drush_log(dt('The sensor @name is already enabled.', array(
'@name' => $sensor_info
->getLabel(),
)), 'warning');
}
} catch (NonExistingSensorException $e) {
drush_set_error('MONITORING_SENSOR_INVALID_NAME', dt('Sensor "@name" does not exist.', array(
'@name' => $sensor_name,
)));
}
}
function monitoring_drush_disable($sensor_name) {
$sensor_manager = monitoring_sensor_manager();
try {
$sensor_info = $sensor_manager
->getSensorInfoByName($sensor_name);
if ($sensor_info
->isEnabled()) {
$sensor_manager
->disableSensor($sensor_name);
drush_log(dt('The sensor @name was disabled.', array(
'@name' => $sensor_info
->getLabel(),
)), 'ok');
}
else {
drush_log(dt('The sensor @name is already disabled.', array(
'@name' => $sensor_info
->getLabel(),
)), 'warning');
}
} catch (NonExistingSensorException $e) {
drush_set_error('MONITORING_SENSOR_INVALID_NAME', dt('Sensor "@name" does not exist.', array(
'@name' => $sensor_name,
)));
}
}
function monitoring_drush_purge_settings($sensor_name = NULL) {
if (empty($sensor_name)) {
if (drush_confirm(dt('Do you want to purge all sensor settings?'))) {
$query = db_query('DELETE FROM {variable} WHERE name LIKE :name', array(
':name' => 'monitoring_%',
));
drush_print(dt('Purged settings of @count sensors.', array(
'@count' => $query
->rowCount(),
)));
}
return;
}
$sensor_manager = monitoring_sensor_manager();
try {
$sensor_manager
->getSensorInfoByName($sensor_name);
$query = db_query('DELETE FROM {variable} WHERE name = :name', array(
':name' => monitoring_sensor_settings_key($sensor_name),
));
if ($query
->rowCount()) {
drush_print(dt('Purged settings of @sensor_name.', array(
'@sensor_name' => $sensor_name,
)));
}
else {
drush_print(dt('No settings to purge.'));
}
} catch (NonExistingSensorException $e) {
drush_set_error('MONITORING_SENSOR_INVALID_NAME', dt('Sensor "@name" does not exist.', array(
'@name' => $sensor_name,
)));
}
}