/** * Executes the available schedules if they are to be executed. * This method can only be run once - even if one execution takes more * than planned. This is ensured by a locking mechanism. */ public function run() { if (!Config::get()->CRONJOBS_ENABLE) { return; } $escalation_time = Config::get()->CRONJOBS_ESCALATION; // Check whether a previous cronjob worker is still running. if ($this->lock->isLocked($data)) { // Running but not yet escalated -> let it run if ($data['timestamp'] + $escalation_time > time()) { return; } // Load locked schedule $schedule = CronjobSchedule::find($data['schedule_id']); // If we discovered a deadlock release it if ($schedule) { // Deactivate schedule $schedule->deactivate(); // Adjust log $log = CronjobLog::find($data['log_id']); $log->duration = time() - $data['timestamp']; $log->exception = new Exception('Cronjob has escalated'); $log->store(); // Inform roots about the escalated cronjob $subject = sprintf('[Cronjobs] %s: %s', _('Eskalierte Ausführung'), $schedule->title); $message = sprintf(_('Der Cronjob "%s" wurde deaktiviert, da ' . 'seine Ausführungsdauer die maximale ' . 'Ausführungszeit von %u Sekunden ' . 'überschritten hat.') . "\n", $schedule->title, $escalation_time); $this->sendMailToRoots($subject, $message); } // Release lock $this->lock->release(); } // Find all schedules that are due to execute and which task is active $temp = CronjobSchedule::findBySQL('active = 1 AND next_execution <= UNIX_TIMESTAMP() ' . 'ORDER BY priority DESC, next_execution ASC'); # $temp = SimpleORMapCollection::createFromArray($temp); $schedules = array_filter($temp, function ($schedule) { return $schedule->task->active; }); if (count($schedules) === 0) { return; } foreach ($schedules as $schedule) { $log = new CronjobLog(); $log->schedule_id = $schedule->schedule_id; $log->scheduled = $schedule->next_execution; $log->executed = time(); $log->exception = null; $log->duration = -1; $log->store(); set_time_limit($escalation_time); // Activate the file lock and store the current timestamp, // schedule id and according log id in it $this->lock->lock(array('schedule_id' => $schedule->schedule_id, 'log_id' => $log->log_id)); // Start capturing output and measuring duration ob_start(); $start_time = microtime(true); try { $schedule->execute(); } catch (Exception $e) { $log->exception = $e; // Deactivate schedule $schedule->deactivate(); // Send mail to root accounts $subject = sprintf('[Cronjobs] %s: %s', _('Fehlerhafte Ausführung'), $schedule->title); $message = sprintf(_('Der Cronjob "%s" wurde deaktiviert, da bei der Ausführung ein Fehler aufgetreten ist.'), $schedule->title) . "\n"; $message .= "\n"; $message .= display_exception($e) . "\n"; $message .= _('Für weiterführende Informationen klicken Sie bitten den folgenden Link:') . "\n"; $message .= $GLOBALS['ABSOLUTE_URI_STUDIP'] . URLHelper::getURL('dispatch.php/admin/cronjobs/logs/schedule/' . $schedule->schedule_id); $this->sendMailToRoots($subject, $message); } // Actually capture output and duration $end_time = microtime(true); $output = ob_get_clean(); // Complete log $log->output = $output; $log->duration = $end_time - $start_time; $log->store(); } // Release lock $this->lock->release(); }
function display_phpc() { global $phpc_messages, $phpc_redirect, $phpc_script, $phpc_prefix, $phpc_title, $phpcdb, $phpc_cal, $phpc_home_url; $navbar = false; try { $calendars = $phpcdb->get_calendars(); $list = array(); if (isset($phpc_cal)) { $phpc_title = $phpc_cal->get_title(); $title_link = tag('a', attrs("href='{$phpc_home_url}?phpcid={$phpc_cal->get_cid()}'", 'class="phpc-dropdown-list-title"'), $phpc_title); } else { $phpc_title = __("(No calendars)"); $title_link = $phpc_title; } foreach ($calendars as $calendar) { $list["{$phpc_home_url}?phpcid={$calendar->get_cid()}"] = $calendar->get_title(); } if (sizeof($calendars) > 1) { $title_tag = create_dropdown_list($title_link, $list); } else { $title_tag = $title_link; } $content = do_action(); if (sizeof($phpc_messages) > 0) { $messages = tag('div'); foreach ($phpc_messages as $message) { $messages->add($message); } // If we're redirecting, the messages might not get // seen, so don't clear them if (empty($phpc_redirect)) { $_SESSION["{$phpc_prefix}messages"] = NULL; } } else { $messages = ''; } return tag('div', attrs('class="php-calendar ui-widget"'), userMenu(), tag('br', attrs('style="clear:both;"')), tag('div', attrs('class="phpc-title ui-widget-header"'), $title_tag), navbar(), $messages, $content, footer()); } catch (PermissionException $e) { $msg = __('You do not have permission to do that: ') . $e->getMessage(); if (is_user()) { return error_message_redirect($msg, $phpc_script); } else { return error_message_redirect($msg, "{$phpc_script}?action=login"); } } catch (InvalidInputException $e) { return error_message_redirect($e->getMessage(), $e->target); } catch (Exception $e) { return display_exception($e, $navbar); } }
$phpc_fa_path = "//maxcdn.bootstrapcdn.com/font-awesome/{$fa_version}"; } if (!isset($phpc_jq_file)) { $phpc_jq_file = "//ajax.googleapis.com/ajax/libs/jquery/{$jquery_version}/jquery{$phpc_min}.js"; } /* * Do not modify anything under this point */ define('IN_PHPC', true); require_once "{$phpc_includes_path}/calendar.php"; try { require_once "{$phpc_includes_path}/setup.php"; } catch (Exception $e) { header("Content-Type: text/html; charset=UTF-8"); echo "<!DOCTYPE html>\n"; echo display_exception($e)->toString(); exit; } if ($vars["content"] == "json") { header("Content-Type: application/json; charset=UTF-8"); echo do_action(); } else { header("Content-Type: text/html; charset=UTF-8"); // This sets global variables that determine the title in the header $content = display_phpc(); $embed_script = ''; if ($vars["content"] == "embed") { $underscore_version = "1.5.2"; $embed_script = array(tag("script", attrs('src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/' . "{$underscore_version}/underscore-min.js\""), ''), tag('script', attrs('src="static/embed.js"'), '')); } $html = tag('html', attrs("lang=\"{$phpc_lang}\""), tag('head', tag('title', $phpc_title), tag('link', attrs('rel="icon"', "href=\"{$phpc_url_path}/static/office-calendar.png\"")), tag('meta', attrs('http-equiv="Content-Type"', 'content="text/html; charset=UTF-8"')), tag('link', attrs('rel="stylesheet"', "href=\"{$phpc_static_path}/phpc.css\"")), tag('link', attrs('rel="stylesheet"', "href=\"{$phpc_jqui_path}/themes/{$phpc_theme}/jquery-ui{$phpc_min}.css\"")), tag('link', attrs('rel="stylesheet"', "href=\"{$phpc_static_path}/jquery-ui-timepicker.css\"")), tag('link', attrs('rel="stylesheet"', "href=\"{$phpc_fa_path}/css/font-awesome{$phpc_min}.css\"")), tag("script", attrs("src=\"{$phpc_jq_file}\""), ''), tag("script", attrs("src=\"{$phpc_jqui_path}/jquery-ui{$phpc_min}.js\""), ''), tag('script', attrs("src=\"{$phpc_static_path}/phpc.js\""), ''), tag("script", attrs("src=\"{$phpc_static_path}/jquery.ui.timepicker.js\""), ''), tag("script", attrs("src=\"{$phpc_static_path}/farbtastic.min.js\""), ''), tag('link', attrs('rel="stylesheet"', "href=\"{$phpc_static_path}/farbtastic.css\""))), tag('body', $embed_script, $content));
echo number_format($log->duration, 6, ',', '.'); ?> <?php echo _('Sekunden'); ?> <? endif; ?> </dd> <? if (!empty($log->output)): ?> <dt><?php echo _('Ausgabe'); ?> </dt> <dd><pre><?php echo htmlReady($log->output); ?> </pre></dd> <? endif; ?> <? if ($log->exception !== null): ?> <dt><?php echo _('Fehler'); ?> </dt> <dd><?php echo display_exception($log->exception, true); ?> </dd> <? endif; ?> </dl>
/** * Displays the provided exception in a more readable fashion. * * @param Exception $exception The exception to be displayed * @param bool $as_html Indicates whether the exception shall be displayed as * plain text or html (optional, defaults to plain text) * @param bool $deep Indicates whether any previous exception should be * included in the output (optional, defaults to false) * @return String The exception display either as plain text or html */ function display_exception(Exception $exception, $as_html = false, $deep = false) { $result = ''; $result .= sprintf("%s: %s\n", _('Typ'), get_class($exception)); $result .= sprintf("%s: %s\n", _('Nachricht'), $exception->getMessage()); $result .= sprintf("%s: %d\n", _('Code'), $exception->getCode()); $trace = sprintf(" #\$ %s(%u)\n", $exception->getFile(), $exception->getLine()) . ' ' . str_replace("\n", "\n ", $exception->getTraceAsString()); $trace = str_replace($GLOBALS['STUDIP_BASE_PATH'] . '/', '', $trace); $result .= sprintf("%s:\n%s\n", _('Stack trace'), $trace); if ($deep && $exception->getPrevious()) { $result .= "\n"; $result .= _('Vorherige Exception:') . "\n"; $result .= display_exception($exception->getPrevious(), false, $deep); } return $as_html ? nl2br(htmlReady($result)) : $result; }
<?php $current_page = _('Fehler'); $title = _('Fehler! Bitte wenden Sie sich an Ihren Systemadministrator.'); $details = array(htmlReady($exception->getMessage())); if (Studip\ENV == 'development') { $title = "Houston, we've got a problem."; $details = array(display_exception($exception, true, true)); } ?> <?php echo MessageBox::exception($title, $details); ?> <p> <?php echo _('Zurück zur'); ?> <a href="<?php echo URLHelper::getLink('index.php'); ?> "><?php echo _('Startseite'); ?> </a> </p>