From bfffe38447192c5b743ef8db0c8a3587f95e7574 Mon Sep 17 00:00:00 2001
From: "Hahn Axel (hahn)" <axel.hahn@unibe.ch>
Date: Tue, 1 Oct 2024 09:48:50 +0200
Subject: [PATCH] limit history table to 1000 newest entries

---
 classes/cronlog-renderer.class.php | 23 ++++++++++++++++++++++-
 classes/cronlog.class.php          | 27 +++++++++++++++++++++++----
 config/lang_de-de.php              |  2 +-
 config/lang_en-en.php              |  2 +-
 4 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/classes/cronlog-renderer.class.php b/classes/cronlog-renderer.class.php
index 791490b..3ad83f5 100644
--- a/classes/cronlog-renderer.class.php
+++ b/classes/cronlog-renderer.class.php
@@ -44,6 +44,13 @@ class cronlogrenderer extends cronlog
      */
     protected int $_iMinTime4Timeline = 60;
 
+    /**
+     * Max count of entries in history table to prevent freezing of the screen
+     * when displaying a lot of entries, eg all logs of 100+ servers
+     * @var int
+     */
+    protected int $_iHistoryLimit = 1000;
+
     /**
      * Show date of last data and last access; used in rendering methods to display it on top
      * @param integer $iLast  unix timestamp of last log entry
@@ -55,9 +62,10 @@ class cronlogrenderer extends cronlog
             return '';
         }
         $iAge = round((date('U') - $iLast) / 60);
+        $sAge = ($iAge > 60*24 ? '<span class="message-error">'.$iAge.'</span>' : $iAge);
         return '<div class="accessandage">'
             . sprintf($this->t("request-time"), date("Y-m-d H:i:s")) . '<br>'
-            . sprintf($this->t("last-entry"), $iAge)
+            . sprintf($this->t("last-entry"), $sAge)
             . '</div>'
         ;
     }
@@ -365,12 +373,25 @@ class cronlogrenderer extends cronlog
             $aData = $this->getServerJobHistory();
         }
 
+        // sort by starting time - especially before cutting the list
+        $aTmp=[];
+        foreach($aData as $sKey => $aEntry) {
+            $aTmp[$aEntry['start'].'__'.$aEntry['host'].'__'.$aEntry['job']]=$aEntry;
+        }
+        krsort($aTmp);
+        $aData = array_values($aTmp);
+
         $sTblHead = '';
         $iOK = 0;
         $iErrors = 0;
         $iLast = false;
+        $iCounter = 0;
         // job=dok-kvm-instances:host=kalium:start=1538358001:end=1538358001:exectime=0:ttl=60:rc=0
         foreach ($aData as $aEntry) {
+            $iCounter++;
+            if($iCounter>$this->_iHistoryLimit) {
+                break;
+            }
             if (!$sTblHead) {
                 foreach ([
                     $this->t("col-starting-time"), 
diff --git a/classes/cronlog.class.php b/classes/cronlog.class.php
index e3c596d..bdfd415 100644
--- a/classes/cronlog.class.php
+++ b/classes/cronlog.class.php
@@ -39,15 +39,34 @@ class cronlog
 {
 
 
+    /**
+     * Data dir with subdirs per host and its cronjob logs
+     * @var string
+     */
     protected string $_sDataDir = "__APPDIR__/data";
+
+    /**
+     * TTL for cached data
+     * @var int
+     */
     protected int $_iTtlCache = 60; // in sec
 
     /**
-     * when show an error for expired jobs (latency to execute job and sync logs)
+     * When show an error for expired jobs (keep in mind the latency to execute job and sync logs)
      * @var integer
      */
     protected int $_iExpiredJobsFailAfter = 60 * 30; // in sec
+
+    /**
+     * Minimal TTL for a cronjob
+     * @var int
+     */
     protected int $_iMinTtl = 0; // in sec
+
+    /**
+     * List of cronjobs to hide in the web view
+     * @var array
+     */
     protected array $_aSkipJoblogs = [];
 
     protected array $_aInstances = [];
@@ -131,9 +150,9 @@ class cronlog
     /**
      * Caching: get cached data if they exist and aren't expired
      * @param  string  $sTaskId  Name of the task
-     * @return mixed boolean|array
+     * @return mixed string|array
      */
-    protected function _getCacheData(string $sTaskId): string
+    protected function _getCacheData(string $sTaskId): string|array
     {
         // DISABLE CACHE return false;
         $sFile = $this->_getCacheFile($sTaskId);
@@ -292,7 +311,7 @@ class cronlog
                 // send the current file part to the browser
                 $aData = $this->_parseJoblogLine($line);
                 if (!$bUseSkip || array_search($aData['job'], $this->_aSkipJoblogs) === false) {
-                    $aReturn[$aData['start']] = $aData;
+                    $aReturn[$aData['start'].'__'.$aData['host'].'__'.$aData['job']] = $aData;
                 }
             }
             fclose($fileHandle);
diff --git a/config/lang_de-de.php b/config/lang_de-de.php
index 70ddac6..ebb1aa8 100644
--- a/config/lang_de-de.php
+++ b/config/lang_de-de.php
@@ -26,7 +26,7 @@ return [
 
     "history"           => "History",
     "history-head"      => "History",
-    "history-hint"      => "Von den gestarteten Cronjobs werden die Ausf&uuml;hrungszeiten und deren Exitcode f&uuml;r 6 Tage aufgehoben.",
+    "history-hint"      => "Von den gestarteten Cronjobs werden die Ausf&uuml;hrungszeiten und deren Exitcode f&uuml;r mehrere Tage aufgehoben.",
 
     "timeline"          => "Timeline",
     "timeline-head"     => "Graph mit Timeline",
diff --git a/config/lang_en-en.php b/config/lang_en-en.php
index 305b112..abfaabf 100644
--- a/config/lang_en-en.php
+++ b/config/lang_en-en.php
@@ -26,7 +26,7 @@ return [
 
     "history"           => "History",
     "history-head"      => "History",
-    "history-hint"      => "The cronwrapper keeps data for 6 days. For each executed cronjob you can see execution times and exitcode.",
+    "history-hint"      => "The cronwrapper keeps execution history data for multiples days. For each executed cronjob you can see execution times and exitcode.",
 
     "timeline"          => "Timeline",
     "timeline-head"     => "Graph with timeline",
-- 
GitLab