Skip to content
Snippets Groups Projects
Select Git revision
  • a7bb1164b5f6a6e752f69665e2ec342d7aa4df7a
  • master default protected
  • simple-task/7248-eol-check-add-node-22
  • 6877_check_iml_deployment
4 results

check_ceph_osd

Blame
  • actionlog.class.php 15.01 KiB
    <?php
    require_once 'user.class.php';
    
    /**
     * class to log all project actions, ie. build, deploy etc.
     *
     * @author hahn
     */
    class Actionlog
    {
    
        private $_dbfile = '';
        private $_aLoglevels = array("info", "warning", "error", "success"); // array of valid loglevels
        private $_sIP = false;
        private $_sUser = false;
        private $_sProject = false;
        private $_sCreate = '
            CREATE TABLE "logs" (
              `id` INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE ,
              `time` DATETIME,
              `loglevel` TEXT,
              `ip` TEXT,
              `user` TEXT,
              `project` TEXT,
              `action` TEXT,
              `message` TEXT
            )';
        /*
        private $_sCreateFUTURE = '
            CREATE TABLE "logs" (
              `id` INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE ,
              `time` DATETIME,
              `time-start` DATETIME,
              `loglevel` TEXT,
              `ip` TEXT,
              `user` TEXT,
              `project` TEXT,
              `action` TEXT,
              `message` TEXT
            )';
            */
        /**
         * constructor - sets internal environment variables and checks existence 
         * of the database
         * @global array $aConfig    settings
         * @param  string $sProject  project ID
         */
        public function __construct($sProject = false)
        {
            global $aConfig;
            if (!isset($aConfig["appRootDir"])) {
                die(__CLASS__ . "::" . __FUNCTION__ . " ERROR: configuration with \$aConfig was not loaded.");
            }
            $this->_dbfile = $aConfig['dataDir'] . '/database/logs.db';
            if (!file_exists($this->_dbfile)) {
                $this->_createDb();
                if (!file_exists($this->_dbfile)) {
                    die("ERROR: unable to create sqlite database " . $this->_dbfile);
                }
            }
            $this->_sProject = $sProject;
            $oUser = new user();
            if ($oUser->getUsername()) {
                $this->_sIP = isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : 'local';
                $this->_sUser = $oUser->getUsername() . " (web)";
            } else {
                $this->_sIP = 'local';
                $aUser = posix_getpwuid(posix_geteuid());
                $this->_sUser = $aUser['name'] . " (system)";
            }
        }
    
        /**
         * create sqlite database - called in constructor if the file does not exist
         */
        private function _createDb()
        {
            echo "try to create file $this->_dbfile ...<br>\n";
            return $this->_makeQuery($this->_sCreate);
        }
    
        /**
         * execute a sql statement
         * @param string $sSql sql statement
         * @return database object
         */
        private function _makeQuery($sSql)
        {
            // $this->_log(__FUNCTION__."($sSql)");
            // echo "<pre>".htmlentities($sSql)."</pre>";
            $db = new PDO("sqlite:" . $this->_dbfile);
            $result = $db->query($sSql);
            /*
            if(!$result){
                echo "PDO ERROR " . print_r($db->errorInfo(), 1) ."<br>";
            }
             */
            $db = NULL;
            return $result;
        }
    
        /**
         * add a log message
         * @param string $sMessage   message
         * @param string $sAction    project action; i.e. build, deploy, ...
         * @param string $sLoglevel  loglevel
         * @return type
         */
        public function add($sMessage, $sAction = "", $sLoglevel = "info", $sTimeStart = false)
        {
            if (array_search($sLoglevel, $this->_aLoglevels) === false) {
                die(__class__ . ": loglevel $sLoglevel is invalid");
            }
            $sql = "INSERT INTO `logs` (`time`, `loglevel`, `ip`, `user`, `project` ,`action`, `message`)
              VALUES(
                '" . date("Y-m-d H:i:s") . "',
                '" . $sLoglevel . "',
                '" . $this->_sIP . "',
                '" . $this->_sUser . "',
                '" . $this->_sProject . "',
                '" . $sAction . "',
                '" . str_replace("'", '"', $sMessage) . "'
              );
            ";
            /*
            $sqlFUTURE = "INSERT INTO `logs` (`time`, ".($sTimeStart ? "`time-start`, " : "" )." `loglevel`, `ip`, `user`, `project` ,`action`, `message`)
              VALUES(
                '" . date("Y-m-d H:i:s") . "',
                ".($sTimeStart ? "'" . $sTimeStart . "', " : "" ) ."
                '" . $sLoglevel . "',
                '" . $this->_sIP . "',
                '" . $this->_sUser . "',
                '" . $this->_sProject . "',
                '" . $sAction . "',
                '" . $sMessage . "'
              );
            ";
             * 
             */
            // echo $sql . "<br>";
            $oResult = $this->_makeQuery($sql);
            return $oResult;
        }
    
        /**
         * helper function to remove chars in a string
         * @param string  $sVal      user value
         * @param string  $sOKChars  good chars to keep
         * @return string
         */
        private function _filterAllowedChars($sVal, $sOKChars)
        {
            return preg_replace('/[^' . $sOKChars . ']/i', '', $sVal);
        }
    
        /**
         * get log data
         * @param array $aFilter with the following keys:
         *   'project' - filter by project; will be mixed with where (see next key)
         *   'from   ' - time greater equal; time as string i.e. "2020-06-24" or "2020-06-24 11:00:00"
         *   'to'      - max time (see from)
         *   'order'   - order clausel - part behind "ORDER BY "; default is "id DESC" (order by newest entries)
         *   'limit'   - limit clausel - part behind "LIMIT "
         * @return array
         */
        public function getLogs($aFilter = array())
        {
            // var_dump(R::findAll( 'log' ));
            $aReturn = array();
    
            $sSql = 'SELECT `id`,`time`,`loglevel`,`ip`,`user`,`project`,`action`,`message`  from logs ';
            $sWhere = false;
    
            $aWhere = array();
            if (isset($aFilter["project"]) && $aFilter["project"]) {
                $aWhere[] = '`project`="' . $this->_filterAllowedChars($aFilter["project"], '[a-z0-9\-\_]') . '"';
            }
            if (isset($aFilter["from"]) && $aFilter["from"]) {
                $aWhere[] = '`time`>="' . $this->_filterAllowedChars($aFilter["from"], '[0-9\-\ \:]') . '"';
            }
            if (isset($aFilter["to"]) && $aFilter["to"]) {
                $aWhere[] = '`time`<="' . $this->_filterAllowedChars($aFilter["to"], '[0-9\-\ \:]') . '"';
            }
    
            $sSql .= (count($aWhere) ? 'WHERE ' . implode(' AND ', $aWhere) : '');
    
            if (isset($aFilter["order"]) && $aFilter["order"]) {
                $sSql .= ' ORDER BY ' . $this->_filterAllowedChars($aFilter["order"], '[a-z\`0-9\,\ ]');
            } else {
                $sSql .= ' ORDER BY id DESC ';
            }
            if (isset($aFilter["limit"]) && $aFilter["limit"]) {
                $sSql .= ' LIMIT ' . $this->_filterAllowedChars($aFilter["limit"], '[0-9\,\ ]');
            }
    
            foreach ($this->_makeQuery($sSql) as $row) {
                for ($i = 0; $i <= 7; $i++) {
                    unset($row[$i]);
                }
                $aReturn[] = $row;
            }
            return $aReturn;
        }
    
        /**
         * render html code for a table with logs. The filter will be sent to
         * getLogs method.
         * @param array $aFilter with the following keys:
         *   'project' - filter by project; will be mixed with where (see next key)
         *   'limit' - limit clausel - part behind "LIMIT "
         * @return string
         */
        public function renderLogs($aFilter = array(), $bIsFullsearch = false)
        {
            $sReturn = '';
    
            static $bWasShown;
            if ($bWasShown)
                return " ";
    
            $bWasShown = true;
            require_once 'formgen.class.php';
    
            // values for dropdowns - limit of lines; time
    
            $aLimits = array(
                '20' => array('label' => 20),
                '50' => array('label' => 50),
                '100' => array('label' => 100),
                '' => array('label' => t("all")),
            );
            $aTimes = array(
                date("Y-m-d", date("U"))                => array('label' => t("class-actionlog-time-today")),
                date("Y-m-d", date("U") - 60 * 60 * 24 * 1)   => array('label' => t("class-actionlog-time-since-yesterday")),
                date("Y-m-d", date("U") - 60 * 60 * 24 * 7)   => array('label' => t("class-actionlog-time-for-1-week")),
                date("Y-m-d", date("U") - 60 * 60 * 24 * 7 * 2) => array('label' => sprintf(t("class-actionlog-time-for-n-weeks"), "2")),
                date("Y-m-d", date("U") - 60 * 60 * 24 * 7 * 4) => array('label' => sprintf(t("class-actionlog-time-for-n-weeks"), "4")),
                '' => array('label' => t("all")),
            );
    
            $aForms = array(
                'filter' => array(
                    'meta' => array(
                        'method' => 'GET',
                        'action' => '?',
                        'class' => 'form-inline',
                    ),
                    'validate' => array(),
                    'form' => array(),
                )
            );
    
            // generate filter for log table
            // $bIsFullsearch: true = show all inputs; false: no interactive search
    
            if ($bIsFullsearch) {
    
                // --- list of all projects in log
                $sSql = 'SELECT DISTINCT(project) from `logs` order by project asc';
                $aForms["filter"]["form"]['selectproject'] = array(
                    'type' => 'select',
                    'name' => 'selectproject',
                    'label' => '<i class="glyphicon glyphicon-tag"></i> ' . t('project'),
                    'class' => 'span2',
                    'onchange' => 'updateActionlog();',
                    'inline' => true,
                );
                $aForms["filter"]["form"]['selectproject']['options'][''] = array('label' => t("all"));
                foreach ($this->_makeQuery($sSql) as $row) {
                    if ($row[0]) {
                        $aForms["filter"]["form"]['selectproject']['options'][$row[0]] = array('label' => $row[0]);
                    }
                }
                $aForms["filter"]["form"]['selectfrom'] = array(
                    'type' => 'select',
                    'name' => 'selectWheretime',
                    'label' => '<i class="glyphicon glyphicon-calendar"></i> ' . t("class-actionlog-time"),
                    'class' => 'span2',
                    'onchange' => 'updateActionlog();',
                    'options' => $aTimes,
                    'inline' => true,
                );
                $aForms["filter"]["form"]['selectlimit'] = array(
                    'type' => 'select',
                    'name' => 'selectlimit',
                    'label' => '<i class="glyphicon glyphicon-list"></i> ' . t("class-actionlog-count"),
                    'class' => 'span1',
                    'onchange' => 'updateActionlog();',
                    'options' => $aLimits,
                    'inline' => true,
                );
    
                // force a line break
                $aForms["filter"]["form"]['line'] = array(
                    'type' => 'markup',
                    'value' => '<div class="col-sm-12"></div>',
                );
            } else {
    
                // write filters as hidden fields
                if (isset($aFilter["project"])) {
                    $aForms["filter"]["form"]['selectproject'] = array(
                        'type' => 'hidden',
                        'value' => $aFilter["project"]
                    );
                }
                if (isset($aFilter["limit"])) {
                    $aForms["filter"]["form"]['selectlimit'] = array(
                        'type' => 'hidden',
                        'value' => $aFilter["limit"]
                    );
                }
            }
            $aForms["filter"]["form"]['efilterlogs'] = array(
                'type' => 'text',
                'name' => 'efilterlogs',
                'label' => '<i class="glyphicon glyphicon-filter"></i>' . t("overview-textsearch"),
                'inline' => true,
                'onkeyup' => 'filterLogTable();',
                'onkeypress' => 'filterLogTable();',
                'onchange' => 'filterLogTable();',
                //'size' => 20,
            );
            if (!$bIsFullsearch) {
                $aForms["filter"]["form"]['btnalllogs'] = array(
                    'type' => 'button',
                    'value' => t('show all'),
                    'class' => 'btn btn-secondary btnlogs',
                    'href' => '/deployment/all/setup/actionlog/',
                    'onclick' => 'location.href=\'/deployment/all/setup/actionlog/\'; return false;',
                );
            } else {
                // $aForms["filter"]["form"]['closediv'] = array(
                //     'type' => 'markup',
                //     'value' => '</div><!-- closediv -->',
                // );
    
            }
    
            // generate html output
    
            $oForm = new formgen($aForms);
    
            $sReturn = ''
                . ($bIsFullsearch ? t("class-actionlog-title") . ' :: ' . t("class-actionlog-filter") : '')
                . '<div id="divActionlogs">' . $oForm->renderHtml("filter") . '
                    <div style="clear: both; margin-bottom: 1em;"></div>
                    <div id="tableLogactions"></div>
                        <!--
                        <script src="/vendor/vis/4.21.0/vis.min.js"></script>
                        <link href="/vendor/vis/4.21.0/vis.min.css" rel="stylesheet" type="text/css" />
                        <div id="divTimeline"></div>
                        -->
                    </div>
                    <script>
                        var sMsgNolog="' . t("class-actionlog-nolog") . '";
                    </script>';
    
            if ($bIsFullsearch) {
                $sReturn .= '<script>
                            $(document).ready(function() {
                                updateActionlog();
                            });</script>';
            } else {
    
                $sReturn = '<strong>'
                    . '<button onclick="setLogVisibility(\'block\');"  id="btnShowLogs" class="btn btn-default btnLogs"><i class="fa-solid fa-chevron-right"></i> </button>'
                    . '<button onclick="setLogVisibility(\'none\');"   id="btnHideLogs" class="btn btn-default btnLogs"><i class="fa-solid fa-chevron-down"></i> </button>'
                    . ' &nbsp; ' . t("class-actionlog-title") . (isset($aFilter["project"]) ? ' [' . $aFilter["project"] . '] ' : '')
                    . '</strong>'
    
                    . $sReturn . '
                    <script>
                    function getLogVisibility(){
                        var sReturn=localStorage.getItem("bActionlogsVisible");
                        sReturn=(sReturn=="block")?"block":"none";
                        return sReturn;
                    }
    
                    function setLogVisibility(sVisibility){
                        localStorage.setItem("bActionlogsVisible", sVisibility);
                        $("#divActionlogs").css("display", sVisibility);
                        $(".btnLogs").css("display", "none");
                        if (sVisibility=="block"){
                            $("#btnHideLogs").css("display", "inline");
                            $(document).ready(function() {
                                updateActionlog();
                            });
                        } else {
                            $("#btnShowLogs").css("display", "inline");
                        }
                    }
                    setLogVisibility(getLogVisibility());
                    </script>';
            }
            return $sReturn;
        }
    }