View source
<?php
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Unicode;
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-sensor-config'] = array(
'callback' => 'monitoring_drush_sensor_config',
'description' => 'Displays information about available sensors. If a sensor name provided as argument a detailed sensor config is provided.',
'arguments' => array(
'sensor_name' => 'Specific sensor name for which we want to display info.',
),
'examples' => array(
'drush monitoring-sensor-config' => 'Prints sensor config for all available sensors.',
'drush monitoring-sensor-config 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-rebuild'] = [
'callback' => 'monitoring_drush_rebuild',
'description' => 'Rebuild the list of sensors',
'drupal dependencies' => [
'monitoring',
],
];
return $items;
}
function monitoring_drush_sensor_config($sensor_name = NULL) {
if (empty($sensor_name)) {
monitoring_drush_sensor_config_all();
}
else {
monitoring_drush_sensor_config_single($sensor_name);
}
}
function monitoring_drush_sensor_config_all() {
$sensor_config_list = monitoring_sensor_manager()
->getAllSensorConfig();
$rows[] = array(
dt('Label'),
dt('Name'),
dt('Category'),
dt('Enabled'),
);
$rows[] = array(
'----',
'----',
'----',
);
foreach ($sensor_config_list as $name => $sensor_config) {
$rows[] = array(
$sensor_config
->getLabel(),
$name,
$sensor_config
->getCategory(),
$sensor_config
->isEnabled() ? t('Yes') : t('No'),
);
}
drush_print_table($rows, TRUE);
}
function monitoring_drush_sensor_config_single($sensor_name) {
$sensor_config = NULL;
try {
$sensor_config = monitoring_sensor_manager()
->getSensorConfigByName($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(
new FormattableMarkup("@label (@id)", array(
'@label' => $sensor_config
->getLabel(),
'@id' => $sensor_config
->id(),
)),
'====================',
);
$rows[] = array(
dt('Category'),
$sensor_config
->getCategory(),
);
$rows[] = array(
dt('Description'),
$sensor_config
->getDescription(),
);
$rows[] = array(
dt('Value info'),
new FormattableMarkup('type: @type, label: @label, numeric: @numeric', array(
'@type' => $sensor_config
->getValueType() ? $sensor_config
->getValueType() : dt('N/A'),
'@label' => $sensor_config
->getValueLabel() ? $sensor_config
->getValueLabel() : dt('N/A'),
'@numeric' => $sensor_config
->isNumeric() ? dt('Yes') : dt('No'),
)),
);
$rows[] = array(
dt('Caching time'),
\Drupal::service('date.formatter')
->formatInterval($sensor_config
->getCachingTime()),
);
$rows[] = array(
dt('Enabled'),
$sensor_config
->isEnabled() ? dt('Yes') : dt('No'),
);
$rows[] = array(
dt('Has thresholds'),
$sensor_config
->isDefiningThresholds() ? dt('Yes') : dt('No'),
);
drush_print_table($rows);
}
function monitoring_drush_run($sensor_name = NULL) {
$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', \Drupal::request()
->getHost());
$ttl = (int) drush_get_option('sensu-ttl');
$handlers = [];
if (drush_get_option('sensu-handlers')) {
$handlers = explode(',', drush_get_option('sensu-handlers'));
}
$metric_handlers = [];
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 = [
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 = [];
$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
->getSensorConfig()
->getCachingTime();
$sensu_output['duration'] = $result
->getExecutionTime() / 1000;
$sensu_output['source'] = $source;
drush_print(Json::encode($sensu_output));
if ($result
->getSensorConfig()
->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(Json::encode($sensu_metric_output));
}
}
}
function monitoring_drush_result_output_json(array $results, $expand = NULL) {
$json_output = array();
foreach ($results as $result) {
$sensor_id = $result
->getSensorId();
$json_output[$sensor_id] = $result
->toArray();
if ($expand == 'sensor') {
$json_output[$sensor_id]['sensor'] = $result
->getSensorConfig()
->toArray();
}
}
drush_print(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('ID'),
$result
->getSensorConfig()
->id(),
);
$rows[] = array(
dt('Label'),
$result
->getSensorConfig()
->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'),
\Drupal::service('date.formatter')
->formatInterval(time() - $result
->getTimestamp()),
);
if ($verbose_output = $result
->getVerboseOutput()) {
$rows[] = array(
dt('Verbose output'),
strip_tags(\Drupal::service('renderer')
->renderRoot($verbose_output)),
);
}
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
->getSensorId()] = array(
new FormattableMarkup("@label\n(@id)", array(
'@label' => Unicode::truncate($result
->getSensorConfig()
->getLabel(), 40, TRUE, TRUE),
'@id' => $result
->getSensorId(),
)),
$result
->getStatusLabel(),
Unicode::truncate($result
->getMessage(), 40, TRUE, TRUE),
\Drupal::service('date.formatter')
->formatInterval(time() - $result
->getTimestamp()),
);
if ($show_exec_time) {
$rows[$result
->getSensorId()][] = $result
->getExecutionTime() . 'ms';
}
}
drush_print_table($rows);
}
function monitoring_drush_enable($sensor_name) {
$sensor_manager = monitoring_sensor_manager();
try {
$sensor_config = $sensor_manager
->getSensorConfigByName($sensor_name);
if (!$sensor_config
->isEnabled()) {
$sensor_manager
->enableSensor($sensor_name);
drush_log(dt('The sensor @name was enabled.', array(
'@name' => $sensor_config
->getLabel(),
)), 'ok');
}
else {
drush_log(dt('The sensor @name is already enabled.', array(
'@name' => $sensor_config
->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_config = $sensor_manager
->getSensorConfigByName($sensor_name);
if ($sensor_config
->isEnabled()) {
$sensor_manager
->disableSensor($sensor_name);
drush_log(dt('The sensor @name was disabled.', array(
'@name' => $sensor_config
->getLabel(),
)), 'ok');
}
else {
drush_log(dt('The sensor @name is already disabled.', array(
'@name' => $sensor_config
->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_rebuild() {
\Drupal::service('monitoring.sensor_manager')
->rebuildSensors();
}