1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-19 16:58:48 +02:00

Modified DarkConsole Error Log to show more detailed information.

Summary:
When function phlog() is called, stacktrace and detailed log information
is shown in DarkConsole.

Test Plan:
Called 'phlog' function from various places in Phabricator and checked that
the debug information was available in DarkConsole.

Reviewed By: epriestley
Reviewers: epriestley
CC: jungejason, epriestley
Differential Revision: 101
This commit is contained in:
tuomaspelkonen 2011-04-05 12:24:21 -07:00
parent 1910f43364
commit d5ee8c792c
10 changed files with 212 additions and 101 deletions

View file

@ -18,7 +18,7 @@ celerity_register_resource_map(array(
),
'aphront-dark-console-css' =>
array(
'uri' => '/res/056b0c12/rsrc/css/aphront/dark-console.css',
'uri' => '/res/0417eb95/rsrc/css/aphront/dark-console.css',
'type' => 'css',
'requires' =>
array(
@ -61,24 +61,6 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/css/aphront/headsup-action-list-view.css',
),
'aphront-list-filter-view-css' =>
array(
'uri' => '/res/50a790ae/rsrc/css/aphront/list-filter-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/list-filter-view.css',
),
'aphront-pager-view-css' =>
array(
'uri' => '/res/73ec8cd5/rsrc/css/aphront/pager-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/pager-view.css',
),
'aphront-panel-view-css' =>
array(
'uri' => '/res/8f9f3632/rsrc/css/aphront/panel-view.css',
@ -134,6 +116,24 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/css/aphront/typeahead.css',
),
'aphront-pager-view-css' =>
array(
'uri' => '/res/73ec8cd5/rsrc/css/aphront/pager-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/pager-view.css',
),
'aphront-list-filter-view-css' =>
array(
'uri' => '/res/50a790ae/rsrc/css/aphront/list-filter-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/list-filter-view.css',
),
'phabricator-standard-page-view' =>
array(
'uri' => '/res/0d41ea7c/rsrc/css/application/base/standard-page-view.css',
@ -297,15 +297,6 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/css/application/objectselector/object-selector.css',
),
'owners-path-editor-css' =>
array(
'uri' => '/res/f40dc6b1/rsrc/css/application/owners/owners-path-editor.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/owners/owners-path-editor.css',
),
'phabricator-profile-css' =>
array(
'uri' => '/res/259ad37f/rsrc/css/application/people/profile.css',
@ -315,6 +306,15 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/css/application/people/profile.css',
),
'owners-path-editor-css' =>
array(
'uri' => '/res/f40dc6b1/rsrc/css/application/owners/owners-path-editor.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/owners/owners-path-editor.css',
),
'phabricator-ui-example-css' =>
array(
'uri' => '/res/365a10f1/rsrc/css/application/uiexample/example.css',
@ -360,6 +360,16 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/css/core/syntax.css',
),
'multirow-row-manager' =>
array(
'uri' => '/res/330d076b/rsrc/js/application/core/MultirowRowManager.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-lib-dev',
),
'disk' => '/rsrc/js/application/core/MultirowRowManager.js',
),
'javelin-behavior-dark-console' =>
array(
'uri' => '/res/020b0265/rsrc/js/application/core/behavior-dark-console.js',
@ -371,7 +381,7 @@ celerity_register_resource_map(array(
),
'javelin-behavior-phabricator-object-selector' =>
array(
'uri' => '/res/4fe735af/rsrc/js/application/core/behavior-object-selector.js',
'uri' => '/res/c0f12b29/rsrc/js/application/core/behavior-object-selector.js',
'type' => 'js',
'requires' =>
array(
@ -399,15 +409,15 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/application/core/behavior-workflow.js',
),
'multirow-row-manager' =>
'javelin-behavior-error-log' =>
array(
'uri' => '/res/330d076b/rsrc/js/application/core/MultirowRowManager.js',
'uri' => '/res/c57a323f/rsrc/js/application/core/behavior-error-log.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-lib-dev',
),
'disk' => '/rsrc/js/application/core/MultirowRowManager.js',
'disk' => '/rsrc/js/application/core/behavior-error-log.js',
),
'javelin-behavior-differential-add-reviewers' =>
array(
@ -499,17 +509,6 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
),
'javelin-behavior-herald-rule-editor' =>
array(
'uri' => '/res/48108130/rsrc/js/application/herald/herald-rule-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'herald-rule-editor',
1 => 'javelin-lib-dev',
),
'disk' => '/rsrc/js/application/herald/herald-rule-editor.js',
),
'herald-rule-editor' =>
array(
'uri' => '/res/ec8e2110/rsrc/js/application/herald/HeraldRuleEditor.js',
@ -523,6 +522,17 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/application/herald/HeraldRuleEditor.js',
),
'javelin-behavior-herald-rule-editor' =>
array(
'uri' => '/res/48108130/rsrc/js/application/herald/herald-rule-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'herald-rule-editor',
1 => 'javelin-lib-dev',
),
'disk' => '/rsrc/js/application/herald/herald-rule-editor.js',
),
'path-typeahead' =>
array(
'uri' => '/res/42fb76c3/rsrc/js/application/herald/PathTypeahead.js',
@ -544,17 +554,6 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/application/maniphest/behavior-transaction-controls.js',
),
'javelin-behavior-owners-path-editor' =>
array(
'uri' => '/res/7568aa22/rsrc/js/application/owners/owners-path-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'owners-path-editor',
1 => 'javelin-lib-dev',
),
'disk' => '/rsrc/js/application/owners/owners-path-editor.js',
),
'owners-path-editor' =>
array(
'uri' => '/res/b01c1ca9/rsrc/js/application/owners/OwnersPathEditor.js',
@ -568,6 +567,17 @@ celerity_register_resource_map(array(
),
'disk' => '/rsrc/js/application/owners/OwnersPathEditor.js',
),
'javelin-behavior-owners-path-editor' =>
array(
'uri' => '/res/7568aa22/rsrc/js/application/owners/owners-path-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'owners-path-editor',
1 => 'javelin-lib-dev',
),
'disk' => '/rsrc/js/application/owners/owners-path-editor.js',
),
'javelin-magical-init' =>
array(
'uri' => '/res/76614f84/rsrc/js/javelin/init.dev.js',

View file

@ -124,7 +124,7 @@ final class DarkConsoleCore {
$panel_markup[] = javelin_render_tag(
'div',
array(
'class' => 'dark-console-panel',
'class' => 'dark-console-panel dark-console-panel-'.$key,
'style' => $style,
'sigil' => 'dark-console-panel',
),

View file

@ -46,39 +46,62 @@ class DarkConsoleErrorLogPlugin extends DarkConsolePlugin {
$data = $this->getData();
$rows = array();
foreach ($data as $row) {
switch ($row['event']) {
case 'error':
$file = $row['file'];
$line = $row['line'];
break;
case 'exception':
$file = $row['exception']->getFile();
$line = $row['exception']->getLine();
break;
$details = '';
foreach ($data as $index => $row) {
$file = $row['file'];
$line = $row['line'];
$tag = phutil_render_tag(
'a',
array(
'onclick' => jsprintf('show_details(%d)', $index),
),
phutil_escape_html($row['str'].' at ['.basename($file).':'.$line.']'));
$rows[] = array($tag);
$details .=
'<div class="dark-console-panel-error-details" id="row-details-'.
$index.'">'.
phutil_escape_html($row['details'])."\n".
'Stack trace:'."\n";
foreach ($row['trace'] as $key => $entry) {
$line = '';
if (isset($entry['class'])) {
$line .= $entry['class'].'::';
}
$line .= idx($entry, 'function', '');
$onclick = '';
if (isset($entry['file'])) {
$line .= ' called at ['.$entry['file'].':'.$entry['line'].']';
$onclick = jsprintf(
'open_file(%s, %d)', $entry['file'], $entry['line']);
}
$details .= phutil_render_tag(
'a',
array(
'onclick' => $onclick,
),
phutil_escape_html($line));
$details .= "\n";
}
$rows[] = array(
basename($file).':'.$line,
$row['str'],
);
$details .= '</div>';
}
$table = new AphrontTableView($rows);
$table->setColumnClasses(
array(
null,
'wide wrap',
));
$table->setHeaders(
array(
'File',
'Error',
));
$table->setClassName('error-log');
$table->setHeaders(array('Error'));
$table->setNoDataString('No errors.');
return $table->render();
return '<div>'.
'<div>'.$table->render().'</div>'.
'<div class="dark-console-panel-error-separator"></div>'.
'<pre class="PhabricatorMonospaced">'.
$details.'</pre>'.
'</div>';
}
}

View file

@ -10,5 +10,9 @@ phutil_require_module('phabricator', 'aphront/console/plugin/base');
phutil_require_module('phabricator', 'aphront/console/plugin/errorlog/api');
phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_module('phutil', 'xsprintf/jsprintf');
phutil_require_source('DarkConsoleErrorLogPlugin.php');

View file

@ -16,6 +16,7 @@
* limitations under the License.
*/
class DarkConsoleErrorLogPluginAPI {
private static $errors = array();
@ -30,29 +31,50 @@ class DarkConsoleErrorLogPluginAPI {
return self::$errors;
}
public static function handleError($num, $str, $file, $line, $cxt) {
if (!self::$discardMode) {
self::$errors[] = array(
'event' => 'error',
'num' => $num,
'str' => $str,
'file' => $file,
'line' => $line,
'cxt' => $cxt,
'trace' => debug_backtrace(),
);
public static function handleErrors($event, $value, $metadata) {
if (self::$discardMode) {
return;
}
error_log("{$file}:{$line} {$str}");
}
public static function handleException($ex) {
if (!self::$discardMode) {
self::$errors[] = array(
'event' => 'exception',
'exception' => $ex,
);
switch ($event) {
case PhutilErrorHandler::EXCEPTION:
// $value is of type Exception
self::$errors[] = array(
'details' => $value->getMessage(),
'event' => $event,
'file' => $value->getFile(),
'line' => $value->getLine(),
'str' => $value->getMessage(),
'trace' => $metadata['trace'],
);
break;
case PhutilErrorHandler::ERROR:
// $value is a simple string
self::$errors[] = array(
'details' => $value,
'event' => $event,
'file' => $metadata['file'],
'line' => $metadata['line'],
'str' => $value,
'trace' => $metadata['trace'],
);
break;
case PhutilErrorHandler::PHLOG:
// $value can be anything
self::$errors[] = array(
'details' => PhutilReadableSerializer::printShallow($value, 3),
'event' => $event,
'file' => $metadata['file'],
'line' => $metadata['line'],
'str' => PhutilReadableSerializer::printShort($value),
'trace' => $metadata['trace'],
);
break;
default:
error_log('Unknown event : '.$event);
break;
}
error_log($ex);
}
}

View file

@ -6,5 +6,8 @@
phutil_require_module('phutil', 'error');
phutil_require_module('phutil', 'readableserializer');
phutil_require_source('DarkConsoleErrorLogPluginAPI.php');

View file

@ -101,6 +101,9 @@ class PhabricatorStandardPageView extends AphrontPageView {
array(
'uri' => '/~/',
));
// Change this to initBehavior when there is some behavior to initialize
require_celerity_resource('javelin-behavior-error-log');
}
$this->bodyContent = $this->renderChildren();

View file

@ -71,6 +71,11 @@ $tz = PhabricatorEnv::getEnvConfig('phabricator.timezone');
if ($tz) {
date_default_timezone_set($tz);
}
phutil_require_module('phabricator', 'aphront/console/plugin/errorlog/api');
phutil_require_module('phutil', 'error');
PhutilErrorHandler::setErrorListener(
array('DarkConsoleErrorLogPluginAPI', 'handleErrors'));
foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) {
phutil_load_library($library);
@ -89,6 +94,7 @@ switch ($host) {
break;
}
$application->setHost($host);
$application->setPath($path);
$application->willBuildRequest();
@ -126,6 +132,7 @@ foreach ($headers as $header) {
header("{$header}: {$value}");
}
// TODO: This shouldn't be possible in a production-configured environment.
if (isset($_REQUEST['__profile__']) &&
($_REQUEST['__profile__'] == 'all')) {

View file

@ -70,3 +70,20 @@ a.dark-console-tab-selected {
.dark-console .aphront-table-view tr.no-data td {
color: #dddddd;
}
.dark-console-panel-ErrorLog {
max-height: 500px;
overflow: auto;
}
.dark-console-panel-error-details {
display: none;
}
.dark-console-panel-error-separator {
background-color: #e8e8e8;
border-bottom: 1px solid #b7b7b7;
border-top: 1px solid #b7b7b7;
height: 2px;
}

View file

@ -0,0 +1,22 @@
/**
* @provides javelin-behavior-error-log
* @requires javelin-lib-dev
*/
var current_details = null;
function open_file(file, row) {
// Do some fun some here, e.g., open the diffusion page for the file
// or open the file in an editor
}
function show_details(row) {
var node = JX.$('row-details-' + row);
if (current_details !== null) {
JX.$('row-details-' + current_details).style.display = 'none';
}
node.style.display = 'block';
current_details = row;
}