Skip to content

Commit 8bb2ed5

Browse files
duyhuynhdevdustinhuynh
andauthored
New metric for 12 months rolling active users - Back fill function #180 (#184)
Co-authored-by: dustinhuynh <dustinhuynh@catalyst-au.net>
1 parent 4cd9f3b commit 8bb2ed5

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

classes/metric/yearly_active_users_metric.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
namespace tool_cloudmetrics\metric;
1818

19+
use progress_bar;
20+
use tool_cloudmetrics\lib;
21+
1922
/**
2023
* Metric class for 12 months yearly active users.
2124
*
@@ -26,6 +29,19 @@
2629
*/
2730
class yearly_active_users_metric extends builtin_user_base {
2831

32+
33+
/** @var int The interval config for which data is displayed in seconds (eg: 5 minutes = 300). */
34+
public $interval;
35+
36+
/** @var int The minimal timestamp representing earliest date retrieved in DB. */
37+
public $mintimestamp;
38+
39+
/** @var int The maximal timestamp representing latest date retrieved in DB. */
40+
public $maxtimestamp;
41+
42+
/** @var bool True if config used is same as one requested. */
43+
public $sameconfig;
44+
2945
/**
3046
* The metric's name.
3147
*
@@ -72,6 +88,15 @@ public function set_frequency(int $freq) {
7288
// Do nothing.
7389
}
7490

91+
/**
92+
* Metric's ability to be backfilled.
93+
*
94+
* @return bool
95+
*/
96+
public function is_backfillable(): bool {
97+
return true;
98+
}
99+
75100
/**
76101
* Generates the metric items from the source data.
77102
*
@@ -91,4 +116,91 @@ public function generate_metric_item(int $starttime, int $finishtime): metric_it
91116
);
92117
return new metric_item($this->get_name(), $finishtime, $users, $this);
93118
}
119+
120+
/**
121+
* Returns records for backfilled metric.
122+
*
123+
* @param int $backwardperiod Time from which sample is to be retrieved.
124+
* @param int|null $finishtime If data is being completed argument is passed here.
125+
* @param progress_bar|null $progress
126+
*
127+
* @return array
128+
*/
129+
public function generate_metric_items(int $backwardperiod, ?int $finishtime = null, ?progress_bar $progress = null): array {
130+
global $DB;
131+
$metricitems = [];
132+
$finishtime = ($finishtime === -1) ? null : $finishtime;
133+
$finishtime = $finishtime ?? time();
134+
$starttime = $finishtime - $backwardperiod;
135+
// Back to last year from start time.
136+
$lastyear = $starttime - YEARSECS;
137+
// Get aggregation interval.
138+
$frequency = $this->get_frequency();
139+
$interval = lib::FREQ_TIMES[$frequency];
140+
if ($finishtime < $starttime) {
141+
return [];
142+
}
143+
$sql = 'SELECT floor(timecreated / :interval ) * :intervaldup AS timestamp,
144+
userid
145+
FROM {logstore_standard_log}
146+
WHERE timecreated >= :lastyear
147+
AND timecreated <= :finishtime
148+
GROUP BY timestamp, userid
149+
ORDER BY timestamp DESC';
150+
$results = $DB->get_recordset_sql(
151+
$sql,
152+
['interval' => $interval, 'intervaldup' => $interval, 'lastyear' => $lastyear, 'finishtime' => $finishtime]
153+
);
154+
$buffer = [];
155+
156+
foreach ($results as $record) {
157+
$buffer[] = $record;
158+
}
159+
$results->close();
160+
161+
// Variables for updating progress.
162+
$count = 0;
163+
$total = ($finishtime - $starttime) / $interval;
164+
// Build a metric for each day from starttime to finishtime.
165+
while ($starttime <= $finishtime) {
166+
$distinctusers = [];
167+
$lastyear = $starttime - YEARSECS;
168+
foreach ($buffer as $r) {
169+
// Count active users in a 12 months period.
170+
if ($r->timestamp >= $lastyear &&
171+
$r->timestamp <= $starttime &&
172+
!array_key_exists($r->userid, $distinctusers)) {
173+
$distinctusers[$r->userid] = true;
174+
}
175+
}
176+
$metricitems[] = new metric_item($this->get_name(), $starttime, count($distinctusers), $this);
177+
$starttime = $starttime + $interval;
178+
$count++;
179+
if ($progress) {
180+
$progress->update(
181+
$count,
182+
$total,
183+
get_string('backfillgenerating', 'tool_cloudmetrics', $this->get_label())
184+
);
185+
}
186+
}
187+
$this->mintimestamp = !empty($metricitems) ? $metricitems[0]->time : null;
188+
$this->maxtimestamp = !empty($metricitems) ? end($metricitems)->time : null;
189+
$this->interval = $frequency;
190+
return $metricitems;
191+
}
192+
193+
/**
194+
* Stores what data has been sent to collector.
195+
*
196+
*/
197+
public function set_data_sent_config(): void {
198+
// Store what data has been sent min, max timestamp range and interval.
199+
$currentconfig = [$this->mintimestamp, $this->maxtimestamp, $this->interval];
200+
$rangeretrieved = $this->get_range_retrieved();
201+
$this->sameconfig = ($rangeretrieved === $currentconfig);
202+
if (!$this->sameconfig && isset($this->mintimestamp) && isset($this->maxtimestamp) && isset($this->interval)) {
203+
$this->set_range_retrieved($currentconfig);
204+
}
205+
}
94206
}

0 commit comments

Comments
 (0)