Skip to content

Commit

Permalink
Add diagnostic to check last time archiving was run successfully and … (
Browse files Browse the repository at this point in the history
matomo-org#13972)

* Add diagnostic to check last time archiving was run successfully and display notification if empty report and archiving has not been run recently.

* Move cron archiving diagnostics next to each other.

* Add new test for archiving not done in time check.

* Remove TODO comment.
  • Loading branch information
diosmosis authored Mar 12, 2019
1 parent 549578d commit e26f5e7
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 2 deletions.
104 changes: 104 additions & 0 deletions plugins/Diagnostics/Diagnostic/CronArchivingLastRunCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Diagnostics\Diagnostic;

use Piwik\ArchiveProcessor\Rules;
use Piwik\Config;
use Piwik\CronArchive;
use Piwik\Date;
use Piwik\Metrics\Formatter;
use Piwik\Option;
use Piwik\Plugins\Intl\DateTimeFormatProvider;
use Piwik\Translation\Translator;

/**
* Check if cron archiving has run in the last 24-48 hrs.
*/
class CronArchivingLastRunCheck implements Diagnostic
{
const SECONDS_IN_DAY = 86400;

/**
* @var Translator
*/
private $translator;

public function __construct(Translator $translator)
{
$this->translator = $translator;
}

public function execute()
{
$label = $this->translator->translate('Diagnostics_CronArchivingLastRunCheck');
$commandToRerun = '<code>' . $this->getArchivingCommand() . '</code>';
$coreArchiveShort = '<code>core:archive</code>';
$mailto = '<code>MAILTO</code>';

// check cron archiving has been enabled
$isBrowserTriggerDisabled = !Rules::isBrowserTriggerEnabled();
if (!$isBrowserTriggerDisabled) {
$comment = $this->translator->translate('Diagnostics_BrowserTriggeredArchivingEnabled', [
'<a href="https://matomo.org/docs/setup-auto-archiving/" target="_blank" rel="noreferrer noopener">', '</a>']);
return [DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment)];
}

// check archiving has been run
$lastRunTime = (int)Option::get(CronArchive::OPTION_ARCHIVING_FINISHED_TS);
if (empty($lastRunTime)) {
$comment = $this->translator->translate('Diagnostics_CronArchivingHasNotRun')
. '<br/><br/>' . $this->translator->translate('Diagnostics_CronArchivingRunDetails', [$coreArchiveShort, $mailto, $commandToRerun]);;
return [DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_ERROR, $comment)];
}

$lastRunTimePretty = Date::factory($lastRunTime)->getLocalized(DateTimeFormatProvider::DATETIME_FORMAT_LONG);

$diffTime = self::getTimeSinceLastSuccessfulRun($lastRunTime);

$formatter = new Formatter();
$diffTimePretty = $formatter->getPrettyTimeFromSeconds($diffTime);

$errorComment = $this->translator->translate('Diagnostics_CronArchivingHasNotRunInAWhile', [$lastRunTimePretty, $diffTimePretty])
. '<br/><br/>' . $this->translator->translate('Diagnostics_CronArchivingRunDetails', [$coreArchiveShort, $mailto, $commandToRerun]);

// check archiving has been run recently
if ($diffTime > self::SECONDS_IN_DAY * 2) {
$result = DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_ERROR, $errorComment);
} else if ($diffTime > self::SECONDS_IN_DAY) {
$result = DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $errorComment);
} else {
$comment = $this->translator->translate('Diagnostics_CronArchivingRanSuccessfullyXAgo', $diffTimePretty);
$result = DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, $comment);
}

return [$result];
}

private function getArchivingCommand()
{
$domain = Config::getHostname();
return PIWIK_INCLUDE_PATH . ' --matomo-domain=' . $domain . ' core:archive';
}

public static function getTimeSinceLastSuccessfulRun($lastRunTime = null)
{
if (empty($lastRunTime)) {
$lastRunTime = (int)Option::get(CronArchive::OPTION_ARCHIVING_FINISHED_TS);
}

if (empty($lastRunTime)) {
return null;
}

$now = Date::now()->getTimestamp();
$diffTime = $now - $lastRunTime;

return $diffTime;
}
}
35 changes: 35 additions & 0 deletions plugins/Diagnostics/Diagnostics.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,25 @@

namespace Piwik\Plugins\Diagnostics;

use Piwik\ArchiveProcessor\Rules;
use Piwik\Notification;
use Piwik\Piwik;
use Piwik\Plugin;
use Piwik\Plugins\Diagnostics\Diagnostic\CronArchivingLastRunCheck;
use Piwik\View;

class Diagnostics extends Plugin
{
const NO_DATA_ARCHIVING_NOT_RUN_NOTIFICATION_ID = 'DiagnosticsNoDataArchivingNotRun';

/**
* @see Piwik\Plugin::registerEvents
*/
public function registerEvents()
{
return array(
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'Visualization.onNoData' => ['function' => 'onNoData', 'before' => true],
);
}

Expand All @@ -27,4 +35,31 @@ public function getStylesheetFiles(&$stylesheets)
$stylesheets[] = "plugins/Diagnostics/stylesheets/configfile.less";
}

