monitoring-8.x-1.x-dev/src/Commands/MonitoringCommands.php

src/Commands/MonitoringCommands.php
<?php

namespace Drupal\monitoring\Commands;

use Consolidation\AnnotatedCommand\CommandResult;
use Consolidation\OutputFormatters\StructuredData\PropertyList;
use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\monitoring\Result\SensorResultInterface;
use Drupal\monitoring\Sensor\SensorManager;
use Drush\Commands\DrushCommands;

/**
 * A Drush commandfile for the Monitoring module.
 */
class MonitoringCommands extends DrushCommands {

  /**
   * Exit code for an unknown sensor status.
   */
  public const SENSOR_STATUS_UNKNOWN = 3;

  /**
   * Exit code for a critical sensor status.
   */
  public const SENSOR_STATUS_CRITICAL = 2;

  /**
   * Exit code for a warning sensor status.
   */
  public const SENSOR_STATUS_WARNING = 1;

  /**
   * Exit code for a proper run with OK status.
   */
  public const SENSOR_STATUS_OK = 0;

  /**
   * The Sensor Manager service.
   *
   * @var \Drupal\monitoring\Sensor\SensorManager
   */
  protected $sensorManager;

  /**
   * The Date formatter service.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * MonitoringCommands constructor.
   *
   * @param \Drupal\monitoring\Sensor\SensorManager $sensor_manager
   *   The Sensor Manager service.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The Date formatter service.
   */
  public function __construct(SensorManager $sensor_manager, DateFormatterInterface $date_formatter) {
    parent::__construct();
    $this->sensorManager = $sensor_manager;
    $this->dateFormatter = $date_formatter;
  }

  /**
   * List all sensors.
   *
   * @validate-module-enabled monitoring
   *
   * @command monitoring:list-sensors
   * @aliases monitoring-list-sensors
   * @field-labels
   *   label: Label
   *   name: Name
   *   category: Category
   *   enabled: Enabled
   *   description: Description
   *   value_info: Value info
   *   caching_time: Caching time
   *   has_thresholds: Has thresholds
   * @default-fields label,name,category,enabled
   *
   * @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
   *   A list with sensors.
   */
  public function sensorConfigAll() {
    $sensor_config_list = $this->sensorManager->getAllSensorConfig();

    $rows = [];
    foreach ($sensor_config_list as $name => $sensor_config) {
      $rows[] = [
        'label' => $sensor_config->label(),
        'name' => $name,
        'category' => $sensor_config->getCategory(),
        'description' => $sensor_config->getDescription(),
        'value_info' => new FormattableMarkup('type: @type, label: @label, numeric: @numeric', [
          '@type' => $sensor_config->getValueType() ?: dt('N/A'),
          '@label' => $sensor_config->getValueLabel() ?: dt('N/A'),
          '@numeric' => $sensor_config->isNumeric() ? dt('Yes') : dt('No'),
        ]),
        'caching_time' => $this->dateFormatter->formatInterval($sensor_config->getCachingTime()),
        'enabled' => $sensor_config->isEnabled() ? dt('Yes') : dt('No'),
        'has_thresholds' => $sensor_config->isDefiningThresholds() ? dt('Yes') : dt('No'),
      ];
    }

    return new RowsOfFields($rows);
  }

  /**
   * Displays detailed information about the sensor config.
   *
   * @param string $sensor_name
   *   Specific sensor name for which we want to display info.
   *
   * @usage drush monitoring-sensor-config node_new
   *   Prints info of the node_new sensor.
   * @validate-module-enabled monitoring
   *
   * @command monitoring:sensor-config
   * @aliases monitoring-sensor-config
   * @field-labels
   *   label: Label
   *   category: Category
   *   description: Description
   *   value_info: Value info
   *   caching_time: Caching time
   *   enabled: Enabled
   *   has_thresholds: Has thresholds
   *
   * @return \Consolidation\OutputFormatters\StructuredData\PropertyList
   *   A list with sensor config properties.
   */
  public function sensorConfig($sensor_name = NULL) {
    $sensor_config = $this->sensorManager->getSensorConfigByName($sensor_name);

    $data = [
      'label' => $sensor_config->label(),
      'category' => $sensor_config->getCategory(),
      'description' => $sensor_config->getDescription(),
      'value_info' => new FormattableMarkup('type: @type, label: @label, numeric: @numeric', [
        '@type' => $sensor_config->getValueType() ?: dt('N/A'),
        '@label' => $sensor_config->getValueLabel() ?: dt('N/A'),
        '@numeric' => $sensor_config->isNumeric() ? dt('Yes') : dt('No'),
      ]),
      'caching_time' => $this->dateFormatter->formatInterval($sensor_config->getCachingTime()),
      'enabled' => $sensor_config->isEnabled() ? dt('Yes') : dt('No'),
      'has_thresholds' => $sensor_config->isDefiningThresholds() ? dt('Yes') : dt('No'),
    ];

    return new PropertyList($data);
  }

