Site Audit is a Drupal static site analysis platform that generates reports with actionable best practice recommendations.
Every Drupal site is unique, with its own individual configuration, content, audience, and so forth. With that said, they all have the same core infrastructure and configuration; Drupal! Therefore, it's possible to perform performance and behavior gathering to inspect any site.
Site Audit uses a technique known as static program analysis. This mechanism does not actually perform requests on the target site, and in doing so avoids the observer effect. It's non-intrusive, so no installation into the target site or configuration is required.
The end result is a fast, repeatable report that can help detect common problems and provide introspection into Drupal sites. Reports can be generated in multiple formats, including plain text, HTML, and JSON.
Site Audit can also be extended by other projects to add custom reports and checks.
There are two major versions of Site Audit:
- 7.x-1.x - Supports Drupal 7.
- 8.x-2.x - Supports Drupal 8; under heavy development.
Site Audit includes a number of comprehensive reports, each consisting of one or more checks. Site Audit reports include:
- Cache - optimal Drupal caching settings
Site Audit is not a module; do not install it in your site root.
Copy the entire Site Audit project to either your unified or personal Drush folder in the commands subdirectory, like
~/.drush/commands
then clear Drush's cache:
drush cc drush
See http://docs.drush.org/en/master/commands/ to learn more about installing commands into Drush.
drush help --filter=site_audit
drush ac
Create a new file or overwrite:
drush ac --html --detail > ~/Desktop/report.html
Continue writing to a file:
drush abp --html --detail >> ~/Desktop/report.html
Run every report with maximum detail, skipping Google insights and adding Twitter Bootstrap for styling:
drush aa --html --bootstrap --detail --skip=insights > ~/Desktop/report.html
For the Audit All command, an individual report can be skipped by name using the option --skip.
For all commands, individual checks can be skipped by specifying the combination of the report name and the check name. For example, if you wanted to skip the System check in the Status report, use the following convention:
--skip=StatusSystem
Multiple skip values can be used, comma separated.
If you want to permanently opt-out of a check, use the $conf array in settings.php with the individual check names in the same format as the skip option. For example, to permanently opt-out of the PageCompression check in the Cache report:
$conf['site_audit']['opt_out']['CachePageCompression'] = TRUE;
Some commands such as the cache audit (ac) have the ability to optionally produce results that are specific to a particular platform. Currently only supports Pantheon, but submit a patch if you have another platform that should have explicit support that will be helpful to other developers.
drush @pantheon.SITENAME.ENV --vendor=pantheon --detail ac
There are two classes that you should be aware of:
-
SiteAuditReport - a collection of Checks, run in sequential order. If a check sets the abort property to TRUE, no further Checks in the report will be executed. The Check names are defined in hook_drush_command with the key name "checks". Check names must match the file name of the actual Check, including capitalization.
-
SiteAuditCheck - an individual Check; treat them like a unit test, in that each check should be looking for one thing at a time.
The AuditCheck class has a number of helpful properties:
- abort - if set to TRUE, will tell the report not to execute any further checks after the completion of the current check. For example, if you're checking Views but the Views module isn't enabled, abort.
- html - if set to TRUE, indicates that the response contains HTML characters.
- registry - use this to pass content from each check to another and within the check itself. Use sparingly, as the registry itself is not cleared. This is safer than a global.
Site Audit supports specialized Reports or Checks that are specific to a particular use case or project. A couple steps are needed; regardless of the approach, a Drush command file is required for the project.
There are no requirements for file structure; depending on the number of checks,
it may be easiest to create a project.site_audit.inc
file within your
project to consolidate the functionality. You can also define the Reports and
Checks within the actual Drush command, but I'd recommend instead requiring the
code only upon execution, otherwise every other drush command execution will
include all the overhead of loading custom code.
In hook_drush_command()
, define a command with the following format:
$items['audit_REPORT'] = array(
// Describe the Report.
'description' => dt('DESCRIPTION.'),
// A short alias for the command. Check site_audit.drush.inc to avoid
// collisions.
'aliases' => array('aN'),
// Specify the maximum bootstrap required for your Checks; if interaction with
// the actual Drupal site is required, use DRUSH_BOOTSTRAP_DRUPAL_FULL.
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
// Names of the individual checks, in order of execution.
'checks' => array(
// If a Check is defined in its own file, the location can be passed to a
// require_once within the Report execution.
array(
'name' => 'FirstCheck',
'location' => __DIR__ . '/site_audit/checks/FirstCheck.php',
);
// If just the name of the check is defined, the assumption is made that the
// code has already been loaded.
'SecondCheck',
'ThirdCheck',
'LastCheck',
),
// Options available for all site_audit commands. You can add your own options
// as well, but make sure to combine the arrays.
'options' => site_audit_common_options(),
);
Define a command callback so the custom Report can be executed individually.
/**
* Command callback for drush audit_NAME.
*/
function drush_PROJECT_audit_REPORT() {
require_once __DIR__ . '/PROJECT.site_audit.inc';
$report = new SiteAuditReportNAME();
$report->render();
}
Finally, include the custom Report to audit_all. The Report name is case-sensitive. The location will be used for a ````require_once``` statement when loading the Report class.
/**
* Implements hook_drush_command_alter().
*/
function security_review_drush_command_alter(&$command) {
if ($command['command'] == 'audit_all') {
$command['reports'][] = array(
'name' => 'Security',
'location' => __DIR__ . '/PROJECT.site_audit.inc',
);
}
}
Custom Checks should extend SiteAuditCheckAbstract
. If including HTML,
be sure to check to see if the HTML option is being used. For example:
if (drush_get_option('html')) {
$values = $this->registry['semantically_significant_name'];
if (drush_get_option('html')) {
$ret_val .= '<ul>';
foreach ($values as $value) {
$ret_val .= '<li>' . $value . '</li>';
}
$ret_val .= '</ul>';
}
else {
// Text-only rendering...
}
}
As Check names are defined in the Report command, just alter the target command name.
/**
* Implements hook_drush_command_alter().
*/
function security_review_drush_command_alter(&$command) {
if ($command['command'] == 'audit_NAME') {
$command['checks'][] = array(
'name' => 'CheckName',
'location' => __DIR__ . '/PROJECT.site_audit.inc',
);
}
}
Site Audit comes with a suite of functional tests testing all the platform independent functionality of the project.
- Run
composer update
to install all the dependencies of site-audit which includes PHPUnit and drush that is used for testing. - Export the environment variable
UNISH_DB_URL
with correct MySQL username, password and host for PHPUnit to use for testing
export UNISH_DB_URL="mysql://USERNAME:PASSWORD@HOST"
- To run all the tests, execute
./test.sh
from within the site_audit directory. - To run the tests selectively, execute
./test.sh --filter="*REPORTNAME*" tests
whereREPORTNAME
is the name of a report, such asExtensions
- All the tests are present inside the
tests
directory. - Add test for a particular check inside the proper file for the check's report.
- For a tutorial on writing tests for drush commands, refer to http://ninjaducks.in/hacking/writing-tests-for-drush-commands/
Release notes are maintained at https://www.drupal.org/node/2022771/release
The version of Site Audit is found in site_audit.info
and can be
displayed with the command:
drush site-audit-version
The response will be in the form:
Site Audit v#.#
Site Audit is written and maintained by Jon Peck, http://about.me/jonpeck
Site Audit can be found at:
Thank you to Suzanne Aldrich, Kelly Bell, Aimee Degnan, Joe Miller, Matt Parker, Ben Sheldon, David Strauss, and everyone else who has given feedback and suggestions to make this a better project.