public function onNoData(View $dataTableView)
{
if (!Piwik::isUserHasSomeAdminAccess()) {
return;
}

if (Rules::isBrowserTriggerEnabled()) {
return;
}

$lastSuccessfulRun = CronArchivingLastRunCheck::getTimeSinceLastSuccessfulRun();
if ($lastSuccessfulRun > CronArchivingLastRunCheck::SECONDS_IN_DAY) {
$content = Piwik::translate('Diagnostics_NoDataForReportArchivingNotRun', [
'<a href="https://matomo.org/docs/setup-auto-archiving/" target="_blank" rel="noreferrer noopener">',
'</a>',
]);

$notification = new Notification($content);
$notification->priority = Notification::PRIORITY_HIGH;
$notification->context = Notification::CONTEXT_INFO;
$notification->flags = Notification::FLAG_NO_CLEAR;
$notification->type = Notification::TYPE_TRANSIENT;
$notification->raw = true;

$dataTableView->notifications[self::NO_DATA_ARCHIVING_NOT_RUN_NOTIFICATION_ID] = $notification;
}
}
}
3 changes: 3 additions & 0 deletions plugins/Diagnostics/config/config.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

use Piwik\Plugins\Diagnostics\Diagnostic\CronArchivingLastRunCheck;

return array(
// Diagnostics for everything that is required for Piwik to run
'diagnostics.required' => array(
Expand All @@ -23,6 +25,7 @@
DI\get('Piwik\Plugins\Diagnostics\Diagnostic\RecommendedFunctionsCheck'),
DI\get('Piwik\Plugins\Diagnostics\Diagnostic\NfsDiskCheck'),
DI\get('Piwik\Plugins\Diagnostics\Diagnostic\CronArchivingCheck'),
DI\get(CronArchivingLastRunCheck::class),
DI\get('Piwik\Plugins\Diagnostics\Diagnostic\LoadDataInfileCheck'),
Di\get('Piwik\Plugins\Diagnostics\Diagnostic\DbOverSSLCheck'),
Di\get('Piwik\Plugins\Diagnostics\Diagnostic\DbMaxPacket'),
Expand Down
11 changes: 9 additions & 2 deletions plugins/Diagnostics/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
"MysqlMaxPacketSizeWarning": "It is recommended to configure a 'max_allowed_packet' size in your MySQL database of at least %1$s. Configured is currently %2$s.",
"ConfigFileIntroduction": "Here you can view the Matomo configuration. If you are running Matomo in a load balanced environment the page might be different depending from which server this page is loaded. Rows with a different background color are changed config values that are specified for example in the %1$s file.",
"HideUnchanged": "If you want to see only changed values you can %1$shide all unchanged values%2$s.",
"Sections": "Sections"
"Sections": "Sections",
"CronArchivingLastRunCheck": "Last Successful Archiving Completion",
"CronArchivingHasNotRun": "Archiving has not yet run successfully.",
"CronArchivingHasNotRunInAWhile": "Archiving last ran successfully on %1$s which is %2$s ago.",
"CronArchivingRunDetails": "Please check that you have setup a crontab calling the %1$s console command, and that you have configured a %2$s to receive errors by email if archiving fails. You can also try to run the console command to archive your reports manually: %3$s",
"CronArchivingRanSuccessfullyXAgo": "The archiving process completed successfully %1$s ago.",
"BrowserTriggeredArchivingEnabled": "For optimal performance and a speedy Matomo, it is highly recommended to set up a crontab to automatically archive your reports, and to disable browser triggering in the Matomo settings. %1$sLearn more.%2$s",
"NoDataForReportArchivingNotRun": "The archiving of your reports hasn't been executed recently, %1$slearn more about how to generate your reports.%2$s"
}
}
}
6 changes: 6 additions & 0 deletions plugins/SegmentEditor/SegmentEditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Piwik\Notification;
use Piwik\Piwik;
use Piwik\Plugins\CoreHome\SystemSummary;
use Piwik\Plugins\Diagnostics\Diagnostics;
use Piwik\Segment;
use Piwik\SettingsPiwik;
use Piwik\SettingsServer;
Expand Down Expand Up @@ -115,6 +116,11 @@ public function onNoArchiveData()

public function onNoData(View $dataTableView)
{
// if the archiving hasn't run in a while notification is up, don't display this one
if (isset($dataTableView->notifications[Diagnostics::NO_DATA_ARCHIVING_NOT_RUN_NOTIFICATION_ID])) {
return;
}

$segmentInfo = $this->getSegmentIfIsUnprocessed();
if (empty($segmentInfo)) {
return;
Expand Down
36 changes: 36 additions & 0 deletions tests/PHPUnit/Integration/ReportRenderingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/

namespace Piwik\Tests\Integration;

use Piwik\ArchiveProcessor\Rules;
use Piwik\CronArchive;
use Piwik\FrontController;
use Piwik\Option;
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;

class ReportRenderingTest extends IntegrationTestCase
{
public function test_reportHasCorrectNotification_WhenReportHasNoData_AndArchivingHasNotRunRecently()
{
$idSite = Fixture::createWebsite('2012-01-02 03:04:44');
Option::set(CronArchive::OPTION_ARCHIVING_FINISHED_TS, time() - 120000);
Option::set(Rules::OPTION_BROWSER_TRIGGER_ARCHIVING, 0);

$_GET['idSite'] = $idSite;
$_GET['date'] = '2012-05-06';
$_GET['period'] = 'day';

$frontController = FrontController::getInstance();
$response = $frontController->dispatch('DevicesDetection', 'getBrand');

$this->assertContains('Diagnostics_NoDataForReportArchivingNotRun', $response);
}
}

0 comments on commit e26f5e7

Please sign in to comment.