  /**
   * Runs all sensors or a specific sensor and provides verbose data.
   *
   * @param string $sensor_name
   *   Sensor name to invoke or keep empty to invoke all sensors.
   * @param array $options
   *   An associative array of options whose values come from cli, aliases,
   *   config, etc.
   *
   * @option force
   *   If the sensor execution should be forced in case cached result is
   *   available.
   * @option output
   *   (deprecated) Use --format for standard outputs and --sensu-output for
   *   a format suitable for sensu.
   * @option expand
   *   Relevant only for the json output. Currently "sensor" value supported.
   * @option sensu-source
   *   Relevant only for sensu output. The sensu source. Defaults to the
   *   host name.
   * @option sensu-ttl
   *   Relevant only for sensu output. Sensu TTL (Time to live)
   * @option sensu-handlers
   *   Relevant only for sensu output. A comma separated list of Sensu handlers
   *   (names).
   * @option sensu-metric-handlers
   *   Relevant only for sensu output. Defaults to the Sensu handlers.
   * @option sensu-metrics
   *   Relevant only for sensu output. Expose numeric sensors additionally as
   *   metrics. Enabled by default.
   * @option sensu-output
   *   Use this option to format the output for sensu. To get other formats use
   *   the drush option --format.
   *
   * @usage drush monitoring-run monitoring_git_dirty_tree
   *   Runs sensor to monitor the git status.
   * @usage drush monitoring-run --verbose monitoring_git_dirty_tree
   *   Runs sensor to monitor the git status and displays verbose information.
   * @usage 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.
   * @usage 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.
   * @validate-module-enabled monitoring
   *
   * @command monitoring:run
   * @aliases monitoring-run
   * @field-labels
   *   sensor_name: ID
   *   label: Label
   *   status: Status
   *   message: Message
   *   exec_time: Execution time
   *   result_age: Result age
   *   value: Value
   *   verbose: Verbose
   *   sensor: Sensor data
   *
   * @return \Consolidation\AnnotatedCommand\CommandResult
   *   The result list with exit code.
   */
  public function run($sensor_name = NULL, array $options = [
    'force' => NULL,
    'output' => NULL,
    'expand' => NULL,
    'show-exec-time' => NULL,
    'sensu-source' => NULL,
    'sensu-ttl' => NULL,
    'sensu-handlers' => NULL,
    'sensu-metric-handlers' => NULL,
    'sensu-metrics' => true,
  ]) {

    $sensor_names = [];
    if (!empty($sensor_name)) {
      $sensor_names[] = $sensor_name;
    }
    $results = monitoring_sensor_run_multiple($sensor_names, $options['force'], $options['verbose']);

    $rows = [];
    foreach ($results as $key => $result) {
      $rows[$key] = [
        'sensor_name' => $result->getSensorId(),
        'label' => $result->getSensorConfig()->getLabel(),
        'status' => $result->getStatusLabel(),
        'message' => $result->getMessage(),
        'exec_time' => $result->getExecutionTime(),
        'result_age' => $this->dateFormatter->formatInterval(time() - $result->getTimestamp()),
      ];
      if ($options['format'] != 'table') {
        $rows[$key]['value'] = $result->getValue();
        if ($options['expand'] == 'sensor') {
          $rows[$key]['sensor'] = $result->getSensorConfig()->toArray();
        }
      }

      // Add the verbose output if requested.
      if ($verbose_output = $result->getVerboseOutput()) {
        // @todo Improve plaintext rendering for tables(view sensor).
        $rows[$key]['verbose'] = strip_tags(\Drupal::service('renderer')->renderRoot($verbose_output));
      }
    }

    $status = self::SENSOR_STATUS_OK;
    foreach ($results as $result) {
      if ($status < self::SENSOR_STATUS_CRITICAL && $result->isCritical()) {
        $status = self::SENSOR_STATUS_CRITICAL;
        // We already have the highest status so we can stop looping now.
        break;
      }
      if ($status < self::SENSOR_STATUS_UNKNOWN && $result->isUnknown()) {
        $status = self::SENSOR_STATUS_UNKNOWN;
      }
      elseif ($status < self::SENSOR_STATUS_WARNING && $result->isWarning()) {
        $status = self::SENSOR_STATUS_WARNING;
      }
    }

    if ($options['output'] ==  'sensu' || $options['sensu-output']) {
      $source = $options['sensu-source'] ?: \Drupal::request()->getHost();
      $ttl = (int) $options['sensu-ttl'];
      $handlers = explode(',', $options['sensu-handlers']);
      $metric_handlers = explode(',', $options['sensu-metric-handlers']);
      $this->outputSensuFormat($results, $source, $ttl, $handlers, $metric_handlers, $options['sensu-metrics']);
      return CommandResult::exitCode($status);
    }
    elseif ($options['output'] && $options['output'] !== 'sensu') {
      $this->logger()->error(dt('Unsupported output option @output. Use the --format option to specify formatting options.', ['@output' => $options['output']]));
      return CommandResult::exitCode(MONITORING_DRUSH_SENSOR_STATUS_UNKNOWN);
    }

    return CommandResult::dataWithExitCode(new RowsOfFields($rows), $status);
  }

