mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
MDL-41284 hack stats to use new log readers if available
This commit is contained in:
parent
e6f0b5f135
commit
92927fba72
@ -942,9 +942,31 @@ function stats_get_start_from($str) {
|
||||
// decide what to do based on our config setting (either all or none or a timestamp)
|
||||
switch ($CFG->statsfirstrun) {
|
||||
case 'all':
|
||||
if ($firstlog = $DB->get_field_sql('SELECT MIN(time) FROM {log}')) {
|
||||
$manager = get_log_manager();
|
||||
$stores = $manager->get_readers();
|
||||
$firstlog = false;
|
||||
foreach ($stores as $store) {
|
||||
if ($store instanceof \core\log\sql_internal_reader) {
|
||||
$logtable = $store->get_internal_log_table_name();
|
||||
if (!$logtable) {
|
||||
continue;
|
||||
}
|
||||
$first = $DB->get_field_sql("SELECT MIN(timecreated) FROM {{$logtable}}");
|
||||
if ($first and (!$firstlog or $firstlog > $first)) {
|
||||
$firstlog = $first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$first = $DB->get_field_sql('SELECT MIN(time) FROM {log}');
|
||||
if ($first and (!$firstlog or $firstlog > $first)) {
|
||||
$firstlog = $first;
|
||||
}
|
||||
|
||||
if ($firstlog) {
|
||||
return $firstlog;
|
||||
}
|
||||
|
||||
default:
|
||||
if (is_numeric($CFG->statsfirstrun)) {
|
||||
return time() - $CFG->statsfirstrun;
|
||||
@ -1698,9 +1720,9 @@ function stats_temp_table_drop() {
|
||||
*
|
||||
* This function is meant to be called once at the start of stats generation
|
||||
*
|
||||
* @param timestart timestamp of the start time of logs view
|
||||
* @param timeend timestamp of the end time of logs view
|
||||
* @return boolen success (true) or failure(false)
|
||||
* @param int timestart timestamp of the start time of logs view
|
||||
* @param int timeend timestamp of the end time of logs view
|
||||
* @return bool success (true) or failure(false)
|
||||
*/
|
||||
function stats_temp_table_setup() {
|
||||
global $DB;
|
||||
@ -1721,19 +1743,68 @@ function stats_temp_table_setup() {
|
||||
*
|
||||
* This function is meant to be called to get a new day of data
|
||||
*
|
||||
* @param timestart timestamp of the start time of logs view
|
||||
* @param timeend timestamp of the end time of logs view
|
||||
* @return boolen success (true) or failure(false)
|
||||
* @param int timestamp of the start time of logs view
|
||||
* @param int timestamp of the end time of logs view
|
||||
* @return bool success (true) or failure(false)
|
||||
*/
|
||||
function stats_temp_table_fill($timestart, $timeend) {
|
||||
global $DB;
|
||||
|
||||
$sql = 'INSERT INTO {temp_log1} (userid, course, action)
|
||||
// First decide from where we want the data.
|
||||
|
||||
SELECT userid, course, action FROM {log}
|
||||
WHERE time >= ? AND time < ?';
|
||||
$params = array('timestart' => $timestart, 'timeend' => $timeend, 'loginevent' => '\core\event\user_loggedin');
|
||||
|
||||
$DB->execute($sql, array($timestart, $timeend));
|
||||
$filled = false;
|
||||
$manager = get_log_manager();
|
||||
$stores = $manager->get_readers();
|
||||
foreach ($stores as $store) {
|
||||
if ($store instanceof \core\log\sql_internal_reader) {
|
||||
$logtable = $store->get_internal_log_table_name();
|
||||
if (!$logtable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sql = "SELECT COUNT('x')
|
||||
FROM {{$logtable}}
|
||||
WHERE timecreated >= :timestart AND timecreated < :timeend";
|
||||
|
||||
if (!$DB->get_field_sql($sql, $params)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Let's fake the old records using new log data.
|
||||
|
||||
$sql = "INSERT INTO {temp_log1} (userid, course, action)
|
||||
|
||||
SELECT userid,
|
||||
CASE
|
||||
WHEN courseid IS NULL THEN ".SITEID."
|
||||
WHEN courseid = 0 THEN ".SITEID."
|
||||
ELSE courseid
|
||||
END,
|
||||
CASE
|
||||
WHEN eventname = :loginevent THEN 'login'
|
||||
WHEN crud = 'r' THEN 'view'
|
||||
ELSE 'update'
|
||||
END
|
||||
FROM {{$logtable}}
|
||||
WHERE timecreated >= :timestart AND timecreated < :timeend";
|
||||
|
||||
$DB->execute($sql, $params);
|
||||
$filled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$filled) {
|
||||
// Fallback to legacy data.
|
||||
$sql = "INSERT INTO {temp_log1} (userid, course, action)
|
||||
|
||||
SELECT userid, course, action
|
||||
FROM {log}
|
||||
WHERE time >= :timestart AND time < :timeend";
|
||||
|
||||
$DB->execute($sql, $params);
|
||||
}
|
||||
|
||||
$sql = 'INSERT INTO {temp_log2} (userid, course, action)
|
||||
|
||||
@ -1751,7 +1822,7 @@ function stats_temp_table_fill($timestart, $timeend) {
|
||||
/**
|
||||
* Deletes summary logs table for stats calculation
|
||||
*
|
||||
* @return boolen success (true) or failure(false)
|
||||
* @return bool success (true) or failure(false)
|
||||
*/
|
||||
function stats_temp_table_clean() {
|
||||
global $DB;
|
||||
|
57
lib/tests/fixtures/stats_events.php
vendored
Normal file
57
lib/tests/fixtures/stats_events.php
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace core_tests\event;
|
||||
|
||||
/**
|
||||
* Fixtures for new stats testing.
|
||||
*
|
||||
* @package core
|
||||
* @category phpunit
|
||||
* @copyright 2014 Petr Skoda
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
class create_executed extends \core\event\base {
|
||||
protected function init() {
|
||||
$this->data['crud'] = 'c';
|
||||
$this->data['edulevel'] = self::LEVEL_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
class read_executed extends \core\event\base {
|
||||
protected function init() {
|
||||
$this->data['crud'] = 'r';
|
||||
$this->data['edulevel'] = self::LEVEL_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
class update_executed extends \core\event\base {
|
||||
protected function init() {
|
||||
$this->data['crud'] = 'u';
|
||||
$this->data['edulevel'] = self::LEVEL_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
class delete_executed extends \core\event\base {
|
||||
protected function init() {
|
||||
$this->data['crud'] = 'd';
|
||||
$this->data['edulevel'] = self::LEVEL_OTHER;
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ global $CFG;
|
||||
require_once($CFG->libdir . '/adminlib.php');
|
||||
require_once($CFG->libdir . '/statslib.php');
|
||||
require_once($CFG->libdir . '/cronlib.php');
|
||||
require_once(__DIR__ . '/fixtures/stats_events.php');
|
||||
|
||||
/**
|
||||
* Test functions that affect daily stats.
|
||||
@ -343,6 +344,43 @@ class core_statslib_testcase extends advanced_testcase {
|
||||
|
||||
$this->prepare_db($dataset[1], array('stats_daily'));
|
||||
$this->assertEquals($day + (24 * 3600), stats_get_start_from('daily'), 'Daily stats start time');
|
||||
|
||||
// New log stores.
|
||||
$this->preventResetByRollback();
|
||||
|
||||
$this->assertFileExists("$CFG->dirroot/$CFG->admin/tool/log/store/standard/version.php");
|
||||
set_config('enabled_stores', 'logstore_standard', 'tool_log');
|
||||
set_config('buffersize', 0, 'logstore_standard');
|
||||
set_config('logguests', 1, 'logstore_standard');
|
||||
get_log_manager(true);
|
||||
|
||||
$this->assertEquals(0, $DB->count_records('logstore_standard_log'));
|
||||
|
||||
$DB->delete_records('stats_daily');
|
||||
$CFG->statsfirstrun = 'all';
|
||||
$firstoldtime = $DB->get_field_sql('SELECT MIN(time) FROM {log}');
|
||||
|
||||
$this->assertEquals($firstoldtime, stats_get_start_from('daily'));
|
||||
|
||||
\core_tests\event\create_executed::create(array('context' => context_system::instance()))->trigger();
|
||||
\core_tests\event\read_executed::create(array('context' => context_system::instance()))->trigger();
|
||||
\core_tests\event\update_executed::create(array('context' => context_system::instance()))->trigger();
|
||||
\core_tests\event\delete_executed::create(array('context' => context_system::instance()))->trigger();
|
||||
|
||||
$logs = $DB->get_records('logstore_standard_log');
|
||||
$this->assertCount(4, $logs);
|
||||
|
||||
$firstnew = reset($logs);
|
||||
$this->assertGreaterThan($firstoldtime, $firstnew->timecreated);
|
||||
$DB->set_field('logstore_standard_log', 'timecreated', 10, array('id' => $firstnew->id));
|
||||
$this->assertEquals(10, stats_get_start_from('daily'));
|
||||
|
||||
$DB->set_field('logstore_standard_log', 'timecreated', $firstnew->timecreated, array('id' => $firstnew->id));
|
||||
$DB->delete_records('log');
|
||||
$this->assertEquals($firstnew->timecreated, stats_get_start_from('daily'));
|
||||
|
||||
set_config('enabled_stores', '', 'tool_log');
|
||||
get_log_manager(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -491,7 +529,7 @@ class core_statslib_testcase extends advanced_testcase {
|
||||
* @depends test_statslib_temp_table_create_and_drop
|
||||
*/
|
||||
public function test_statslib_temp_table_fill() {
|
||||
global $CFG, $DB;
|
||||
global $CFG, $DB, $USER;
|
||||
|
||||
$dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test09.xml");
|
||||
|
||||
@ -507,6 +545,80 @@ class core_statslib_testcase extends advanced_testcase {
|
||||
$this->assertEquals(1, $DB->count_records('temp_log2'));
|
||||
|
||||
stats_temp_table_drop();
|
||||
|
||||
// New log stores.
|
||||
$this->preventResetByRollback();
|
||||
stats_temp_table_create();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$context = context_course::instance($course->id);
|
||||
$fcontext = context_course::instance(SITEID);
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
$this->assertFileExists("$CFG->dirroot/$CFG->admin/tool/log/store/standard/version.php");
|
||||
set_config('enabled_stores', 'logstore_standard', 'tool_log');
|
||||
set_config('buffersize', 0, 'logstore_standard');
|
||||
set_config('logguests', 1, 'logstore_standard');
|
||||
get_log_manager(true);
|
||||
|
||||
$DB->delete_records('logstore_standard_log');
|
||||
|
||||
\core_tests\event\create_executed::create(array('context' => $fcontext, 'courseid' => SITEID))->trigger();
|
||||
\core_tests\event\read_executed::create(array('context' => $context, 'courseid' => $course->id))->trigger();
|
||||
\core_tests\event\update_executed::create(array('context' => context_system::instance()))->trigger();
|
||||
\core_tests\event\delete_executed::create(array('context' => context_system::instance()))->trigger();
|
||||
|
||||
\core\event\user_loggedin::create(
|
||||
array(
|
||||
'userid' => $USER->id,
|
||||
'objectid' => $USER->id,
|
||||
'other' => array('username' => $USER->username),
|
||||
)
|
||||
)->trigger();
|
||||
|
||||
$DB->set_field('logstore_standard_log', 'timecreated', 10);
|
||||
|
||||
$this->assertEquals(5, $DB->count_records('logstore_standard_log'));
|
||||
|
||||
\core_tests\event\delete_executed::create(array('context' => context_system::instance()))->trigger();
|
||||
\core_tests\event\delete_executed::create(array('context' => context_system::instance()))->trigger();
|
||||
|
||||
$this->assertEquals(7, $DB->count_records('logstore_standard_log'));
|
||||
|
||||
stats_temp_table_fill(9, 11);
|
||||
|
||||
$logs1 = $DB->get_records('temp_log1');
|
||||
$logs2 = $DB->get_records('temp_log2');
|
||||
$this->assertCount(5, $logs1);
|
||||
$this->assertCount(5, $logs2);
|
||||
// The order of records in the temp tables is not guaranteed...
|
||||
|
||||
$viewcount = 0;
|
||||
$updatecount = 0;
|
||||
$logincount = 0;
|
||||
foreach ($logs1 as $log) {
|
||||
if ($log->course == $course->id) {
|
||||
$this->assertEquals('view', $log->action);
|
||||
$viewcount++;
|
||||
} else {
|
||||
$this->assertTrue(in_array($log->action, array('update', 'login')));
|
||||
if ($log->action === 'update') {
|
||||
$updatecount++;
|
||||
} else {
|
||||
$logincount++;
|
||||
}
|
||||
$this->assertEquals(SITEID, $log->course);
|
||||
}
|
||||
$this->assertEquals($user->id, $log->userid);
|
||||
}
|
||||
$this->assertEquals(1, $viewcount);
|
||||
$this->assertEquals(3, $updatecount);
|
||||
$this->assertEquals(1, $logincount);
|
||||
|
||||
set_config('enabled_stores', '', 'tool_log');
|
||||
get_log_manager(true);
|
||||
stats_temp_table_drop();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user