Improved cron logging via logfiles
* Added 3rd party logger library KLogger * Adjusted all cronjobs from verbose output to logging * Added new logs folder for crons to write to * Added new .gitignore for logs folder data * Updated blocks class to only fetch blocks with no share_id * Adjusted findblocks to use no blocks class method
This commit is contained in:
parent
2586aca34e
commit
6dc795fd77
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/public/include/config/global.inc.php
|
||||
/public/templates/compile/*.php
|
||||
/cronjobs/logs/*.txt
|
||||
|
||||
@ -22,10 +22,8 @@ limitations under the License.
|
||||
// Include all settings and classes
|
||||
require_once('shared.inc.php');
|
||||
|
||||
verbose("Running auto-payouts ...");
|
||||
|
||||
if ($bitcoin->can_connect() !== true) {
|
||||
verbose(" unable to connect to RPC server, exiting\n");
|
||||
$log->logFatal(" unable to connect to RPC server, exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -36,16 +34,16 @@ $setting->setValue('auto_payout_active', 1);
|
||||
$users = $user->getAllAutoPayout();
|
||||
|
||||
// Quick summary
|
||||
verbose(" found " . count($users) . " queued payout(s)\n");
|
||||
$log->logInfo(" found " . count($users) . " queued payout(s)\n");
|
||||
|
||||
// Go through users and run transactions
|
||||
if (! empty($users)) {
|
||||
verbose("\tUserID\tUsername\tBalance\tThreshold\tAddress\t\t\t\t\tStatus\n\n");
|
||||
$log->logInfo("\tUserID\tUsername\tBalance\tThreshold\tAddress");
|
||||
|
||||
foreach ($users as $aUserData) {
|
||||
$aBalance = $transaction->getBalance($aUserData['id']);
|
||||
$dBalance = $aBalance['confirmed'];
|
||||
verbose("\t" . $aUserData['id'] . "\t" . $aUserData['username'] . "\t" . $dBalance . "\t" . $aUserData['ap_threshold'] . "\t\t" . $aUserData['coin_address'] . "\t");
|
||||
$log->logInfo("\t" . $aUserData['id'] . "\t" . $aUserData['username'] . "\t" . $dBalance . "\t" . $aUserData['ap_threshold'] . "\t\t" . $aUserData['coin_address']);
|
||||
|
||||
// Only run if balance meets threshold and can pay the potential transaction fee
|
||||
if ($dBalance > $aUserData['ap_threshold'] && $dBalance > $config['txfee']) {
|
||||
@ -53,7 +51,7 @@ if (! empty($users)) {
|
||||
try {
|
||||
$bitcoin->validateaddress($aUserData['coin_address']);
|
||||
} catch (BitcoinClientException $e) {
|
||||
verbose("VERIFY FAILED\n");
|
||||
$log->logError('Failed to verifu this users coin address, skipping payout');
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -61,7 +59,7 @@ if (! empty($users)) {
|
||||
try {
|
||||
$bitcoin->sendtoaddress($aUserData['coin_address'], $dBalance);
|
||||
} catch (BitcoinClientException $e) {
|
||||
verbose("SEND FAILED\n");
|
||||
$log->logError('Failed to send requested balance to coin address, please check payout process');
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -71,21 +69,15 @@ if (! empty($users)) {
|
||||
$aMailData['email'] = $user->getUserEmail($user->getUserName($aUserData['id']));
|
||||
$aMailData['subject'] = 'Auto Payout Completed';
|
||||
$aMailData['amount'] = $dBalance;
|
||||
if (!$notification->sendNotification($aUserData['id'], 'auto_payout', $aMailData)) {
|
||||
verbose("NOTIFY FAILED\n");
|
||||
} else {
|
||||
verbose("OK\n");
|
||||
}
|
||||
if (!$notification->sendNotification($aUserData['id'], 'auto_payout', $aMailData))
|
||||
$log->logError('Failed to send notification email to users address: ' . $aMailData['email']);
|
||||
} else {
|
||||
verbose("FAILED\n");
|
||||
$log->logError('Failed to add new Debit_AP transaction in database for user ' . $user->getUserName($aUserData['id']));
|
||||
}
|
||||
|
||||
} else {
|
||||
verbose("SKIPPED\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
verbose(" no user has configured their AP > 0\n");
|
||||
$log->logDebug(" no user has configured their AP > 0\n");
|
||||
}
|
||||
|
||||
// Mark this job as inactive
|
||||
|
||||
@ -23,33 +23,31 @@ limitations under the License.
|
||||
require_once('shared.inc.php');
|
||||
|
||||
if ( $bitcoin->can_connect() !== true ) {
|
||||
verbose("Failed to connect to RPC server\n");
|
||||
$log->logFatal("Failed to connect to RPC server\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Fetch all unconfirmed blocks
|
||||
$aAllBlocks = $block->getAllUnconfirmed($config['confirmations']);
|
||||
|
||||
verbose("ID\tBlockhash\tConfirmations\t\n");
|
||||
$log->logInfo("ID\tBlockhash\tConfirmations");
|
||||
foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
$aBlockInfo = $bitcoin->query('getblock', $aBlock['blockhash']);
|
||||
// Fetch this blocks transaction details to find orphan blocks
|
||||
$aTxDetails = $bitcoin->query('gettransaction', $aBlockInfo['tx'][0]);
|
||||
verbose($aBlock['id'] . "\t" . $aBlock['blockhash'] . "\t" . $aBlock['confirmations'] . " -> " . $aBlockInfo['confirmations'] . "\t");
|
||||
$log->logInfo($aBlock['id'] . "\t" . $aBlock['blockhash'] . "\t" . $aBlock['confirmations'] . " -> " . $aBlockInfo['confirmations']);
|
||||
if ($aTxDetails['details'][0]['category'] == 'orphan') {
|
||||
// We have an orphaned block, we need to invalidate all transactions for this one
|
||||
if ($transaction->setOrphan($aBlock['id']) && $block->setConfirmations($aBlock['id'], -1)) {
|
||||
verbose("ORPHAN\n");
|
||||
$log->logInfo(" Block marked as orphan");
|
||||
} else {
|
||||
verbose("ORPHAN_ERR");
|
||||
$log->logError(" Block became orphaned but unable to update database entries");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ($aBlock['confirmations'] == $aBlockInfo['confirmations']) {
|
||||
verbose("SKIPPED\n");
|
||||
} else if ($block->setConfirmations($aBlock['id'], $aBlockInfo['confirmations'])) {
|
||||
verbose("UPDATED\n");
|
||||
} else {
|
||||
verbose("ERROR\n");
|
||||
$log->logDebug(' No update needed');
|
||||
} else if (!$block->setConfirmations($aBlock['id'], $aBlockInfo['confirmations'])) {
|
||||
$log->logError(' Failed to update block confirmations');
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,24 +25,22 @@ require_once('shared.inc.php');
|
||||
// Fetch our last block found from the DB as a starting point
|
||||
$aLastBlock = @$block->getLast();
|
||||
$strLastBlockHash = $aLastBlock['blockhash'];
|
||||
if (!$strLastBlockHash) {
|
||||
$strLastBlockHash = '';
|
||||
}
|
||||
if (!$strLastBlockHash) $strLastBlockHash = '';
|
||||
|
||||
// Fetch all transactions since our last block
|
||||
if ( $bitcoin->can_connect() === true ){
|
||||
$aTransactions = $bitcoin->query('listsinceblock', $strLastBlockHash);
|
||||
} else {
|
||||
verbose("Aborted: " . $bitcoin->can_connect() . "\n");
|
||||
$log->logFatal('Unable to conenct to RPC server backend');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Nothing to do so bail out
|
||||
if (empty($aTransactions['transactions'])) {
|
||||
verbose("No new RPC transactions since last block\n");
|
||||
$log->logDebug('No new RPC transactions since last block');
|
||||
} else {
|
||||
// Table header
|
||||
verbose("Blockhash\t\tHeight\tAmount\tConfirmations\tDiff\t\tTime\t\t\tStatus\n");
|
||||
$log->logInfo("Blockhash\t\tHeight\tAmount\tConfirmations\tDiff\t\tTime");
|
||||
|
||||
// Let us add those blocks as unaccounted
|
||||
foreach ($aTransactions['transactions'] as $iIndex => $aData) {
|
||||
@ -51,29 +49,26 @@ if (empty($aTransactions['transactions'])) {
|
||||
$config['reward_type'] == 'block' ? $aData['amount'] = $aData['amount'] : $aData['amount'] = $config['reward'];
|
||||
$aData['height'] = $aBlockInfo['height'];
|
||||
$aData['difficulty'] = $aBlockInfo['difficulty'];
|
||||
verbose(substr($aData['blockhash'], 0, 15) . "...\t" .
|
||||
$log->logInfo(substr($aData['blockhash'], 0, 15) . "...\t" .
|
||||
$aData['height'] . "\t" .
|
||||
$aData['amount'] . "\t" .
|
||||
$aData['confirmations'] . "\t\t" .
|
||||
$aData['difficulty'] . "\t" .
|
||||
strftime("%Y-%m-%d %H:%M:%S", $aData['time']) . "\t");
|
||||
if ( $block->addBlock($aData) ) {
|
||||
verbose("Added\n");
|
||||
} else {
|
||||
verbose("Failed" . "\n");
|
||||
strftime("%Y-%m-%d %H:%M:%S", $aData['time']));
|
||||
if (!$block->addBlock($aData) ) {
|
||||
$log->logFatal('Unable to add this block to database: ' . $aData['height']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
verbose("\n");
|
||||
// Now with our blocks added we can scan for their upstream shares
|
||||
$aAllBlocks = $block->getAllUnaccounted('ASC');
|
||||
$aAllBlocks = $block->getAllUnsetShareId('ASC');
|
||||
if (empty($aAllBlocks)) {
|
||||
verbose("No new unaccounted blocks found\n");
|
||||
$log->logDebug('No new blocks without share_id found in database');
|
||||
} else {
|
||||
// Loop through our unaccounted blocks
|
||||
verbose("\nBlock ID\tBlock Height\tAmount\tShare ID\tShares\tFinder\t\t\tStatus\n");
|
||||
$log->logInfo("Block ID\t\tHeight\tAmount\tShare ID\tShares\tFinder");
|
||||
foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
if (empty($aBlock['share_id'])) {
|
||||
// Fetch this blocks upstream ID
|
||||
@ -81,40 +76,35 @@ if (empty($aAllBlocks)) {
|
||||
$iCurrentUpstreamId = $share->getUpstreamId();
|
||||
$iAccountId = $user->getUserId($share->getUpstreamFinder());
|
||||
} else {
|
||||
verbose("\nUnable to fetch blocks upstream share. Aborting!\n");
|
||||
verbose($share->getError() . "\n");
|
||||
$log->logFatal('Unable to fetch blocks upstream share, aborted:' . $share->getError());
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch share information
|
||||
if (!$iPreviousShareId = $block->getLastShareId()) {
|
||||
$iPreviousShareId = 0;
|
||||
verbose("\nUnable to find highest share ID found so far\n");
|
||||
verbose("If this is your first block, this is normal\n\n");
|
||||
$log->logInfo('Unable to find highest share ID found so far, if this is your first block, this is normal.');
|
||||
}
|
||||
$iRoundShares = $share->getRoundShares($iPreviousShareId, $iCurrentUpstreamId);
|
||||
|
||||
// Store new information
|
||||
$strStatus = "OK";
|
||||
if (!$block->setShareId($aBlock['id'], $iCurrentUpstreamId))
|
||||
$strStatus = "Share ID Failed";
|
||||
$log->logError('Failed to update share ID in database for block ' . $aBlock['height']);
|
||||
if (!$block->setFinder($aBlock['id'], $iAccountId))
|
||||
$strStatus = "Finder Failed";
|
||||
$log->logError('Failed to update finder account ID in database for block ' . $aBlock['height']);
|
||||
if (!$block->setShares($aBlock['id'], $iRoundShares))
|
||||
$strStatus = "Shares Failed";
|
||||
$log->logError('Failed to update share count in database for block ' . $aBlock['height']);
|
||||
if ($config['block_bonus'] > 0 && !$transaction->addTransaction($iAccountId, $config['block_bonus'], 'Bonus', $aBlock['id'])) {
|
||||
$strStatus = "Bonus Failed";
|
||||
$log->logError('Failed to create Bonus transaction in database for user ' . $user->getUserName($iAccountId) . ' for block ' . $aBlock['height']);
|
||||
}
|
||||
|
||||
verbose(
|
||||
$log->logInfo(
|
||||
$aBlock['id'] . "\t\t"
|
||||
. $aBlock['height'] . "\t\t"
|
||||
. $aBlock['amount'] . "\t"
|
||||
. $iCurrentUpstreamId . "\t\t"
|
||||
. $iRoundShares . "\t"
|
||||
. "[$iAccountId] " . $user->getUserName($iAccountId) . "\t\t"
|
||||
. $strStatus
|
||||
. "\n"
|
||||
. "[$iAccountId] " . $user->getUserName($iAccountId)
|
||||
);
|
||||
|
||||
// Notify users
|
||||
@ -125,7 +115,8 @@ if (empty($aAllBlocks)) {
|
||||
$aMailData['subject'] = 'New Block';
|
||||
$aMailData['email'] = $user->getUserEmail($user->getUserName($aData['account_id']));
|
||||
$aMailData['shares'] = $iRoundShares;
|
||||
$notification->sendNotification($aData['account_id'], 'new_block', $aMailData);
|
||||
if (!$notification->sendNotification($aData['account_id'], 'new_block', $aMailData))
|
||||
$log->logError('Failed to notify user of new found block: ' . $user->getUserName($aData['account_id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
cronjobs/logs/README.md
Normal file
1
cronjobs/logs/README.md
Normal file
@ -0,0 +1 @@
|
||||
Logging directory for cronjobs.
|
||||
@ -22,51 +22,47 @@ limitations under the License.
|
||||
// Include all settings and classes
|
||||
require_once('shared.inc.php');
|
||||
|
||||
verbose("Running system notifications\n");
|
||||
|
||||
verbose(" IDLE Worker Notifications ...");
|
||||
$log->logDebug(" IDLE Worker Notifications ...");
|
||||
// Find all IDLE workers
|
||||
$aWorkers = $worker->getAllIdleWorkers();
|
||||
if (empty($aWorkers)) {
|
||||
verbose(" no idle workers found\n");
|
||||
$log->logDebug(" no idle workers found\n");
|
||||
} else {
|
||||
verbose(" found " . count($aWorkers) . " IDLE workers\n");
|
||||
$log->logInfo(" found " . count($aWorkers) . " IDLE workers\n");
|
||||
foreach ($aWorkers as $aWorker) {
|
||||
$aData = $aWorker;
|
||||
$aData['username'] = $user->getUserName($aWorker['account_id']);
|
||||
$aData['subject'] = 'IDLE Worker : ' . $aWorker['username'];
|
||||
$aData['worker'] = $aWorker['username'];
|
||||
$aData['email'] = $user->getUserEmail($aData['username']);
|
||||
verbose(" " . $aWorker['username'] . "...");
|
||||
if (!$notification->sendNotification($aWorker['account_id'], 'idle_worker', $aData)) {
|
||||
verbose(" " . $notification->getError() . "\n");
|
||||
} else {
|
||||
verbose(" sent\n");
|
||||
}
|
||||
$log->logInfo(" " . $aWorker['username'] . "...");
|
||||
if (!$notification->sendNotification($aWorker['account_id'], 'idle_worker', $aData))
|
||||
$log->logError(" Failed sending notifications: " . $notification->getError() . "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
verbose(" Reset IDLE Worker Notifications ...");
|
||||
$log->logDebug(" Reset IDLE Worker Notifications ...");
|
||||
// We notified, lets check which recovered
|
||||
$aNotifications = $notification->getAllActive('idle_worker');
|
||||
if (!empty($aNotifications)) {
|
||||
verbose(" found " . count($aNotifications) . " active notification(s)\n");
|
||||
$log->logInfo(" found " . count($aNotifications) . " active notification(s)\n");
|
||||
foreach ($aNotifications as $aNotification) {
|
||||
$aData = json_decode($aNotification['data'], true);
|
||||
$aWorker = $worker->getWorker($aData['id']);
|
||||
verbose(" " . $aWorker['username'] . " ...");
|
||||
$log->logInfo(" " . $aWorker['username'] . " ...");
|
||||
if ($aWorker['active'] == 1) {
|
||||
if ($notification->setInactive($aNotification['id'])) {
|
||||
verbose(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive\n");
|
||||
$log->logInfo(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive\n");
|
||||
} else {
|
||||
verbose(" failed to update #" . $aNotification['id'] . " for " . $aWorker['username'] . "\n");
|
||||
$log->logInfo(" failed to update #" . $aNotification['id'] . " for " . $aWorker['username'] . "\n");
|
||||
}
|
||||
} else {
|
||||
verbose(" still inactive\n");
|
||||
$log->logInfo(" still inactive\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
verbose(" no active IDLE worker notifications\n");
|
||||
$log->logDebug(" no active IDLE worker notifications\n");
|
||||
}
|
||||
?>
|
||||
|
||||
@ -25,7 +25,7 @@ require_once('shared.inc.php');
|
||||
|
||||
// Check if we are set as the payout system
|
||||
if ($config['payout_system'] != 'pps') {
|
||||
verbose("Please activate this cron in configuration via payout_system = pps\n");
|
||||
$log->logInfo("Please activate this cron in configuration via payout_system = pps\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ if ( $bitcoin->can_connect() === true ){
|
||||
if (is_array($dDifficulty) && array_key_exists('proof-of-work', $dDifficulty))
|
||||
$dDifficulty = $dDifficulty['proof-of-work'];
|
||||
} else {
|
||||
verbose("Aborted: " . $bitcoin->can_connect() . "\n");
|
||||
$log->logFatal("Aborted: " . $bitcoin->can_connect() . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ $iLastShareId = $share->getLastInsertedShareId();
|
||||
// Check for all new shares, we start one higher as our last accounted share to avoid duplicates
|
||||
$aAccountShares = $share->getSharesForAccounts($iPreviousShareId + 1, $iLastShareId);
|
||||
|
||||
verbose("ID\tUsername\tInvalid\tValid\t\tPPS Value\t\tPayout\t\tDonation\tFee\t\tStatus\n");
|
||||
$log->logInfo("ID\tUsername\tInvalid\tValid\t\tPPS Value\t\tPayout\t\tDonation\tFee");
|
||||
|
||||
foreach ($aAccountShares as $aData) {
|
||||
// Take our valid shares and multiply by per share value
|
||||
@ -74,60 +74,59 @@ foreach ($aAccountShares as $aData) {
|
||||
// Calculate donation amount
|
||||
$aData['donation'] = number_format(round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8), 8);
|
||||
|
||||
verbose($aData['id'] . "\t" .
|
||||
$log->logInfo($aData['id'] . "\t" .
|
||||
$aData['username'] . "\t" .
|
||||
$aData['invalid'] . "\t" .
|
||||
$aData['valid'] . "\t*\t" .
|
||||
$pps_value . "\t=\t" .
|
||||
$aData['payout'] . "\t" .
|
||||
$aData['donation'] . "\t" .
|
||||
$aData['fee'] . "\t");
|
||||
$aData['fee']);
|
||||
|
||||
$strStatus = "OK";
|
||||
// Add new credit transaction
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['payout'], 'Credit_PPS'))
|
||||
$strStatus = "Transaction Failed";
|
||||
$log->logError('Failed to add Credit_PPS transaction in database');
|
||||
// Add new fee debit for this block
|
||||
if ($aData['fee'] > 0 && $config['fees'] > 0)
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['fee'], 'Fee_PPS'))
|
||||
$strStatus = "Fee Failed";
|
||||
$log->logError('Failed to add Fee_PPS transaction in database');
|
||||
// Add new donation debit
|
||||
if ($aData['donation'] > 0)
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['donation'], 'Donation_PPS'))
|
||||
$strStatus = "Donation Failed";
|
||||
verbose($strStatus . "\n");
|
||||
$log->logError('Failed to add Donation_PPS transaction in database');
|
||||
}
|
||||
|
||||
// Store our last inserted ID for the next run
|
||||
$setting->setValue('pps_last_share_id', $iLastShareId);
|
||||
|
||||
verbose("\n\n------------------------------------------------------------------------------------\n\n");
|
||||
|
||||
// Fetch all unaccounted blocks
|
||||
$aAllBlocks = $block->getAllUnaccounted('ASC');
|
||||
if (empty($aAllBlocks)) {
|
||||
verbose("No new unaccounted blocks found\n");
|
||||
$log->logDebug("No new unaccounted blocks found");
|
||||
}
|
||||
|
||||
// Go through blocks and archive/delete shares that have been accounted for
|
||||
foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
// If we are running through more than one block, check for previous share ID
|
||||
$iLastBlockShare = @$aAllBlocks[$iIndex - 1]['share_id'] ? @$aAllBlocks[$iIndex - 1]['share_id'] : 0;
|
||||
if (!is_numeric($aBlock['share_id'])) die("Block " . $aBlock['height'] . " has no share_id associated with it, not going to continue\n");
|
||||
if (!is_numeric($aBlock['share_id'])) {
|
||||
$log->logFatal("Block " . $aBlock['height'] . " has no share_id associated with it, not going to continue");
|
||||
exit(1);
|
||||
}
|
||||
// Per account statistics
|
||||
$aAccountShares = $share->getSharesForAccounts(@$iLastBlockShare, $aBlock['share_id']);
|
||||
foreach ($aAccountShares as $key => $aData) {
|
||||
if (!$statistics->updateShareStatistics($aData, $aBlock['id']))
|
||||
verbose("Failed to update stats for this block on : " . $aData['username'] . "\n");
|
||||
$log->logError("Failed to update stats for this block on : " . $aData['username']);
|
||||
}
|
||||
// Move shares to archive
|
||||
if ($config['archive_shares'] && $aBlock['share_id'] < $iLastShareId) {
|
||||
if (!$share->moveArchive($aBlock['share_id'], $aBlock['id'], @$iLastBlockShare))
|
||||
verbose("Archving failed\n");
|
||||
$log->logError("Archving failed");
|
||||
}
|
||||
// Delete shares
|
||||
if ($aBlock['share_id'] < $iLastShareId && !$share->deleteAccountedShares($aBlock['share_id'], $iLastBlockShare)) {
|
||||
verbose("\nERROR : Failed to delete accounted shares from " . $aBlock['share_id'] . " to " . $iLastBlockShare . ", aborting!\n");
|
||||
$log->logFatal("Failed to delete accounted shares from " . $aBlock['share_id'] . " to " . $iLastBlockShare . ", aborting!");
|
||||
exit(1);
|
||||
}
|
||||
// Mark this block as accounted for
|
||||
|
||||
@ -24,36 +24,39 @@ require_once('shared.inc.php');
|
||||
|
||||
// Check if we are set as the payout system
|
||||
if ($config['payout_system'] != 'prop') {
|
||||
verbose("Please activate this cron in configuration via payout_system = prop\n");
|
||||
$log->logInfo("Please activate this cron in configuration via payout_system = prop");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Fetch all unaccounted blocks
|
||||
$aAllBlocks = $block->getAllUnaccounted('ASC');
|
||||
if (empty($aAllBlocks)) {
|
||||
verbose("No new unaccounted blocks found\n");
|
||||
$log->logDebug('No new unaccounted blocks found in database');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
// Table header for account shares
|
||||
$log->logInfo("ID\tUsername\tValid\tInvalid\tPercentage\tPayout\t\tDonation\tFee");
|
||||
foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
if (!$aBlock['accounted']) {
|
||||
$iPreviousShareId = @$aAllBlocks[$iIndex - 1]['share_id'] ? $aAllBlocks[$iIndex - 1]['share_id'] : 0;
|
||||
$iCurrentUpstreamId = $aBlock['share_id'];
|
||||
if (!is_numeric($iCurrentUpstreamId)) die("Block " . $aBlock['height'] . " has no share_id associated with it, not going to continue\n");
|
||||
if (!is_numeric($iCurrentUpstreamId)) {
|
||||
$log->logFatal("Block " . $aBlock['height'] . " has no share_id associated with it, not going to continue.");
|
||||
$log->logFatal("Please assign a valid share ID to this block to continue the payout process.");
|
||||
exit(1);
|
||||
}
|
||||
$aAccountShares = $share->getSharesForAccounts($iPreviousShareId, $aBlock['share_id']);
|
||||
$iRoundShares = $share->getRoundShares($iPreviousShareId, $aBlock['share_id']);
|
||||
$config['reward_type'] == 'block' ? $dReward = $aBlock['amount'] : $dReward = $config['reward'];
|
||||
|
||||
if (empty($aAccountShares)) {
|
||||
verbose("\nNo shares found for this block: " . $aBlock['height'] . " \n\n");
|
||||
$log->logFatal('No shares found for this block, aborted: ' . $aBlock['height']);
|
||||
sleep(2);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Table header for account shares
|
||||
verbose("ID\tUsername\tValid\tInvalid\tPercentage\tPayout\t\tDonation\tFee\t\tStatus\n");
|
||||
|
||||
// Loop through all accounts that have found shares for this round
|
||||
foreach ($aAccountShares as $key => $aData) {
|
||||
// Payout based on shares, PPS system
|
||||
@ -69,45 +72,40 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
$aData['donation'] = number_format(round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8), 8);
|
||||
|
||||
// Verbose output of this users calculations
|
||||
verbose($aData['id'] . "\t" .
|
||||
$log->logInfo($aData['id'] . "\t" .
|
||||
$aData['username'] . "\t" .
|
||||
$aData['valid'] . "\t" .
|
||||
$aData['invalid'] . "\t" .
|
||||
$aData['percentage'] . "\t" .
|
||||
$aData['payout'] . "\t" .
|
||||
$aData['donation'] . "\t" .
|
||||
$aData['fee'] . "\t");
|
||||
$aData['fee']);
|
||||
|
||||
$strStatus = "OK";
|
||||
// Update user share statistics
|
||||
if (!$statistics->updateShareStatistics($aData, $aBlock['id']))
|
||||
$strStatus = "Stats Failed";
|
||||
$log->logFatal('Failed to update share statistics for ' . $aData['username']);
|
||||
// Add new credit transaction
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['payout'], 'Credit', $aBlock['id']))
|
||||
$strStatus = "Transaction Failed";
|
||||
$log->logFatal('Failed to insert new Credit transaction to database for ' . $aData['username']);
|
||||
// Add new fee debit for this block
|
||||
if ($aData['fee'] > 0 && $config['fees'] > 0)
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['fee'], 'Fee', $aBlock['id']))
|
||||
$strStatus = "Fee Failed";
|
||||
$log->logFatal('Failed to insert new Fee transaction to database for ' . $aData['username']);
|
||||
// Add new donation debit
|
||||
if ($aData['donation'] > 0)
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['donation'], 'Donation', $aBlock['id']))
|
||||
$strStatus = "Donation Failed";
|
||||
verbose("\t$strStatus\n");
|
||||
$log->logFatal('Failed to insert new Donation transaction to database for ' . $aData['username']);
|
||||
}
|
||||
|
||||
// Move counted shares to archive before this blockhash upstream share
|
||||
if ($config['archive_shares']) $share->moveArchive($iCurrentUpstreamId, $aBlock['id'], $iPreviousShareId);
|
||||
// Delete all accounted shares
|
||||
if (!$share->deleteAccountedShares($iCurrentUpstreamId, $iPreviousShareId)) {
|
||||
verbose("\nERROR : Failed to delete accounted shares from $iPreviousShareId to $iCurrentUpstreamId, aborting!\n");
|
||||
$log->logFatal('Failed to delete accounted shares from ' . $iPreviousShareId . ' to ' . $iCurrentUpstreamId . ', aborted');
|
||||
exit(1);
|
||||
}
|
||||
// Mark this block as accounted for
|
||||
if (!$block->setAccounted($aBlock['id'])) {
|
||||
verbose("\nERROR : Failed to mark block as accounted! Aborting!\n");
|
||||
}
|
||||
|
||||
verbose("------------------------------------------------------------------------\n\n");
|
||||
if (!$block->setAccounted($aBlock['id']))
|
||||
$log->logFatal('Failed to mark block as accounted! Aborted.');
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,16 +31,7 @@ require_once(BASEPATH . 'include/config/global.inc.php');
|
||||
// We include all needed files here, even though our templates could load them themself
|
||||
require_once(INCLUDE_DIR . '/autoloader.inc.php');
|
||||
|
||||
// Parse command line
|
||||
$options = getopt("v");
|
||||
if (array_key_exists('v', $options)) {
|
||||
define("VERBOSE", true);
|
||||
} else {
|
||||
define("VERBOSE", false);
|
||||
}
|
||||
|
||||
// Command line cron functions only
|
||||
function verbose($msg) {
|
||||
if (VERBOSE) echo $msg;
|
||||
}
|
||||
|
||||
// Load 3rd party logging library for running crons
|
||||
$log = new KLogger ( 'logs/' . basename($_SERVER['PHP_SELF'], '.php') . '.txt' , KLogger::DEBUG );
|
||||
$log->LogDebug('Starting ' . basename($_SERVER['PHP_SELF'], '.php'));
|
||||
?>
|
||||
|
||||
@ -25,44 +25,34 @@ require_once('shared.inc.php');
|
||||
// Fetch all cachable values but disable fetching from cache
|
||||
$statistics->setGetCache(false);
|
||||
|
||||
// Verbose output
|
||||
verbose("Running statistical cache updates\n");
|
||||
|
||||
// Since fetching from cache is disabled, overwrite our stats
|
||||
verbose(" getRoundShares ...");
|
||||
$start = microtime(true);
|
||||
if (!$statistics->getRoundShares())
|
||||
verbose(" update failed");
|
||||
verbose(" " . number_format(microtime(true) - $start, 2) . " seconds\n");
|
||||
verbose(" getTopContributors shares ...");
|
||||
$log->logError("getRoundShares update failed");
|
||||
$log->logInfo("getRoundShares update " . number_format(microtime(true) - $start, 2) . " seconds");
|
||||
$start = microtime(true);
|
||||
if (!$statistics->getTopContributors('shares'))
|
||||
verbose(" update failed");
|
||||
verbose(" " . number_format(microtime(true) - $start, 2) . " seconds\n");
|
||||
verbose(" getTopContributors hashes ...");
|
||||
$log->logError("getTopContributors shares update failed");
|
||||
$log->logInfo("getTopContributors shares " . number_format(microtime(true) - $start, 2) . " seconds");
|
||||
$start = microtime(true);
|
||||
if (!$statistics->getTopContributors('hashes'))
|
||||
verbose(" update failed");
|
||||
verbose(" " . number_format(microtime(true) - $start, 2) . " seconds\n");
|
||||
verbose(" getCurrentHashrate ...");
|
||||
$log->logError("getTopContributors hashes update failed");
|
||||
$log->logInfo("getTopContributors hashes " . number_format(microtime(true) - $start, 2) . " seconds");
|
||||
$start = microtime(true);
|
||||
if (!$statistics->getCurrentHashrate())
|
||||
verbose(" update failed");
|
||||
verbose(" " . number_format(microtime(true) - $start, 2) . " seconds\n");
|
||||
$log->logError("getCurrentHashrate update failed");
|
||||
$log->logInfo("getCurrentHashrate " . number_format(microtime(true) - $start, 2) . " seconds");
|
||||
// Admin specific statistics, we cache the global query due to slowness
|
||||
verbose(" getAllUserStats ...");
|
||||
$start = microtime(true);
|
||||
if (!$statistics->getAllUserStats('%'))
|
||||
verbose(" update failed");
|
||||
verbose(" " . number_format(microtime(true) - $start, 2) . " seconds\n");
|
||||
$log->logError("getAllUserStats update failed");
|
||||
$log->logInfo("getAllUserStats " . number_format(microtime(true) - $start, 2) . " seconds");
|
||||
|
||||
// Per user share statistics based on all shares submitted
|
||||
verbose(" getAllUserShares ...");
|
||||
$start = microtime(true);
|
||||
$aUserShares = $statistics->getAllUserShares();
|
||||
verbose(" " . number_format(microtime(true) - $start, 2) . " seconds");
|
||||
$log->logInfo("getAllUserShares " . number_format(microtime(true) - $start, 2) . " seconds");
|
||||
foreach ($aUserShares as $aShares) {
|
||||
$memcache->setCache('getUserShares'. $aShares['id'], $aShares);
|
||||
}
|
||||
verbose("\n");
|
||||
?>
|
||||
|
||||
@ -25,14 +25,12 @@ require_once('shared.inc.php');
|
||||
// Include additional file not set in autoloader
|
||||
require_once(CLASS_DIR . '/tools.class.php');
|
||||
|
||||
verbose("Running scheduled updates\n");
|
||||
verbose(" Price API Call ... ");
|
||||
if ($price = $tools->getPrice()) {
|
||||
verbose("found $price as price\n");
|
||||
$log->logInfo("Price update: found $price as price");
|
||||
if (!$setting->setValue('price', $price))
|
||||
verbose("unable to update value in settings table\n");
|
||||
$log->logError("unable to update value in settings table");
|
||||
} else {
|
||||
verbose("failed to fetch API data: " . $tools->getError() . "\n");
|
||||
$log->logFatal("failed to fetch API data: " . $tools->getError());
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@ -17,6 +17,7 @@ require_once(CLASS_DIR . '/debug.class.php');
|
||||
require_once(CLASS_DIR . '/bitcoin.class.php');
|
||||
require_once(CLASS_DIR . '/statscache.class.php');
|
||||
require_once(CLASS_DIR . '/bitcoinwrapper.class.php');
|
||||
require_once(INCLUDE_DIR . '/lib/KLogger.php');
|
||||
require_once(INCLUDE_DIR . '/database.inc.php');
|
||||
require_once(INCLUDE_DIR . '/smarty.inc.php');
|
||||
// Load classes that need the above as dependencies
|
||||
|
||||
@ -55,6 +55,18 @@ class Block {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all blocks without a share ID
|
||||
* @param order string Sort order, default ASC
|
||||
* @return data array Array with database fields as keys
|
||||
**/
|
||||
public function getAllUnsetShareId($order='ASC') {
|
||||
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE ISNULL(share_id) ORDER BY height $order");
|
||||
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all unaccounted blocks
|
||||
* @param order string Sort order, default ASC
|
||||
@ -62,12 +74,8 @@ class Block {
|
||||
**/
|
||||
public function getAllUnaccounted($order='ASC') {
|
||||
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE accounted = 0 ORDER BY height $order");
|
||||
if ($this->checkStmt($stmt)) {
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$stmt->close();
|
||||
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
148
public/include/lib/KLogger.php
Executable file
148
public/include/lib/KLogger.php
Executable file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/* Finally, A light, permissions-checking logging class.
|
||||
*
|
||||
* Author : Kenneth Katzgrau < katzgrau@gmail.com >
|
||||
* Date : July 26, 2008
|
||||
* Comments : Originally written for use with wpSearch
|
||||
* Website : http://codefury.net
|
||||
* Version : 1.0
|
||||
*
|
||||
* Usage:
|
||||
* $log = new KLogger ( "log.txt" , KLogger::INFO );
|
||||
* $log->LogInfo("Returned a million search results"); //Prints to the log file
|
||||
* $log->LogFATAL("Oh dear."); //Prints to the log file
|
||||
* $log->LogDebug("x = 5"); //Prints nothing due to priority setting
|
||||
*/
|
||||
|
||||
class KLogger
|
||||
{
|
||||
|
||||
const DEBUG = 1; // Most Verbose
|
||||
const INFO = 2; // ...
|
||||
const WARN = 3; // ...
|
||||
const ERROR = 4; // ...
|
||||
const FATAL = 5; // Least Verbose
|
||||
const OFF = 6; // Nothing at all.
|
||||
|
||||
const LOG_OPEN = 1;
|
||||
const OPEN_FAILED = 2;
|
||||
const LOG_CLOSED = 3;
|
||||
|
||||
/* Public members: Not so much of an example of encapsulation, but that's okay. */
|
||||
public $Log_Status = KLogger::LOG_CLOSED;
|
||||
public $DateFormat = "Y-m-d G:i:s";
|
||||
public $MessageQueue;
|
||||
|
||||
private $log_file;
|
||||
private $priority = KLogger::INFO;
|
||||
|
||||
private $file_handle;
|
||||
|
||||
public function __construct( $filepath , $priority )
|
||||
{
|
||||
if ( $priority == KLogger::OFF ) return;
|
||||
|
||||
$this->log_file = $filepath;
|
||||
$this->MessageQueue = array();
|
||||
$this->priority = $priority;
|
||||
|
||||
if ( file_exists( $this->log_file ) )
|
||||
{
|
||||
if ( !is_writable($this->log_file) )
|
||||
{
|
||||
$this->Log_Status = KLogger::OPEN_FAILED;
|
||||
$this->MessageQueue[] = "The file exists, but could not be opened for writing. Check that appropriate permissions have been set.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->file_handle = fopen( $this->log_file , "a" ) )
|
||||
{
|
||||
$this->Log_Status = KLogger::LOG_OPEN;
|
||||
$this->MessageQueue[] = "The log file was opened successfully.";
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Log_Status = KLogger::OPEN_FAILED;
|
||||
$this->MessageQueue[] = "The file could not be opened. Check permissions.";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ( $this->file_handle )
|
||||
fclose( $this->file_handle );
|
||||
}
|
||||
|
||||
public function LogInfo($line)
|
||||
{
|
||||
$this->Log( $line , KLogger::INFO );
|
||||
}
|
||||
|
||||
public function LogDebug($line)
|
||||
{
|
||||
$this->Log( $line , KLogger::DEBUG );
|
||||
}
|
||||
|
||||
public function LogWarn($line)
|
||||
{
|
||||
$this->Log( $line , KLogger::WARN );
|
||||
}
|
||||
|
||||
public function LogError($line)
|
||||
{
|
||||
$this->Log( $line , KLogger::ERROR );
|
||||
}
|
||||
|
||||
public function LogFatal($line)
|
||||
{
|
||||
$this->Log( $line , KLogger::FATAL );
|
||||
}
|
||||
|
||||
public function Log($line, $priority)
|
||||
{
|
||||
if ( $this->priority <= $priority )
|
||||
{
|
||||
$status = $this->getTimeLine( $priority );
|
||||
$this->WriteFreeFormLine ( "$status $line \n" );
|
||||
}
|
||||
}
|
||||
|
||||
public function WriteFreeFormLine( $line )
|
||||
{
|
||||
if ( $this->Log_Status == KLogger::LOG_OPEN && $this->priority != KLogger::OFF )
|
||||
{
|
||||
if (fwrite( $this->file_handle , $line ) === false) {
|
||||
$this->MessageQueue[] = "The file could not be written to. Check that appropriate permissions have been set.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getTimeLine( $level )
|
||||
{
|
||||
$time = date( $this->DateFormat );
|
||||
|
||||
switch( $level )
|
||||
{
|
||||
case KLogger::INFO:
|
||||
return "$time - INFO -->";
|
||||
case KLogger::WARN:
|
||||
return "$time - WARN -->";
|
||||
case KLogger::DEBUG:
|
||||
return "$time - DEBUG -->";
|
||||
case KLogger::ERROR:
|
||||
return "$time - ERROR -->";
|
||||
case KLogger::FATAL:
|
||||
return "$time - FATAL -->";
|
||||
default:
|
||||
return "$time - LOG -->";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
Loading…
Reference in New Issue
Block a user