diff --git a/.gitignore b/.gitignore index d67a566e..66b6c501 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /public/include/config/global.inc.php /public/templates/compile/*.php +/cronjobs/logs/*.txt diff --git a/cronjobs/auto_payout.php b/cronjobs/auto_payout.php index aaf715e0..943a6cd7 100755 --- a/cronjobs/auto_payout.php +++ b/cronjobs/auto_payout.php @@ -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 diff --git a/cronjobs/blockupdate.php b/cronjobs/blockupdate.php index 65779a3a..89a27be1 100755 --- a/cronjobs/blockupdate.php +++ b/cronjobs/blockupdate.php @@ -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'); } } diff --git a/cronjobs/findblock.php b/cronjobs/findblock.php index efcc9f11..28dddb4b 100755 --- a/cronjobs/findblock.php +++ b/cronjobs/findblock.php @@ -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'])); } } } diff --git a/cronjobs/logs/README.md b/cronjobs/logs/README.md new file mode 100644 index 00000000..864999fd --- /dev/null +++ b/cronjobs/logs/README.md @@ -0,0 +1 @@ +Logging directory for cronjobs. diff --git a/cronjobs/notifications.php b/cronjobs/notifications.php index 61a608ab..a60e4657 100755 --- a/cronjobs/notifications.php +++ b/cronjobs/notifications.php @@ -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"); } ?> diff --git a/cronjobs/pps_payout.php b/cronjobs/pps_payout.php index 9c108e78..388f49ac 100755 --- a/cronjobs/pps_payout.php +++ b/cronjobs/pps_payout.php @@ -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 diff --git a/cronjobs/proportional_payout.php b/cronjobs/proportional_payout.php index fa346dfc..c9c61539 100755 --- a/cronjobs/proportional_payout.php +++ b/cronjobs/proportional_payout.php @@ -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.'); } } diff --git a/cronjobs/shared.inc.php b/cronjobs/shared.inc.php index a0b1dc5d..9d3ae322 100644 --- a/cronjobs/shared.inc.php +++ b/cronjobs/shared.inc.php @@ -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')); +?> diff --git a/cronjobs/statistics.php b/cronjobs/statistics.php index 69c1db5f..9ce96bde 100755 --- a/cronjobs/statistics.php +++ b/cronjobs/statistics.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"); ?> diff --git a/cronjobs/tickerupdate.php b/cronjobs/tickerupdate.php index 26323738..4b36adb2 100755 --- a/cronjobs/tickerupdate.php +++ b/cronjobs/tickerupdate.php @@ -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()); } ?> diff --git a/public/include/autoloader.inc.php b/public/include/autoloader.inc.php index e3a4534b..c74fa62b 100644 --- a/public/include/autoloader.inc.php +++ b/public/include/autoloader.inc.php @@ -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 diff --git a/public/include/classes/block.class.php b/public/include/classes/block.class.php index 743ce67e..2fcbad09 100644 --- a/public/include/classes/block.class.php +++ b/public/include/classes/block.class.php @@ -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; } diff --git a/public/include/lib/KLogger.php b/public/include/lib/KLogger.php new file mode 100755 index 00000000..9f53788e --- /dev/null +++ b/public/include/lib/KLogger.php @@ -0,0 +1,148 @@ + + * 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 -->"; + } + } + + } + + +?> \ No newline at end of file