From 36c13592306ce5e32e9167e8ec7ae654d3b2db5d Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 23 Jul 2013 12:30:58 -0700 Subject: [PATCH] Allow long daemon log messages to be expanded Summary: Ref T3557. We summarize long messages, but don't let you see the entire message. This is occasionally inconvenient, and I'm planning to add more prefix junk to some messages for T2569. Provide a link you can click to see the full message. This isn't javascripted because a ton of these can make the page ridiculously enormous and it seems unlikely you'd care much about all of them. Test Plan: {F51261} {F51262} Reviewers: btrahan Reviewed By: btrahan CC: aran, chad Maniphest Tasks: T3557 Differential Revision: https://secure.phabricator.com/D6546 --- src/__celerity_resource_map__.php | 90 +++++++++---------- src/__phutil_library_map__.php | 2 + .../PhabricatorApplicationDaemons.php | 1 + ...habricatorDaemonLogEventViewController.php | 52 +++++++++++ .../PhabricatorDaemonLogViewController.php | 5 +- .../query/PhabricatorDaemonLogQuery.php | 13 +++ .../view/PhabricatorDaemonLogEventsView.php | 79 ++++++++++------ webroot/rsrc/css/aphront/table-view.css | 6 ++ 8 files changed, 175 insertions(+), 73 deletions(-) create mode 100644 src/applications/daemon/controller/PhabricatorDaemonLogEventViewController.php diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index be5197b76e..fd96f6e7fa 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -917,7 +917,7 @@ celerity_register_resource_map(array( ), 'aphront-table-view-css' => array( - 'uri' => '/res/d3c44c69/rsrc/css/aphront/table-view.css', + 'uri' => '/res/be5ca6be/rsrc/css/aphront/table-view.css', 'type' => 'css', 'requires' => array( @@ -4182,7 +4182,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - '72b33589' => + '570cc49c' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -4230,7 +4230,7 @@ celerity_register_resource_map(array( 40 => 'phabricator-property-list-view-css', 41 => 'phabricator-tag-view-css', ), - 'uri' => '/res/pkg/72b33589/core.pkg.css', + 'uri' => '/res/pkg/570cc49c/core.pkg.css', 'type' => 'css', ), '75ccea43' => @@ -4421,16 +4421,16 @@ celerity_register_resource_map(array( ), 'reverse' => array( - 'aphront-dialog-view-css' => '72b33589', - 'aphront-error-view-css' => '72b33589', - 'aphront-form-view-css' => '72b33589', - 'aphront-list-filter-view-css' => '72b33589', - 'aphront-pager-view-css' => '72b33589', - 'aphront-panel-view-css' => '72b33589', - 'aphront-table-view-css' => '72b33589', - 'aphront-tokenizer-control-css' => '72b33589', - 'aphront-tooltip-css' => '72b33589', - 'aphront-typeahead-control-css' => '72b33589', + 'aphront-dialog-view-css' => '570cc49c', + 'aphront-error-view-css' => '570cc49c', + 'aphront-form-view-css' => '570cc49c', + 'aphront-list-filter-view-css' => '570cc49c', + 'aphront-pager-view-css' => '570cc49c', + 'aphront-panel-view-css' => '570cc49c', + 'aphront-table-view-css' => '570cc49c', + 'aphront-tokenizer-control-css' => '570cc49c', + 'aphront-tooltip-css' => '570cc49c', + 'aphront-typeahead-control-css' => '570cc49c', 'differential-changeset-view-css' => 'dd27a69b', 'differential-core-view-css' => 'dd27a69b', 'differential-inline-comment-editor' => '48040be9', @@ -4444,7 +4444,7 @@ celerity_register_resource_map(array( 'differential-table-of-contents-css' => 'dd27a69b', 'diffusion-commit-view-css' => 'c8ce2d88', 'diffusion-icons-css' => 'c8ce2d88', - 'global-drag-and-drop-css' => '72b33589', + 'global-drag-and-drop-css' => '570cc49c', 'inline-comment-summary-css' => 'dd27a69b', 'javelin-aphlict' => '75ccea43', 'javelin-behavior' => 'a9f14d76', @@ -4517,55 +4517,55 @@ celerity_register_resource_map(array( 'javelin-util' => 'a9f14d76', 'javelin-vector' => 'a9f14d76', 'javelin-workflow' => 'a9f14d76', - 'lightbox-attachment-css' => '72b33589', + 'lightbox-attachment-css' => '570cc49c', 'maniphest-task-summary-css' => '06bacb9a', 'maniphest-transaction-detail-css' => '06bacb9a', - 'phabricator-action-list-view-css' => '72b33589', - 'phabricator-application-launch-view-css' => '72b33589', + 'phabricator-action-list-view-css' => '570cc49c', + 'phabricator-application-launch-view-css' => '570cc49c', 'phabricator-busy' => '75ccea43', 'phabricator-content-source-view-css' => 'dd27a69b', - 'phabricator-core-css' => '72b33589', - 'phabricator-crumbs-view-css' => '72b33589', + 'phabricator-core-css' => '570cc49c', + 'phabricator-crumbs-view-css' => '570cc49c', 'phabricator-drag-and-drop-file-upload' => '48040be9', 'phabricator-dropdown-menu' => '75ccea43', 'phabricator-file-upload' => '75ccea43', - 'phabricator-filetree-view-css' => '72b33589', - 'phabricator-flag-css' => '72b33589', - 'phabricator-form-view-css' => '72b33589', - 'phabricator-header-view-css' => '72b33589', + 'phabricator-filetree-view-css' => '570cc49c', + 'phabricator-flag-css' => '570cc49c', + 'phabricator-form-view-css' => '570cc49c', + 'phabricator-header-view-css' => '570cc49c', 'phabricator-hovercard' => '75ccea43', - 'phabricator-jump-nav' => '72b33589', + 'phabricator-jump-nav' => '570cc49c', 'phabricator-keyboard-shortcut' => '75ccea43', 'phabricator-keyboard-shortcut-manager' => '75ccea43', - 'phabricator-main-menu-view' => '72b33589', + 'phabricator-main-menu-view' => '570cc49c', 'phabricator-menu-item' => '75ccea43', - 'phabricator-nav-view-css' => '72b33589', + 'phabricator-nav-view-css' => '570cc49c', 'phabricator-notification' => '75ccea43', - 'phabricator-notification-css' => '72b33589', - 'phabricator-notification-menu-css' => '72b33589', - 'phabricator-object-item-list-view-css' => '72b33589', + 'phabricator-notification-css' => '570cc49c', + 'phabricator-notification-menu-css' => '570cc49c', + 'phabricator-object-item-list-view-css' => '570cc49c', 'phabricator-object-selector-css' => 'dd27a69b', 'phabricator-phtize' => '75ccea43', 'phabricator-prefab' => '75ccea43', 'phabricator-project-tag-css' => '06bacb9a', - 'phabricator-property-list-view-css' => '72b33589', - 'phabricator-remarkup-css' => '72b33589', + 'phabricator-property-list-view-css' => '570cc49c', + 'phabricator-remarkup-css' => '570cc49c', 'phabricator-shaped-request' => '48040be9', - 'phabricator-side-menu-view-css' => '72b33589', - 'phabricator-standard-page-view' => '72b33589', - 'phabricator-tag-view-css' => '72b33589', + 'phabricator-side-menu-view-css' => '570cc49c', + 'phabricator-standard-page-view' => '570cc49c', + 'phabricator-tag-view-css' => '570cc49c', 'phabricator-textareautils' => '75ccea43', 'phabricator-tooltip' => '75ccea43', - 'phabricator-transaction-view-css' => '72b33589', - 'phabricator-zindex-css' => '72b33589', - 'phui-button-css' => '72b33589', - 'phui-form-css' => '72b33589', - 'phui-icon-view-css' => '72b33589', - 'phui-spacing-css' => '72b33589', - 'sprite-apps-large-css' => '72b33589', - 'sprite-gradient-css' => '72b33589', - 'sprite-icons-css' => '72b33589', - 'sprite-menu-css' => '72b33589', - 'syntax-highlighting-css' => '72b33589', + 'phabricator-transaction-view-css' => '570cc49c', + 'phabricator-zindex-css' => '570cc49c', + 'phui-button-css' => '570cc49c', + 'phui-form-css' => '570cc49c', + 'phui-icon-view-css' => '570cc49c', + 'phui-spacing-css' => '570cc49c', + 'sprite-apps-large-css' => '570cc49c', + 'sprite-gradient-css' => '570cc49c', + 'sprite-icons-css' => '570cc49c', + 'sprite-menu-css' => '570cc49c', + 'syntax-highlighting-css' => '570cc49c', ), )); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index f8af211340..1541cadd7c 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1023,6 +1023,7 @@ phutil_register_library_map(array( 'PhabricatorDaemonEventListener' => 'applications/daemon/event/PhabricatorDaemonEventListener.php', 'PhabricatorDaemonLog' => 'applications/daemon/storage/PhabricatorDaemonLog.php', 'PhabricatorDaemonLogEvent' => 'applications/daemon/storage/PhabricatorDaemonLogEvent.php', + 'PhabricatorDaemonLogEventViewController' => 'applications/daemon/controller/PhabricatorDaemonLogEventViewController.php', 'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/PhabricatorDaemonLogEventsView.php', 'PhabricatorDaemonLogListController' => 'applications/daemon/controller/PhabricatorDaemonLogListController.php', 'PhabricatorDaemonLogListView' => 'applications/daemon/view/PhabricatorDaemonLogListView.php', @@ -3029,6 +3030,7 @@ phutil_register_library_map(array( 1 => 'PhabricatorPolicyInterface', ), 'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO', + 'PhabricatorDaemonLogEventViewController' => 'PhabricatorDaemonController', 'PhabricatorDaemonLogEventsView' => 'AphrontView', 'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController', 'PhabricatorDaemonLogListView' => 'AphrontView', diff --git a/src/applications/daemon/application/PhabricatorApplicationDaemons.php b/src/applications/daemon/application/PhabricatorApplicationDaemons.php index 8180319f80..f6582ccfee 100644 --- a/src/applications/daemon/application/PhabricatorApplicationDaemons.php +++ b/src/applications/daemon/application/PhabricatorApplicationDaemons.php @@ -48,6 +48,7 @@ final class PhabricatorApplicationDaemons extends PhabricatorApplication { 'combined/' => 'PhabricatorDaemonCombinedLogController', '(?P[1-9]\d*)/' => 'PhabricatorDaemonLogViewController', ), + 'event/(?P[1-9]\d*)/' => 'PhabricatorDaemonLogEventViewController', ), ); } diff --git a/src/applications/daemon/controller/PhabricatorDaemonLogEventViewController.php b/src/applications/daemon/controller/PhabricatorDaemonLogEventViewController.php new file mode 100644 index 0000000000..a57b41c483 --- /dev/null +++ b/src/applications/daemon/controller/PhabricatorDaemonLogEventViewController.php @@ -0,0 +1,52 @@ +id = $data['id']; + } + + public function processRequest() { + $request = $this->getRequest(); + + $event = id(new PhabricatorDaemonLogEvent())->load($this->id); + if (!$event) { + return new Aphront404Response(); + } + + $event_view = id(new PhabricatorDaemonLogEventsView()) + ->setEvents(array($event)) + ->setUser($request->getUser()) + ->setCombinedLog(true) + ->setShowFullMessage(true); + + $log_panel = new AphrontPanelView(); + $log_panel->appendChild($event_view); + $log_panel->setNoBackground(); + + $daemon_id = $event->getLogID(); + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addCrumb( + id(new PhabricatorCrumbView()) + ->setName(pht('Daemon %s', $daemon_id)) + ->setHref($this->getApplicationURI("log/{$daemon_id}/"))); + $crumbs->addCrumb( + id(new PhabricatorCrumbView()) + ->setName(pht('Event %s', $event->getID()))); + + + return $this->buildApplicationPage( + array( + $crumbs, + $log_panel, + ), + array( + 'title' => pht('Combined Daemon Log'), + )); + } + +} diff --git a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php index e62471357c..f0230df87d 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonLogViewController.php @@ -13,7 +13,10 @@ final class PhabricatorDaemonLogViewController $request = $this->getRequest(); $user = $request->getUser(); - $log = id(new PhabricatorDaemonLog())->load($this->id); + $log = id(new PhabricatorDaemonLogQuery()) + ->setViewer($user) + ->withIDs(array($this->id)) + ->executeOne(); if (!$log) { return new Aphront404Response(); } diff --git a/src/applications/daemon/query/PhabricatorDaemonLogQuery.php b/src/applications/daemon/query/PhabricatorDaemonLogQuery.php index 5f47eb5a92..bb00f9ff85 100644 --- a/src/applications/daemon/query/PhabricatorDaemonLogQuery.php +++ b/src/applications/daemon/query/PhabricatorDaemonLogQuery.php @@ -6,6 +6,7 @@ final class PhabricatorDaemonLogQuery const STATUS_ALL = 'status-all'; const STATUS_ALIVE = 'status-alive'; + private $ids; private $status = self::STATUS_ALL; public static function getTimeUntilUnknown() { @@ -16,6 +17,11 @@ final class PhabricatorDaemonLogQuery return 30 * PhutilDaemonOverseer::HEARTBEAT_WAIT; } + public function withIDs(array $ids) { + $this->ids = $ids; + return $this; + } + public function withStatus($status) { $this->status = $status; return $this; @@ -89,6 +95,13 @@ final class PhabricatorDaemonLogQuery private function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); + if ($this->ids) { + $where[] = qsprintf( + $conn_r, + 'id IN (%Ld)', + $this->ids); + } + if ($this->getStatusConstants()) { $where[] = qsprintf( $conn_r, diff --git a/src/applications/daemon/view/PhabricatorDaemonLogEventsView.php b/src/applications/daemon/view/PhabricatorDaemonLogEventsView.php index 600dc50e14..bb7c288aab 100644 --- a/src/applications/daemon/view/PhabricatorDaemonLogEventsView.php +++ b/src/applications/daemon/view/PhabricatorDaemonLogEventsView.php @@ -4,6 +4,13 @@ final class PhabricatorDaemonLogEventsView extends AphrontView { private $events; private $combinedLog; + private $showFullMessage; + + + public function setShowFullMessage($show_full_message) { + $this->showFullMessage = $show_full_message; + return $this; + } public function setEvents(array $events) { assert_instances_of($events, 'PhabricatorDaemonLogEvent'); @@ -31,39 +38,57 @@ final class PhabricatorDaemonLogEventsView extends AphrontView { // truncation if that doesn't get things short enough. $message = $event->getMessage(); - - $more_lines = null; - $more_chars = null; - $line_limit = 12; - if (substr_count($message, "\n") > $line_limit) { - $message = explode("\n", $message); - $more_lines = count($message) - $line_limit; - $message = array_slice($message, 0, $line_limit); - $message = implode("\n", $message); - } - - $char_limit = 8192; - if (strlen($message) > $char_limit) { - $message = phutil_utf8v($message); - $more_chars = count($message) - $char_limit; - $message = array_slice($message, 0, $char_limit); - $message = implode('', $message); - } - $more = null; - if ($more_chars) { - $more = number_format($more_chars); - $more = "\n<... {$more} more characters ...>"; - } else if ($more_lines) { - $more = number_format($more_lines); - $more = "\n<... {$more} more lines ...>"; + + if (!$this->showFullMessage) { + $more_lines = null; + $more_chars = null; + $line_limit = 12; + if (substr_count($message, "\n") > $line_limit) { + $message = explode("\n", $message); + $more_lines = count($message) - $line_limit; + $message = array_slice($message, 0, $line_limit); + $message = implode("\n", $message); + } + + $char_limit = 8192; + if (strlen($message) > $char_limit) { + $message = phutil_utf8v($message); + $more_chars = count($message) - $char_limit; + $message = array_slice($message, 0, $char_limit); + $message = implode('', $message); + } + + if ($more_chars) { + $more = new PhutilNumber($more_chars); + $more = pht("Show %d more character(s)...", $more); + } else if ($more_lines) { + $more = new PhutilNumber($more_lines); + $more = pht("Show %d more line(s)...", $more); + } + + if ($more) { + $id = $event->getID(); + $more = array( + "\n...\n", + phutil_tag( + 'a', + array( + 'href' => "/daemon/event/{$id}/", + ), + $more), + ); + } } $row = array( $event->getLogType(), phabricator_date($event->getEpoch(), $this->user), phabricator_time($event->getEpoch(), $this->user), - phutil_escape_html_newlines($message.$more), + array( + $message, + $more, + ), ); if ($this->combinedLog) { @@ -84,7 +109,7 @@ final class PhabricatorDaemonLogEventsView extends AphrontView { '', '', 'right', - 'wide wrap', + 'wide prewrap', ); $headers = array( diff --git a/webroot/rsrc/css/aphront/table-view.css b/webroot/rsrc/css/aphront/table-view.css index d6d12fc26c..592467c697 100644 --- a/webroot/rsrc/css/aphront/table-view.css +++ b/webroot/rsrc/css/aphront/table-view.css @@ -168,6 +168,12 @@ th.aphront-table-view-sortable-selected { white-space: normal; } +.aphront-table-view td.prewrap { + font-family: "Monaco", monospace; + font-size: 11px; + white-space: pre-wrap; +} + .aphront-table-view td.narrow { width: 1px; }