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

Flesh out some DarkConsole stuff.

This commit is contained in:
epriestley 2011-02-02 22:38:42 -08:00
parent 5eb9bce6d4
commit c93dd9c090
26 changed files with 349 additions and 194 deletions

View file

@ -100,7 +100,7 @@ celerity_register_resource_map(array(
),
'differential-revision-add-comment-css' =>
array(
'uri' => '/res/d7f8719e/rsrc/css/application/differential/add-comment.css',
'uri' => '/res/9be761de/rsrc/css/application/differential/add-comment.css',
'type' => 'css',
'requires' =>
array(
@ -136,7 +136,7 @@ celerity_register_resource_map(array(
),
'differential-revision-comment-css' =>
array(
'uri' => '/res/368bd612/rsrc/css/application/differential/revision-comment.css',
'uri' => '/res/274eb3f1/rsrc/css/application/differential/revision-comment.css',
'type' => 'css',
'requires' =>
array(
@ -226,7 +226,7 @@ celerity_register_resource_map(array(
),
'javelin-behavior-dark-console' =>
array(
'uri' => '/res/453503f4/rsrc/js/application/core/behavior-dark-console.js',
'uri' => '/res/35907b6e/rsrc/js/application/core/behavior-dark-console.js',
'type' => 'js',
'requires' =>
array(

View file

@ -72,9 +72,11 @@ phutil_register_library_map(array(
'DarkConsoleController' => 'aphront/console/controller',
'DarkConsoleCore' => 'aphront/console/core',
'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/errorlog',
'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/api',
'DarkConsolePlugin' => 'aphront/console/plugin/base',
'DarkConsoleRequestPlugin' => 'aphront/console/plugin/request',
'DarkConsoleServicesPlugin' => 'aphront/console/plugin/services',
'DarkConsoleServicesPluginAPI' => 'aphront/console/plugin/services/api',
'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/xhprof',
'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/api',
'DifferentialAction' => 'applications/differential/constants/action',
@ -263,7 +265,7 @@ phutil_register_library_map(array(
'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_find_Method' => 'ConduitAPIMethod',
'DarkConsoleController' => 'AliteController',
'DarkConsoleController' => 'PhabricatorController',
'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
'DarkConsoleRequestPlugin' => 'DarkConsolePlugin',
'DarkConsoleServicesPlugin' => 'DarkConsolePlugin',

View file

@ -16,85 +16,29 @@
* limitations under the License.
*/
class DarkConsoleController extends AliteController {
class DarkConsoleController extends PhabricatorController {
protected $op;
protected $data;
public function __construct(AliteRequest $request, array $params) {
parent::__construct($request);
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
validate_parameter_list(
$params,
array(
),
$ops = array(
'tab' => true,
'toggle' => true,
'visible' => true,
'plugin' => true,
'etc' => true,
));
foreach (array_keys($ops) as $op) {
if (isset($params[$op])) {
$this->op = $op;
break;
}
}
$this->data = $params;
}
public function getShortControllerName() {
return 'DarkConsole';
}
public function shouldPreflush() {
return false;
}
public function process() {
$request = $this->getRequest();
if (!$this->op) {
$this->op = 'toggle';
$visible = $request->getStr('visible');
if (strlen($visible)) {
$user->setConsoleVisible((int)$visible);
$user->save();
return new AphrontAjaxResponse();
}
$coredata = $request->getCoreData();
$console = $coredata->getConsole();
if ($request->isAsync()) {
$return = null;
} else {
$return = '/';
$tab = $request->getStr('tab');
if (strlen($tab)) {
$user->setConsoleTab($tab);
$user->save();
return new AphrontAjaxResponse();
}
switch ($this->op) {
case 'toggle':
$enabled = $coredata->didToggleDarkConsole();
if ($enabled) {
if (!$console) {
$console = new DarkConsoleCore($coredata);
}
$console->setConsoleSetting(
DarkConsoleCore::SETTING_VISIBLE,
true);
}
break;
case 'tab':
$console->setConsoleSetting(
DarkConsoleCore::SETTING_TAB,
$request->getStr('tab'));
break;
case 'visible':
$console->setConsoleSetting(
DarkConsoleCore::SETTING_VISIBLE,
!$console->getConsoleSetting(DarkConsoleCore::SETTING_VISIBLE));
break;
}
// return <alite:redirect uri={$return} />;
}
}

View file

@ -6,7 +6,8 @@
phutil_require_module('phabricator', 'aphront/console/core');
phutil_require_module('phabricator', 'aphront/response/ajax');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_source('DarkConsoleController.php');

View file

@ -36,41 +36,11 @@ final class DarkConsoleCore {
private $settings;
private $coredata;
public function setConsoleSetting($key, $value) {
/*
$guard = new WriteOnHttpGet();
$okay = user_set_pref(
$this->getCoreData()->getViewerContext()->getUserID(),
self::APPLICATION_ID,
$key,
$value);
$guard->release();
if (!$okay) {
throw new Exception('Failed to set preference setting.');
}
*/
}
public function getConsoleSetting($key) {
// $viewer_id = $this->getCoreData()->getViewerContext()->getUserID();
// return idx(idx($this->settings[$viewer_id], $key), 'value');
return true;
}
public function getPlugin($plugin_name) {
return idx($this->plugins, $plugin_name);
}
public function __construct() {
/*
$this->settings = users_multiget_prefs_info(
array($coredata->getViewerContext()->getUserID()),
self::APPLICATION_ID);
$disabled = $this->getConsoleSetting(self::SETTING_PLUGINS);
$disabled = array_flip(explode(',', $disabled));
*/
foreach (self::getPlugins() as $plugin_name) {
$plugin = self::newPlugin($plugin_name);
if ($plugin->isPermanent() || !isset($disabled[$plugin_name])) {
@ -95,6 +65,8 @@ final class DarkConsoleCore {
public function render(AphrontRequest $request) {
$user = $request->getUser();
$plugins = $this->getEnabledPlugins();
foreach ($plugins as $plugin) {
@ -110,8 +82,8 @@ final class DarkConsoleCore {
$plugin->setData($plugin->generateData());
}
$selected = 'XHProf';//true;//$this->getConsoleSetting(DarkConsoleCore::SETTING_TAB);
$visible = true;//$this->getConsoleSetting(DarkConsoleCore::SETTING_VISIBLE);
$selected = $user->getConsoleTab();
$visible = $user->getConsoleVisible();
if (!isset($plugins[$selected])) {
$selected = key($plugins);
@ -142,9 +114,7 @@ final class DarkConsoleCore {
array(
'class' => "dark-console-tab {$tabclass}",
'sigil' => 'dark-console-tab',
'meta' => array(
'key' => $key,
),
'id' => 'dark-console-tab-'.$key,
),
(string)$data['name']);
@ -154,9 +124,6 @@ final class DarkConsoleCore {
'class' => 'dark-console-panel',
'style' => $style,
'sigil' => 'dark-console-panel',
'meta' => array(
'key' => $key,
),
),
(string)$data['panel']);
}
@ -166,10 +133,7 @@ final class DarkConsoleCore {
array(
'class' => 'dark-console',
'sigil' => 'dark-console',
'meta' => array(
'visible' => true,
),
'style' => '',
'style' => $visible ? '' : 'display: none;',
),
'<tr>'.
'<th class="dark-console-tabs">'.
@ -178,7 +142,12 @@ final class DarkConsoleCore {
'<td>'.implode("\n", $panel_markup).'</td>'.
'</tr>');
Javelin::initBehavior('dark-console');
if (!empty($_COOKIE['phsid'])) {
$console = str_replace(
$_COOKIE['phsid'],
phutil_escape_html('<session-key>'),
$console);
}
return "\n\n\n\n".$console."\n\n\n\n";
}

View file

@ -6,9 +6,9 @@
phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'infrastructure/javelin/markup');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'symbols');
phutil_require_module('phutil', 'utils');

View file

@ -21,15 +21,12 @@ class DarkConsoleErrorLogPlugin extends DarkConsolePlugin {
public function getName() {
$count = count($this->getData());
/*
if ($count) {
return
<x:frag>
<span style="color: #ff0000;">&bull;</span> Error Log ({$count})
</x:frag>;
'<span style="color: #ff0000;">&bull;</span> '.
"Error Log ({$count})";
}
*/
return 'Error Log';
}
@ -40,36 +37,51 @@ class DarkConsoleErrorLogPlugin extends DarkConsolePlugin {
public function generateData() {
/*
$stub = tabconsole();
if (!$stub) {
return array();
}
$errors = $stub->getErrors();
$data = array();
foreach ($errors as $error) {
if (is_array($error)) {
list($err, $trace) = $error;
$trace = implode("\n", $trace);
} else {
$err = $error->getMessage();
$trace = $error->getTraceAsString();
}
$data[] = array(
'error' => $err,
'trace' => $trace,
);
}
return $data;
*/
return DarkConsoleErrorLogPluginAPI::getErrors();
}
public function render() {
return '!!';
$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;
}
$rows[] = array(
basename($file).':'.$line,
$row['str'],
);
}
$table = new AphrontTableView($rows);
$table->setColumnClasses(
array(
null,
'wide wrap',
));
$table->setHeaders(
array(
'File',
'Error',
));
$table->setNoDataString('No errors.');
return $table->render();
}
}
/*
$data = $this->getData();
if (!$data) {
@ -124,6 +136,3 @@ class DarkConsoleErrorLogPlugin extends DarkConsolePlugin {
<div class="LConsoleErrors">{$markup}</div>
</x:frag>;
*/
}
}

View file

@ -7,6 +7,8 @@
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_source('DarkConsoleErrorLogPlugin.php');

View file

@ -0,0 +1,48 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class DarkConsoleErrorLogPluginAPI {
private static $errors = array();
public static function getErrors() {
return self::$errors;
}
public static function handleError($num, $str, $file, $line, $cxt) {
self::$errors[] = array(
'event' => 'error',
'num' => $num,
'str' => $str,
'file' => $file,
'line' => $line,
'cxt' => $cxt,
'trace' => debug_backtrace(),
);
error_log("{$file}:{$line} {$str}");
}
public static function handleException($ex) {
self::$errors[] = array(
'event' => 'exception',
'exception' => $ex,
);
error_log($ex);
}
}

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('DarkConsoleErrorLogPluginAPI.php');

View file

@ -41,32 +41,36 @@ class DarkConsoleRequestPlugin extends DarkConsolePlugin {
'Basics' => array(
'Host' => $data['Server']['SERVER_ADDR'],
'Hostname' => gethostbyaddr($data['Server']['SERVER_ADDR']),
'Machine' => php_uname('n'),
),
);
$sections = array_merge($sections, $data);
/*
$out = <x:frag />;
$out = array();
foreach ($sections as $header => $map) {
$list = <table class="LConsoleRequestDict" />;
$rows = array();
foreach ($map as $key => $value) {
if (!is_scalar($value)) {
$value = fb_json_encode($value);
}
$value = <text wrap="80">{$value}</text>;
$list->appendChild(
<tr><th>{$key}</th><td>{$value}</td></tr>);
$rows[] = array(
phutil_escape_html($key),
phutil_escape_html($value),
);
}
$out->appendChild(
<x:frag>
<h1>{$header}</h1>
{$list}
</x:frag>);
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
$header,
null,
));
$table->setColumnClasses(
array(
'header',
'wide wrap',
));
$out[] = $table->render();
}
return $out;
*/
return "REQUEST";
return implode("\n", $out);
}
}

View file

@ -7,6 +7,9 @@
phutil_require_module('phabricator', 'aphront/console/plugin/base');
phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phutil', 'markup');
phutil_require_source('DarkConsoleRequestPlugin.php');

View file

@ -28,12 +28,53 @@ class DarkConsoleServicesPlugin extends DarkConsolePlugin {
return 'Information about services.';
}
public function willShutdown() {
// $this->observations = cacheobserver();
public function generateData() {
return DarkConsoleServicesPluginAPI::getEvents();
}
public function render() {
return '!';
$data = $this->getData();
$rows = array();
foreach ($data as $row) {
switch ($row['event']) {
case DarkConsoleServicesPluginAPI::EVENT_QUERY:
$info = $row['query'];
$info = phutil_escape_html($info);
break;
case DarkConsoleServicesPluginAPI::EVENT_CONNECT:
$info = $row['host'].':'.$row['database'];
$info = phutil_escape_html($info);
break;
default:
$info = '-';
break;
}
$rows[] = array(
$row['event'],
number_format(1000000 * ($row['end'] - $row['start'])).' us',
$info,
);
}
$table = new AphrontTableView($rows);
$table->setColumnClasses(
array(
null,
'n',
'wide wrap',
));
$table->setHeaders(
array(
'Event',
'Duration',
'Details',
));
return $table->render();
}
}

View file

@ -7,6 +7,10 @@
phutil_require_module('phabricator', 'aphront/console/plugin/base');
phutil_require_module('phabricator', 'aphront/console/plugin/services/api');
phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phutil', 'markup');
phutil_require_source('DarkConsoleServicesPlugin.php');

View file

@ -0,0 +1,35 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class DarkConsoleServicesPluginAPI {
const EVENT_QUERY = 'query';
const EVENT_CONNECT = 'connect';
private static $events = array();
public static function addEvent(array $event) {
self::$events[] = $event;
}
public static function getEvents() {
return self::$events;
}
}

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('DarkConsoleServicesPluginAPI.php');

View file

@ -130,6 +130,8 @@ class AphrontDefaultApplicationConfiguration
'/xhprof/' => array(
'profile/(?<phid>[^/]+)/$' => 'PhabricatorXHProfProfileController',
),
'/~/' => 'DarkConsoleController',
);
}

View file

@ -58,7 +58,7 @@ abstract class PhabricatorController extends AphrontController {
return $view;
}
public function buildStandardPageResponse($view) {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->appendChild($view);
$response = new AphrontWebpageResponse();

View file

@ -90,7 +90,8 @@ class DifferentialChangesetParser {
public function setFilename($filename) {
$this->filename = $filename;
if (strpos($filename, '.', 1) !== false) {
$this->filetype = end(explode('.', $filename));
$parts = explode('.', $filename);
$this->filetype = end($parts);
}
}

View file

@ -29,7 +29,9 @@ class PhabricatorUser extends PhabricatorUserDAO {
protected $facebookUID;
protected $profileImagePHID;
private $sessionKey;
protected $consoleEnabled = 0;
protected $consoleVisible = 0;
protected $consoleTab = '';
public function getProfileImagePHID() {
return nonempty(
@ -127,6 +129,8 @@ class PhabricatorUser extends PhabricatorUserDAO {
$session_type,
$session_key);
$this->sessionKey = $session_key;
return $session_key;
}

View file

@ -24,14 +24,14 @@ class AphrontMySQLDatabaseConnection extends AphrontDatabaseConnection {
private $config;
private $connection;
private static $connectionCache = array();
public function __construct(array $configuration) {
$this->configuration = $configuration;
}
public function escapeString($string) {
if (!$this->connection) {
$this->establishConnection();
}
$this->requireConnection();
return mysql_real_escape_string($string, $this->connection);
}
@ -92,6 +92,15 @@ class AphrontMySQLDatabaseConnection extends AphrontDatabaseConnection {
$user = $this->getConfiguration('user');
$host = $this->getConfiguration('host');
$database = $this->getConfiguration('database');
$key = "{$user}:{$host}:{$database}";
if (isset(self::$connectionCache[$key])) {
$this->connection = self::$connectionCache[$key];
return;
}
$start = microtime(true);
$conn = @mysql_connect(
$host,
@ -108,11 +117,23 @@ class AphrontMySQLDatabaseConnection extends AphrontDatabaseConnection {
"{$error}.");
}
$ret = @mysql_select_db($this->getConfiguration('database'), $conn);
$ret = @mysql_select_db($database, $conn);
if (!$ret) {
$this->throwQueryException($conn);
}
$end = microtime(true);
DarkConsoleServicesPluginAPI::addEvent(
array(
'event' => DarkConsoleServicesPluginAPI::EVENT_CONNECT,
'host' => $host,
'database' => $database,
'start' => $start,
'end' => $end,
));
self::$connectionCache[$key] = $conn;
$this->connection = $conn;
}
@ -152,11 +173,19 @@ class AphrontMySQLDatabaseConnection extends AphrontDatabaseConnection {
$retries = 3;
while ($retries--) {
try {
if (!$this->connection) {
$this->establishConnection();
}
$this->requireConnection();
$start = microtime(true);
$result = mysql_query($raw_query, $this->connection);
$end = microtime(true);
DarkConsoleServicesPluginAPI::addEvent(
array(
'event' => DarkConsoleServicesPluginAPI::EVENT_QUERY,
'query' => $raw_query,
'start' => $start,
'end' => $end,
));
if ($result) {
$this->lastResult = $result;

View file

@ -6,6 +6,7 @@
phutil_require_module('phabricator', 'aphront/console/plugin/services/api');
phutil_require_module('phabricator', 'storage/connection/base');
phutil_require_module('phabricator', 'storage/exception/base');
phutil_require_module('phabricator', 'storage/exception/connection');

View file

@ -16,6 +16,8 @@
* limitations under the License.
*/
error_reporting(E_ALL | E_STRICT);
$env = getenv('PHABRICATOR_ENV');
if (!$env) {
header('Content-Type: text/plain');
@ -37,6 +39,10 @@ PhabricatorEnv::setEnvConfig($conf);
phutil_require_module('phabricator', 'aphront/console/plugin/xhprof/api');
DarkConsoleXHProfPluginAPI::hookProfiler();
phutil_require_module('phabricator', 'aphront/console/plugin/errorlog/api');
set_error_handler(array('DarkConsoleErrorLogPluginAPI', 'handleError'));
set_exception_handler(array('DarkConsoleErrorLogPluginAPI', 'handleException'));
$host = $_SERVER['HTTP_HOST'];
$path = $_REQUEST['__path__'];
@ -91,7 +97,7 @@ foreach ($headers as $header) {
if (isset($_REQUEST['__profile__']) &&
($_REQUEST['__profile__'] == 'all')) {
$profile = DarkConsoleXHProfPluginAPI::stopProfiler();
$profile =
$profile =
'<div style="text-align: center; background: #ff00ff; padding: 1em;
font-size: 24px; font-weight: bold;">'.
'<a href="/xhprof/profile/'.$profile.'/">'.

View file

@ -44,3 +44,29 @@ a.dark-console-tab-selected {
}
.dark-console .aphront-table-view {
background: #888888;
color: #eeeeee;
margin: 1em 1%;
width: 98%;
border-color: #333333;
}
.dark-console .aphront-table-view th {
background: #333333;
color: #ffffff;
}
.dark-console .aphront-table-view td.header {
background: #444444;
color: #ffffff;
min-width: 200px;
}
.dark-console .aphront-table-view tr.alt {
background: #666666;
}
.dark-console .aphront-table-view tr.no-data td {
color: #dddddd;
}

View file

@ -70,6 +70,11 @@
text-align: right;
}
.aprhont-table-view td.wrap {
white-space: normal;
}
.aphront-table-view tr.no-data td {
padding: 1em;
text-align: center;

View file

@ -2,7 +2,7 @@
* @provides javelin-behavior-dark-console
*/
JX.behavior('dark-console', function() {
JX.behavior('dark-console', function(config) {
JX.Stratcom.listen(
'click',
['dark-console', 'dark-console-tab'],
@ -18,11 +18,10 @@ JX.behavior('dark-console', function() {
tabs[ii] == target);
(tabs[ii] != target ? JX.DOM.hide : JX.DOM.show)(panels[ii]);
}
/*
new JX.Request(e.getNodeData('dark-console').uri, JX.bag)
.setData({tab: e.getNodeData('dark-console-tab').key})
new JX.Request(config.uri, JX.bag)
.setData({tab: target.id.replace('dark-console-tab-', '')})
.send();
*/
});
JX.Stratcom.listen(
@ -39,17 +38,17 @@ JX.behavior('dark-console', function() {
}
var console = JX.DOM.find(document.body, 'table', 'dark-console');
var data = JX.Stratcom.getData(console);
data.visible = !data.visible;
if (data.visible) {
config.visible = !config.visible;
if (config.visible) {
JX.DOM.show(console);
} else {
JX.DOM.hide(console);
}
// new JX.Request(data.uri, JX.bag)
// .setData({visible: data.visible})
// .send();
new JX.Request(config.uri, JX.bag)
.setData({visible: config.visible ? 1 : 0})
.send();
}
});
});