  /**
   * Enable specified monitoring sensor.
   *
   * @param string $sensor_name
   *   Sensor name to enable.
   *
   * @usage drush monitoring-enable monitoring_git_dirty_tree
   *   Enables monitoring_git_dirty_tree sensor.
   * @validate-module-enabled monitoring
   *
   * @command monitoring:enable
   * @aliases monitoring-enable
   */
  public function enable($sensor_name) {
    $sensor_config = $this->sensorManager->getSensorConfigByName($sensor_name);

    if ($sensor_config->isEnabled()) {
      $message = dt('The sensor @name is already enabled.', ['@name' => $sensor_config->label()]);
      $this->logger()->notice($message);
      return;
    }
    $this->sensorManager->enableSensor($sensor_name);
    $message = dt('The sensor @name was enabled.', ['@name' => $sensor_config->label()]);
    /* @noinspection PhpUndefinedMethodInspection */
    $this->logger()->success($message);
  }

  /**
   * Disable specified monitoring sensor.
   *
   * @param string $sensor_name
   *   Sensor name to disable.
   *
   * @usage drush monitoring-disable monitoring_git_dirty_tree
   *   Disables monitoring_git_dirty_tree sensor.
   * @validate-module-enabled monitoring
   *
   * @command monitoring:disable
   * @aliases monitoring-disable
   */
  public function disable($sensor_name) {
    $sensor_config = $this->sensorManager->getSensorConfigByName($sensor_name);

    if (!$sensor_config->isEnabled()) {
      $message = dt('The sensor @name is already disabled.', ['@name' => $sensor_config->label()]);
      $this->logger()->notice($message);
      return;
    }
    $this->sensorManager->disableSensor($sensor_name);
    $message = dt('The sensor @name was disabled.', ['@name' => $sensor_config->label()]);
    /* @noinspection PhpUndefinedMethodInspection */
    $this->logger()->success($message);
  }

  /**
   * Rebuild the list of sensors.
   *
   * @validate-module-enabled monitoring
   *
   * @command monitoring:rebuild
   * @aliases monitoring-rebuild
   */
  public function rebuild() {
    $this->sensorManager->rebuildSensors();
    /* @noinspection PhpUndefinedMethodInspection */
    $this->logger()->success(dt('Sensors rebuilt.'));
  }

  /**
   * Results output in sensu format.
   *
   * @param \Drupal\monitoring\Result\SensorResultInterface[] $results
   *   List of sensor result objects.
   * @param string $source
   *   Sensu source.
   * @param int $ttl
   *   Sensor time to live.
   * @param array $handlers
   *   Sensu handlers.
   * @param array $metric_handlers
   *   Sensu metric handlers.
   * @param bool $metrics
   *   Sensu metrics.
   */
  protected function outputSensuFormat(array $results, $source, $ttl, array $handlers, array $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) {
      // Build sensu check 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;
      $this->output()->writeln(Json::encode($sensu_output));

      // Also print numeric sensors as metrics, if enabled.
      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;
        }

        // Build the metrics data.
        $reversed_source = implode('.', array_reverse(explode('.', $sensu_output['source'])));
        $value = $result->getValue();
        $executed = $result->getTimestamp();
        $sensu_metric_output['output'] = $reversed_source . '.' . $name . ' ' . $value . ' ' . $executed;
        $this->output()->writeln(Json::encode($sensu_metric_output));
      }
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc