ILIAS  trunk Revision v11.0_alpha-1744-gb0451eebef4
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
ilSessionStatistics Class Reference
+ Collaboration diagram for ilSessionStatistics:

Static Public Member Functions

static isActive ()
 Is session statistics active at all? More...
 
static createRawEntry (string $a_session_id, int $a_session_type, int $a_timestamp, int $a_user_id)
 Create raw data entry. More...
 
static closeRawEntry ($a_session_id, ?int $a_context=null, $a_expired_at=null)
 Close raw data entry. More...
 
static aggretateRaw (int $a_now)
 Aggregate raw session data (older than given time) More...
 
static aggregateRawHelper (int $a_begin, int $a_end)
 Aggregate statistics data for one slot. More...
 
static getNumberOfSessionsByType (int $a_from, int $a_to)
 Get session counters by type (opened, closed) More...
 
static getLastAggregation ()
 Get timestamp of last aggregation. More...
 

Static Protected Member Functions

static getCurrentSlot (int $a_now)
 Get next slot to aggregate. More...
 
static getNumberOfActiveRawSessions (int $a_time)
 Count number of active sessions at given time. More...
 
static getRawData (int $a_begin, int $a_end)
 Read raw data for timespan. More...
 
static createNewAggregationSlot (int $a_now)
 Create new slot (using table lock) More...
 
static deleteAggregatedRaw ($a_now)
 Remove already aggregated raw data. More...
 

Private Attributes

const SLOT_SIZE = 15
 

Detailed Description

Member Function Documentation

◆ aggregateRawHelper()

static ilSessionStatistics::aggregateRawHelper ( int  $a_begin,
int  $a_end 
)
static

Aggregate statistics data for one slot.

Definition at line 274 of file class.ilSessionStatistics.php.

References $DIC, $ilDB, $ilSetting, ilSession\SESSION_CLOSE_EXPIRE, ilSession\SESSION_CLOSE_LOGIN, and ilSession\SESSION_CLOSE_USER.

274  : void
275  {
276  global $DIC;
277 
278  $ilDB = $DIC['ilDB'];
279  $ilSetting = $DIC['ilSetting'];
280 
281  // "relevant" closing types
282  $separate_closed = array(ilSession::SESSION_CLOSE_USER,
285 
286  // gather/process data (build event timeline)
287  $closed_counter = $events = array();
288  $opened_counter = 0;
289  foreach (self::getRawData($a_begin, $a_end) as $item) {
290  // open/close counters are _not_ time related
291 
292  // we could filter for undefined/invalid closing contexts
293  // and ignore those items, but this would make any debugging
294  // close to impossible
295  // "closed_other" would have been a good idea...
296 
297  // session opened
298  if ($item["start_time"] >= $a_begin) {
299  $opened_counter++;
300  $events[$item["start_time"]][] = 1;
301  }
302  // session closed
303  if ($item["end_time"] && $item["end_time"] <= $a_end) {
304  if (in_array($item["end_context"], $separate_closed, true)) {
305  if (!isset($closed_counter[$item["end_context"]])) {
306  $closed_counter[$item["end_context"]] = 0;
307  }
308 
309  $closed_counter[$item["end_context"]]++;
310  } else {
311  $closed_counter[0] = ($closed_counter[0] ?? 0) + 1;
312  }
313  $events[$item["end_time"]][] = -1;
314  }
315  }
316 
317  // initialising active statistical values
318  $active_begin = self::getNumberOfActiveRawSessions($a_begin - 1);
319  $active_end = $active_min = $active_max = $active_avg = $active_begin;
320 
321  // parsing events / building avergages
322  if (count($events)) {
323  $last_update_avg = $a_begin - 1;
324  $slot_seconds = self::SLOT_SIZE * 60;
325  $active_avg = 0;
326 
327  // parse all open/closing events
328  ksort($events);
329  foreach ($events as $ts => $actions) {
330  // actions which occur in the same second are "merged"
331  foreach ($actions as $action) {
332  // max
333  if ($action > 0) {
334  $active_end++;
335  }
336  // min
337  else {
338  $active_end--;
339  }
340  }
341 
342  // max
343  if ($active_end > $active_max) {
344  $active_max = $active_end;
345  }
346 
347  // min
348  if ($active_end < $active_min) {
349  $active_min = $active_end;
350  }
351 
352  // avg
353  $diff = $ts - $last_update_avg;
354  $active_avg += $diff / $slot_seconds * $active_end;
355  $last_update_avg = $ts;
356  }
357 
358  // add up to end of slot if needed
359  if ($last_update_avg < $a_end) {
360  $diff = $a_end - $last_update_avg;
361  $active_avg += $diff / $slot_seconds * $active_end;
362  }
363 
364  $active_avg = round($active_avg);
365  }
366  unset($events);
367 
368  // save aggregated data
369  $fields = array(
370  "active_min" => array("integer", $active_min),
371  "active_max" => array("integer", $active_max),
372  "active_avg" => array("integer", $active_avg),
373  "active_end" => array("integer", $active_end),
374  "opened" => array("integer", $opened_counter),
375  "closed_manual" => array("integer", (int) ($closed_counter[ilSession::SESSION_CLOSE_USER] ?? 0)),
376  "closed_expire" => array("integer", (int) ($closed_counter[ilSession::SESSION_CLOSE_EXPIRE] ?? 0)),
377  "closed_login" => array("integer", (int) ($closed_counter[ilSession::SESSION_CLOSE_LOGIN] ?? 0)),
378  "closed_misc" => array("integer", (int) ($closed_counter[0] ?? 0)),
379  );
380  $ilDB->update(
381  "usr_session_stats",
382  $fields,
383  array("slot_begin" => array("integer", $a_begin),
384  "slot_end" => array("integer", $a_end))
385  );
386  }
const SESSION_CLOSE_LOGIN
const SESSION_CLOSE_EXPIRE
const SESSION_CLOSE_USER
global $DIC
Definition: shib_login.php:22
global $ilSetting
Definition: privfeed.php:31

◆ aggretateRaw()

static ilSessionStatistics::aggretateRaw ( int  $a_now)
static

Aggregate raw session data (older than given time)

Parameters
integer$a_now

Definition at line 254 of file class.ilSessionStatistics.php.

Referenced by ilSessionStatisticsGUI\adminSync(), ilSession\lookupExpireTime(), and ilAuthDestroyExpiredSessionsCron\run().

254  : void
255  {
256  if (!self::isActive()) {
257  return;
258  }
259 
260  $slot = self::createNewAggregationSlot($a_now);
261  while (is_array($slot)) {
262  self::aggregateRawHelper($slot[0], $slot[1]);
263  $slot = self::createNewAggregationSlot($a_now);
264  }
265 
266  // #12728
267  self::deleteAggregatedRaw($a_now);
268  }
+ Here is the caller graph for this function:

◆ closeRawEntry()

static ilSessionStatistics::closeRawEntry (   $a_session_id,
?int  $a_context = null,
  $a_expired_at = null 
)
static

Close raw data entry.

Parameters
int | array$a_session_id
int$a_context
int | bool$a_expired_at

Definition at line 76 of file class.ilSessionStatistics.php.

References $DIC, $id, and $ilDB.

Referenced by ilSession\_destroy().

76  : void
77  {
78  global $DIC;
79 
80  $ilDB = $DIC['ilDB'];
81 
82  if (!self::isActive()) {
83  return;
84  }
85 
86  // single entry
87  if (!is_array($a_session_id)) {
88  if ($a_expired_at) {
89  $end_time = $a_expired_at;
90  } else {
91  $end_time = time();
92  }
93  $sql = "UPDATE usr_session_stats_raw" .
94  " SET end_time = " . $ilDB->quote($end_time, "integer");
95  if ($a_context) {
96  $sql .= ",end_context = " . $ilDB->quote($a_context, "integer");
97  }
98  $sql .= " WHERE session_id = " . $ilDB->quote($a_session_id, "text") .
99  " AND end_time IS NULL";
100  $ilDB->manipulate($sql);
101  }
102  // batch closing
103  elseif (!$a_expired_at) {
104  $sql = "UPDATE usr_session_stats_raw" .
105  " SET end_time = " . $ilDB->quote(time(), "integer");
106  if ($a_context) {
107  $sql .= ",end_context = " . $ilDB->quote($a_context, "integer");
108  }
109  $sql .= " WHERE " . $ilDB->in("session_id", $a_session_id, false, "text") .
110  " AND end_time IS NULL";
111  $ilDB->manipulate($sql);
112  }
113  // batch with individual timestamps
114  else {
115  foreach ($a_session_id as $id => $ts) {
116  $sql = "UPDATE usr_session_stats_raw" .
117  " SET end_time = " . $ilDB->quote($ts, "integer");
118  if ($a_context) {
119  $sql .= ",end_context = " . $ilDB->quote($a_context, "integer");
120  }
121  $sql .= " WHERE session_id = " . $ilDB->quote($id, "text") .
122  " AND end_time IS NULL";
123  $ilDB->manipulate($sql);
124  }
125  }
126  }
global $DIC
Definition: shib_login.php:22
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
+ Here is the caller graph for this function:

◆ createNewAggregationSlot()

static ilSessionStatistics::createNewAggregationSlot ( int  $a_now)
staticprotected

Create new slot (using table lock)

Returns
array begin, end

Definition at line 219 of file class.ilSessionStatistics.php.

References $DIC, $ilDB, ilDBInterface\insert(), and null.

219  : ?array
220  {
221  global $DIC;
222 
223  $ilDB = $DIC['ilDB'];
224 
225  $ilAtomQuery = $ilDB->buildAtomQuery();
226  $ilAtomQuery->addTableLock("usr_session_stats");
227 
228  $ilAtomQuery->addQueryCallable(function (ilDBInterface $ilDB) use ($a_now, &$slot) {
229  // if we had to wait for the lock, no current slot should be returned here
230  $slot = self::getCurrentSlot($a_now);
231  if (!is_array($slot)) {
232  $slot = null;
233  return;
234  }
235 
236  // save slot to mark as taken
237  $fields = array(
238  "slot_begin" => array("integer", $slot[0]),
239  "slot_end" => array("integer", $slot[1]),
240  );
241  $ilDB->insert("usr_session_stats", $fields);
242  });
243 
244  $ilAtomQuery->run();
245 
246  return $slot;
247  }
insert(string $table_name, array $values)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
global $DIC
Definition: shib_login.php:22
+ Here is the call graph for this function:

◆ createRawEntry()

static ilSessionStatistics::createRawEntry ( string  $a_session_id,
int  $a_session_type,
int  $a_timestamp,
int  $a_user_id 
)
static

Create raw data entry.

Definition at line 43 of file class.ilSessionStatistics.php.

References $DIC, and $ilDB.

Referenced by ilSession\lookupExpireTime().

43  : void
44  {
45  global $DIC;
46 
47  $ilDB = $DIC['ilDB'];
48 
49  if (!$a_user_id || !$a_session_id || !self::isActive()) {
50  return;
51  }
52 
53  // #9669: if a session was destroyed and somehow the session id is still
54  // in use there will be a id-collision for the raw-entry
55 
56  $ilDB->replace(
57  "usr_session_stats_raw",
58  array(
59  "session_id" => array("text", $a_session_id)
60  ),
61  array(
62  "type" => array("integer", $a_session_type),
63  "start_time" => array("integer", $a_timestamp),
64  "user_id" => array("integer", $a_user_id)
65  )
66  );
67  }
global $DIC
Definition: shib_login.php:22
+ Here is the caller graph for this function:

◆ deleteAggregatedRaw()

static ilSessionStatistics::deleteAggregatedRaw (   $a_now)
staticprotected

Remove already aggregated raw data.

Parameters
integer$a_now

Definition at line 393 of file class.ilSessionStatistics.php.

References $DIC, and $ilDB.

393  : void
394  {
395  global $DIC;
396 
397  $ilDB = $DIC['ilDB'];
398 
399  // we are rather defensive here - 7 days BEFORE current aggregation
400  $cut = $a_now - (60 * 60 * 24 * 7);
401 
402  $ilDB->manipulate("DELETE FROM usr_session_stats_raw" .
403  " WHERE start_time <= " . $ilDB->quote($cut, "integer"));
404  }
global $DIC
Definition: shib_login.php:22

◆ getCurrentSlot()

static ilSessionStatistics::getCurrentSlot ( int  $a_now)
staticprotected

Get next slot to aggregate.

Returns
array begin, end

Definition at line 133 of file class.ilSessionStatistics.php.

References $DIC, $ilDB, $res, ILIAS\Repository\int(), and null.

133  : ?array
134  {
135  global $DIC;
136 
137  $ilDB = $DIC['ilDB'];
138 
139  // get latest slot in db
140  $sql = "SELECT MAX(slot_end) previous_slot_end" .
141  " FROM usr_session_stats";
142  $res = $ilDB->query($sql);
143  $row = $ilDB->fetchAssoc($res);
144  $previous_slot_end = $row["previous_slot_end"];
145 
146  // no previous slot? calculate last complete slot
147  // should we use minimum session raw date instead? (problem: table lock)
148  if (!$previous_slot_end) {
149  $slot = (int) (floor(date("i") / self::SLOT_SIZE));
150  // last slot of previous hour
151  if (!$slot) {
152  $current_slot_begin = mktime((int) date("H", $a_now) - 1, 60 - self::SLOT_SIZE, 0);
153  }
154  // "normalize" to slot
155  else {
156  $current_slot_begin = mktime((int) date("H", $a_now), ($slot - 1) * self::SLOT_SIZE, 0);
157  }
158  } else {
159  $current_slot_begin = $previous_slot_end + 1;
160  }
161 
162  $current_slot_end = $current_slot_begin + (60 * self::SLOT_SIZE) - 1;
163 
164  // no complete slot: nothing to do yet
165  if ($current_slot_end < $a_now) {
166  return array($current_slot_begin, $current_slot_end);
167  }
168  return null;
169  }
$res
Definition: ltiservices.php:66
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
global $DIC
Definition: shib_login.php:22
+ Here is the call graph for this function:

◆ getLastAggregation()

static ilSessionStatistics::getLastAggregation ( )
static

Get timestamp of last aggregation.

Definition at line 455 of file class.ilSessionStatistics.php.

References $DIC, $ilDB, $res, and null.

Referenced by ilSessionStatisticsGUI\renderCurrentBasics().

455  : ?int
456  {
457  global $DIC;
458 
459  $ilDB = $DIC['ilDB'];
460 
461  $sql = "SELECT max(slot_end) latest FROM usr_session_stats";
462  $res = $ilDB->query($sql);
463  $row = $ilDB->fetchAssoc($res);
464  if ($row["latest"]) {
465  return (int) $row["latest"];
466  }
467  //TODO check if return null as timestamp causes issues
468  return null;
469  }
$res
Definition: ltiservices.php:66
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
global $DIC
Definition: shib_login.php:22
+ Here is the caller graph for this function:

◆ getNumberOfActiveRawSessions()

static ilSessionStatistics::getNumberOfActiveRawSessions ( int  $a_time)
staticprotected

Count number of active sessions at given time.

Parameters
integer$a_time
Returns
integer

Definition at line 177 of file class.ilSessionStatistics.php.

References $DIC, $ilDB, $res, and ilSessionControl\$session_types_controlled.

177  : int
178  {
179  global $DIC;
180 
181  $ilDB = $DIC['ilDB'];
182 
183  $sql = "SELECT COUNT(*) counter FROM usr_session_stats_raw" .
184  " WHERE (end_time IS NULL OR end_time >= " . $ilDB->quote($a_time, "integer") . ")" .
185  " AND start_time <= " . $ilDB->quote($a_time, "integer") .
186  " AND " . $ilDB->in("type", ilSessionControl::$session_types_controlled, false, "integer");
187  $res = $ilDB->query($sql);
188  $row = $ilDB->fetchAssoc($res);
189  return (int) $row["counter"];
190  }
$res
Definition: ltiservices.php:66
global $DIC
Definition: shib_login.php:22
static array $session_types_controlled

◆ getNumberOfSessionsByType()

static ilSessionStatistics::getNumberOfSessionsByType ( int  $a_from,
int  $a_to 
)
static

Get session counters by type (opened, closed)

Definition at line 409 of file class.ilSessionStatistics.php.

References $DIC, $ilDB, $res, and ILIAS\Repository\int().

Referenced by ilSessionStatisticsGUI\buildData().

409  : array
410  {
411  global $DIC;
412 
413  $ilDB = $DIC['ilDB'];
414 
415  $sql = "SELECT SUM(opened) opened, SUM(closed_manual) closed_manual," .
416  " SUM(closed_expire) closed_expire," .
417  " SUM(closed_login) closed_login, SUM(closed_misc) closed_misc" .
418  " FROM usr_session_stats" .
419  " WHERE slot_end > " . $ilDB->quote($a_from, "integer") .
420  " AND slot_begin < " . $ilDB->quote($a_to, "integer");
421  $res = $ilDB->query($sql);
422  return $ilDB->fetchAssoc($res);
423  }
$res
Definition: ltiservices.php:66
global $DIC
Definition: shib_login.php:22
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRawData()

static ilSessionStatistics::getRawData ( int  $a_begin,
int  $a_end 
)
staticprotected

Read raw data for timespan.

Definition at line 195 of file class.ilSessionStatistics.php.

References $DIC, $ilDB, $res, and ilSessionControl\$session_types_controlled.

195  : array
196  {
197  global $DIC;
198 
199  $ilDB = $DIC['ilDB'];
200 
201  $sql = "SELECT start_time,end_time,end_context FROM usr_session_stats_raw" .
202  " WHERE start_time <= " . $ilDB->quote($a_end, "integer") .
203  " AND (end_time IS NULL OR end_time >= " . $ilDB->quote($a_begin, "integer") . ")" .
204  " AND " . $ilDB->in("type", ilSessionControl::$session_types_controlled, false, "integer") .
205  " ORDER BY start_time";
206  $res = $ilDB->query($sql);
207  $all = array();
208  while ($row = $ilDB->fetchAssoc($res)) {
209  $all[] = $row;
210  }
211  return $all;
212  }
$res
Definition: ltiservices.php:66
global $DIC
Definition: shib_login.php:22
static array $session_types_controlled

◆ isActive()

static ilSessionStatistics::isActive ( )
static

Is session statistics active at all?

Definition at line 31 of file class.ilSessionStatistics.php.

References $DIC, and $ilSetting.

31  : bool
32  {
33  global $DIC;
34 
35  $ilSetting = $DIC['ilSetting'];
36 
37  return (bool) $ilSetting->get('session_statistics', "1");
38  }
global $DIC
Definition: shib_login.php:22
global $ilSetting
Definition: privfeed.php:31

Field Documentation

◆ SLOT_SIZE

const ilSessionStatistics::SLOT_SIZE = 15
private

Definition at line 26 of file class.ilSessionStatistics.php.


The documentation for this class was generated from the following file: