<?php
function base_dayclean($systemrow) {
    global $db;
    $msg = '';

    $execute = $db->execute('delete from zc_autotsk_run where addtimes<' . (time() - 86400 * 30));
    if ($execute === false)
        $msg .= 'clean zc_autotsk_run: ' . $db->error . '<br/>';
    else if ($execute > 0)
        $msg .= 'clean zc_autotsk_run: ' . $execute . '<br/>';
    $execute = $db->execute('delete from zc_autotsk_run where msg=\'\' and addtimes<' . (time() - 86400 * 3));
    if ($execute === false)
        $msg .= 'clean zc_autotsk_run B: ' . $db->error . '<br/>';
    $execute = $db->execute('delete from ap_usr_capcode where exptimes<' . time());
    if ($execute === false)
        $msg .= 'clean ap_usr_capcode: ' . $db->error . '<br/>';
    else if ($execute > 0)
        $msg .= 'clean ap_usr_capcode: ' . $execute . '<br/>';
    $cnt = 0;
    $errcnt = 0;
    $files = scandir(PATH_WEB . 'ud/tmp/');
    foreach ($files as $file) {
        if ($file[0] == '.')
            continue;
        $mtime = filemtime(PATH_WEB . 'ud/tmp/' . $file);
        if ($mtime === false)
            continue;
        if (tostamp() - $mtime > 86400 * 3) {
            $ret = _base_delall(PATH_WEB . 'ud/tmp/' . $file);
            $cnt++;
            if ($ret !== true) {
                $errcnt++;
                savelog($db, 0, 'CRON', '清理tmp文件失败【' . PATH_WEB . 'ud/tmp/' . $file . '】' . $ret);
            }
        }
    }
    if ($cnt > 0 || $errcnt > 0)
        $msg .= 'clean file: ' . $cnt . ($errcnt > 0 ? ', err: ' . $errcnt : '') . '<br/>';
    return $msg;
}
function base_srvstats($systemrow) {
    global $db;
    $func_succ = 0;
    $func_fail = 0;
    $func_commit = 0;
    $func_rollback = 0;
    $func_runms = 0;
    $csql = new \ciy\sql('zc_zmem_var');
    $memrows = $db->get($csql);
    foreach ($memrows as $memrow) {
        if ($memrow['types'] == 'func_succ')
            $func_succ = (int)$memrow['params'];
        else if ($memrow['types'] == 'func_fail')
            $func_fail = (int)$memrow['params'];
        else if ($memrow['types'] == 'func_commit')
            $func_commit = (int)$memrow['params'];
        else if ($memrow['types'] == 'func_rollback')
            $func_rollback = (int)$memrow['params'];
        else if ($memrow['types'] == 'func_runms') {
            $func_runms = (int)$memrow['params'];
        } else
            continue;
        $updata = array();
        $updata['params'] = 0;
        $csql = new \ciy\sql('zc_zmem_var');
        $csql->where('id', $memrow['id']);
        $db->update($csql, $updata);
    }
    $func_runms = 0;
    if ($func_succ + $func_fail > 0)
        $func_runms = $func_runms / ($func_succ + $func_fail);

    $disk_sysfree = disk_free_space("/");
    $disk_datafree = disk_free_space("/data");
    // $disk_sysfree = disk_free_space("D:/");
    // $disk_datafree = disk_free_space("E:/");
    $starttime = timems();
    $fcontent = str_repeat("0", 1024 * 1024); //写入1MB
    $fpath = PATH_WEB . "/ud/_" . tostamp() . ".bin";
    file_put_contents($fpath, $fcontent);
    $rcontent = file_get_contents($fpath);
    unlink($fpath);
    $disk_ioms = timems() - $starttime;
    if ($rcontent !== $fcontent) {
        savelog($db, 0, 'STAT', '写入临时文件校验失败');
    }

    $output = array();
    exec("ps aux -A", $output);
    // $output = array();
    // $output[] = "USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND";
    // $output[] = "root         1  0.0  0.0 190928  3396 ?        Ss   Apr10   9:54 /usr/lib/systemd/systemd --switched-root --system --deserialize 22";
    // $output[] = "root         2  0.0  0.0      0     0 ?        S    Apr10   0:00 [kthreadd]";
    // $output[] = "root      1322  0.0  0.0 102900  2320 ?        Ss   Apr10   0:00 /sbin/dhclient -q -lf /var/lib/dhclient/dhclient--eth0.lease -pf /var/run/dhclient-eth0.pid -H VM_0_5_centos eth0";
    // $output[] = "mysql     2219  0.2  9.3 1654448 362344 ?      Sl   Apr10  76:53 /usr/libexec/mysqld --basedir=/usr --datadir=/data/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mariadb/mariadb.log --pid-file=/var/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock";
    // $output[] = "root      2934  0.0  0.2 494920 10360 ?        S    Apr10   0:02 WorkerMan: worker process  proxy tcp://0.0.0.0:6981";
    $cmddb = ['mysql', 'mysqld'];
    $cmdweb = ['nginx', 'php', 'WorkerMan', 'mosquitto', 'gitea', '/zgo'];
    $cpu = array('db' => 0, 'web' => 0, 'oth' => 0);
    $mem = array('db' => 0, 'web' => 0, 'oth' => 0);

    foreach ($output as $line) {
        if (strpos($line, "COMMAND") !== false)
            continue;
        _base_nextspace($line);
        _base_nextspace($line);
        $cpup = (float)_base_nextspace($line);
        $memp = (float)_base_nextspace($line);
        _base_nextspace($line); //虚拟内存
        _base_nextspace($line); //物理内存 包括共享内存
        _base_nextspace($line);
        _base_nextspace($line);
        _base_nextspace($line);
        _base_nextspace($line);
        if (_base_arrin($line, $cmddb)) {
            $cpu['db'] += $cpup;
            $mem['db'] += $memp;
        } else if (_base_arrin($line, $cmdweb)) {
            $cpu['web'] += $cpup;
            $mem['web'] += $memp;
        } else {
            $cpu['oth'] += $cpup;
            $mem['oth'] += $memp;
        }
    }

    $output = array();
    exec("free -m", $output);
    // $output = array();
    // $output[] = "              total        used        free      shared  buff/cache   available";
    // $output[] = "Mem:           3789         860         201          18        2727        2629";

    preg_match('/Mem:\s+(\d+)/', $output[1], $totalmem);
    $mem_free = $totalmem[1] * (100 - $cpu['db'] - $cpu['web'] - $cpu['oth']) * 1024 * 1024 / 100;

    $output = array();
    exec("netstat -an | awk '/^tcp/ {++S[\$NF]} END {for(a in S) print a, S[a]}'", $output);

    // $output = array();
    // $output[] = "LISTEN 13";
    // $output[] = "SYN_RECV 3";
    // $output[] = "ESTABLISHED 15";
    // $output[] = "TIME_WAIT 36";
    $net_tcp = 0;
    foreach ($output as $line) {
        $ls = explode(" ", $line);
        if ($ls[0] == 'LISTEN')
            continue;
        $net_tcp += (int)$ls[1];
    }

    $starttime = timems();
    $http = new ciy\http();
    $http->request('https://www.baidu.com');
    $http->get_data();
    $net_ioms = timems() - $starttime;

    $dbrows = $db->getraw('show global status');
    $dbstat = array();
    for ($i = 0; $i < count($dbrows); $i++) {
        $name = $dbrows[$i]['Variable_name'];
        $val = $dbrows[$i]['Value'];
        $dbstat[$name] = $val;
    }
    $db_keyhit = (int)$dbstat['Handler_read_key'] / ((int)$dbstat['Com_select'] + 1) * 100;
    $db_dbhit = (int)$dbstat['Innodb_buffer_pool_reads'] / ((int)$dbstat['Innodb_buffer_pool_read_requests'] + 1) * 100;
    $db_tmptable = (int)$dbstat['Created_tmp_disk_tables'] / ((int)$dbstat['Created_tmp_tables'] + 1) * 100;

    $updata = array();
    $updata['func_succ'] = $func_succ;
    $updata['func_fail'] = $func_fail;
    $updata['func_commit'] = $func_commit;
    $updata['func_rollback'] = $func_rollback;
    $updata['func_runms'] = $func_runms;
    $updata['disk_sysfree'] = $disk_sysfree;
    $updata['disk_datafree'] = $disk_datafree;
    $updata['disk_ioms'] = $disk_ioms;
    $updata['cpu_free'] = 100 - $cpu['db'] - $cpu['web'] - $cpu['oth'];
    $updata['cpu_db'] = $cpu['db'];
    $updata['cpu_web'] = $cpu['web'];
    $updata['cpu_oth'] = $cpu['oth'];
    $updata['mem_free'] = $mem_free;
    $updata['mem_db'] = $mem['db'];
    $updata['mem_web'] = $mem['web'];
    $updata['mem_oth'] = $mem['oth'];
    $updata['net_tcp'] = $net_tcp;
    $updata['net_ioms'] = $net_ioms;
    $updata['db_query'] = $dbstat['Questions'];
    $updata['db_commit'] = $dbstat['Com_commit'];
    $updata['db_rollback'] = $dbstat['Com_rollback'];
    $updata['db_keyhit'] = $db_keyhit;
    $updata['db_dbhit'] = $db_dbhit;
    $updata['db_tmptable'] = $db_tmptable;
    $updata['db_lock'] = $dbstat['Innodb_row_lock_current_waits'];
    $updata['addtimes'] = tostamp();
    $csql = new \ciy\sql('zc_stats');
    $db->insert($csql, $updata);
    if ($func_succ == 0 && $func_fail == 0 && $func_rollback == 0)
        return '';
    return 'succ: ' . $func_succ . ($func_rollback > 0 ? ', rollback: ' . $func_rollback : '');
}

function _base_delall($path) {
    try {
        if (is_dir($path)) {
            $p = scandir($path);
            foreach ($p as $val) {
                if ($val[0] == '.')
                    continue;
                if (is_dir($path . '/' . $val)) {
                    _base_delall($path . '/' . $val);
                } else {
                    unlink($path . '/' . $val);
                }
            }
            rmdir($path);
        } else {
            unlink($path);
        }
    } catch (\Exception $ex) {
        return $ex->getMessage();
    }
    return true;
}

function _base_nextspace(&$line) {
    $ind = strpos($line, " ");
    if ($ind === false) {
        $line = '';
        return $line;
    }
    $va = substr($line, 0, $ind);
    $line = ltrim(substr($line, $ind));
    return $va;
}
function _base_arrin($cmd, $arr) {
    foreach ($arr as $v) {
        if (strpos($cmd, $v) !== false)
            return true;
    }
    return false;
}
