Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Check API: Difference between revisions

From MoodleDocs
Line 109: Line 109:


Each check might simply check for certain settings which are known to slow things down, or it might actually do some sort of test like multiple reads and writes to the db or filesystem to get a performance metric.
Each check might simply check for certain settings which are known to slow things down, or it might actually do some sort of test like multiple reads and writes to the db or filesystem to get a performance metric.
(no tracker yet to convert to the Check API)


=== Health checks (health) ===
=== Health checks (health) ===

Revision as of 11:59, 9 April 2020

Moodle 3.9


Checks

WARNING: Work in Progress

https://tracker.moodle.org/browse/MDL-67818

A Check is a runtime test to make sure something is working well. You can think of Checks as similar and complimentary to the Unit_test_API and Acceptance_testing but the next layer around them, and done at run time rather than dev time or build time. Like other forms of testing the tests themselves should easy to read and reason about and confirm as valid. As many types of runtime checks can't be unit tested, the checks are the test.

Checks can be used for a variety of purposes including:

  • configuration checks
  • security checks
  • status checks
  • performance checks
  • health checks

Moodle has had various types of checks and reports for a long time but they were inconsistent and not machine readable. In Moodle 3.9 they were unified under a single Check API which also enabled plugins to cleanly define their own additional checks. Some examples include:

  • a password policy plugin could add a security check
  • a custom authentication plugin can add a check that the upstream identity system can be connected to
  • a MUC store plugin could add a performance check

Having these centralized and with a consistent contract makes it much easier to ensure the whole system is running smoothly. This makes it possible for an external integration with monitoring systems such as Nagios / Icinga. The Check API is expose as an NPRE compliance cli script:

php admin/cli/checks.php

Result state of a check

Status Meaning Example
N/A This check doesn't apply - but we may still want to expose the check secure cookies setting is disabled because site is not https
Ok A component is configured, working and fast. ldap can bind and return value with low latency
Info A component is OK, and we may want to alert the admin to something non urgent such as a deprecation, or something which needs to be checked manually.
Unknown We don't yet know the state. eg it may be very expensive so it is run using the Task API and we are waiting for the answer. NOTE: unknown is generally a bad thing and is semantically treated as an error. It is better to have a result of Unknown until the first result happens, and from then on it is Ok, or perhaps Warning or Error if the last known result is getting stale. If you are caching or showing a stale result you should expose the time of this in the result summary text. A complex user security report is still running for the first time.
Warning Something is not ideal and should be addressed, eg usability or the speed of the site may be affected, but it may self heal (eg a load spike) auth_ldap could bind but was slower than normal
Error Something is wrong with a component and a feature is not working auth_ldap could not connect, so users cannot start new sessions
Critical An error which is affecting everyone in a major way Cannot read sitedata or the database, the whole site is down

How the various states are then leveraged is a local decision. A typical policy might be that health checks with a status of 'Error' or 'Critical' will page a system administrator 24/7, while 'Warning' only pages during business hours.

Check types and reports

Checks are broken down into types, which roughly map to a step life cycle of your Moodle System

Environmental checks (?)

/admin/environment.php

These are environmental checks to make sure a Moodle instance is fully setup. This page is potential candidate to move to the new Check API but it slightly more complex than the other checks so hasn't been tackled yet. It would be a deeper change and this is intrinsically part of the install and upgrade system. It is not as critical to refactor as it is already possible for a plugin to declare its own checks, via either declarative Environment_checking or programmatically with a custom check:

https://docs.moodle.org/dev/Environment_checking#Custom_checks

Configuration checks (?)

/admin/index.php?cache=1

The Admin notifications page performs a mixture of checks, including security, status, and performance but none are as exhaustive as the checks in the reports below. It also does checks such as whether the web services for the Moodle Mobile App are turned on, and whether the site has been registered. Long term this page could show a summary of all the other check reports, or perhaps just the checks which are not in an OK state.

Security checks (security)

These are checks to make sure a Moodle instance is hardened correctly for you needs.

/report/security/index.php

https://tracker.moodle.org/browse/MDL-67776

Status checks (status)

/report/status/index.php

A status check is an 'in the moment' test and covers operational tests such as 'can moodle connect to ldap'. The main core status checks are that cron is running regularly and there has been no failed tasks.

An additional status check is likely the most common type of check a plugin would define. Especially a plugin that connects to a 3rd party service. If the concept of 'OK' requires some sort of threshold, eg network response within 500ms, then that threshold should be managed by the plugin and optionally exposed as a admin setting. The plugin may choose to have different thresholds for Warning / Error / Critical.

https://tracker.moodle.org/browse/MDL-47271

Performance checks (performance)

/report/performance/index.php

Each check might simply check for certain settings which are known to slow things down, or it might actually do some sort of test like multiple reads and writes to the db or filesystem to get a performance metric.

Health checks (health)

/admin/tool/health/

The 'health center' is currently unsupported and contains some very old code. It is conceptually similar to 'status' checks except larger more long terms issues, such as detecting corrupt records. Ideally it is improved and converted to the Check API, see https://tracker.moodle.org/browse/MDL-67228

Implementing a new check

A check class

And make a new check class in mod/myplugin/classes/check/foobar.php

<?php namespace mod_myplugin\check; use core\check\check;

class foobar extends check {

   public function get_action_link(): ?\action_link {
       $url = new \moodle_url(/mod/myplugin/dosomething.php'),
       return new \action_link($url, get_string('sitepolicies', 'admin'));
   }
   public function get_result() : result {
       if (some_check()) {
           $status = result::ERROR;
           $summary = get_string('check_foobar_error', 'mod_myplugin');
       } else {
           $status = result::OK;
           $summary = get_string('check_foobar_ok', 'mod_myplugin');
       }
       $details = get_string('check_details', 'mod_myplugin');
       return new result($status, $summary, $details);
   }

}

lib.php callback

Decide on what type of check, ie what report it should be included into. Some checks might make sense to be reused with more than one report, eg both Performance and Health.

Implement a the right callback in lib.php for the report you want to add to, and return an array (usually with only 1 item) of check objects:

/mod/myplugin/lib.php

function mod_myplugin_security_checks() {

   return [new mod_myplugin\check\foobar()];

}

Multiple instances of checks

Checks have been designed to be dynamic so you can return different checks depending on configuration, so auth_ldap would not return a check if the plugin is not enabled. Hypothetically if auth_ldap could be configured with 5 ldap servers then you could return 5 independent checks for each remote connection, each with different labels and information.

If you plan to return multiple instances of a check class, make sure that each instance has a unique id.

function mod_myplugin_security_checks() {

   return [
       new mod_myplugin\check\foobar('one'),
       new mod_myplugin\check\foobar('two'),
   ];

}

Set the internal id in a way which is unique across your components namespace:

<?php namespace mod_myplugin\check; use core\check\check;

class foobar extends check {

   public function __construct($id) {
       $this->id = 'foobar' . $id;
   }

}

Performance and check details

Checks can provide details on a check, such as the complete list of bad records. Generally this type of information might be expensive to produce so you can defer this lookup until get_details() is called specifically rather than setting this in the constructor.

<?php namespace mod_myplugin\check; use core\check\check;

class foobar extends check {

   public function __construct() {
       $this->details = 'some details!';
       $this->status = check::ERROR;
       $this->summary = 'foobar summary';
   }
   public function get_details() : string {
       // Some really expensive lookup.
       $this->details = 'expensive details!';
   }

}