Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1097)

Unified Diff: pkg/analysis_server/tool/instrumentation/page/page_writer.dart

Issue 2338883003: Add a tool for viewing instrumentation logs (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analysis_server/tool/instrumentation/page/page_writer.dart
diff --git a/pkg/analysis_server/tool/instrumentation/page/page_writer.dart b/pkg/analysis_server/tool/instrumentation/page/page_writer.dart
new file mode 100644
index 0000000000000000000000000000000000000000..492f86ac328dbcd2911f309c253a98e0865318a8
--- /dev/null
+++ b/pkg/analysis_server/tool/instrumentation/page/page_writer.dart
@@ -0,0 +1,307 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+
+import '../log/log.dart';
+import '../server.dart';
+
+typedef void Writer(StringSink sink);
+
+/**
+ * A class used to write an HTML page.
+ */
+abstract class PageWriter {
+ /**
+ * The object used to escape special HTML characters.
+ */
+ static final HtmlEscape htmlEscape = new HtmlEscape();
+
+ /**
+ * Initialize a newly create page writer.
+ */
+ PageWriter();
+
+ /**
+ * Return the length of the common prefix for time stamps associated with the
+ * given log [entries].
+ */
+ int computePrefixLength(List<LogEntry> entries) {
+ int length = entries.length;
+ if (length < 2) {
+ return 0;
+ }
+ String firstTime = entries[0].timeStamp.toString();
+ String lastTime = entries[length - 1].timeStamp.toString();
+ int prefixLength = 0;
+ int timeLength = firstTime.length;
+ while (prefixLength < timeLength &&
+ firstTime.codeUnitAt(prefixLength) ==
+ lastTime.codeUnitAt(prefixLength)) {
+ prefixLength++;
+ }
+ return prefixLength;
+ }
+
+ /**
+ * Return an escaped version of the given [unsafe] text.
+ */
+ String escape(String unsafe) {
+ return htmlEscape.convert(unsafe);
+ }
+
+ /**
+ * Write the body of the page (without the 'body' tag) to the given [sink].
+ */
+ void writeBody(StringSink sink);
+
+ /**
+ * Write the given [date] to the given [sink].
+ */
+ void writeDate(StringSink sink, DateTime date) {
+ String isoString = date.toIso8601String();
+ int index = isoString.indexOf('T');
+ String dateString = isoString.substring(0, index);
+ String timeString = isoString.substring(index + 1);
+ sink.write(dateString);
+ sink.write(' at ');
+ sink.write(timeString);
+ }
+
+ /**
+ * Write the body of the page (without the 'body' tag) to the given [sink].
+ */
+ void writeMenu(StringSink sink) {
+ sink.writeln('<div class="menu">');
+ sink.write('<a href="${WebServer.logPath}" class="menuItem">Log</a>');
+ sink.write('&nbsp;&bullet;&nbsp;');
+ sink.write('<a href="${WebServer.statsPath}" class="menuItem">Stats</a>');
+ sink.writeln('</div>');
+ }
+
+ /**
+ * Write the contents of the instrumentation log to the given [sink].
+ */
+ void writePage(StringSink sink) {
+ sink.writeln('<!DOCTYPE html>');
+ sink.writeln('<html lang="en-US">');
+ sink.writeln('<head>');
+ sink.writeln('<meta charset="utf-8">');
+ sink.writeln(
+ '<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0">');
+ sink.writeln('<title>Instrumentation Log</title>');
+ sink.writeln('<style>');
+ writeStyleSheet(sink);
+ sink.writeln('</style>');
+ sink.writeln('<script>');
+ writeScripts(sink);
+ sink.writeln('</script>');
+ sink.writeln('</head>');
+ sink.writeln('<body>');
+ writeBody(sink);
+ sink.writeln('</body>');
+ sink.writeln('</html>');
+ }
+
+ /**
+ * Write the scripts for the page (without the 'script' tag) to the given
+ * [sink].
+ */
+ void writeScripts(StringSink sink) {
+ // No common scripts.
+ }
+
+ /**
+ * Write the content of the style sheet (without the 'script' tag) for the
+ * page to the given [sink].
+ */
+ void writeStyleSheet(StringSink sink) {
+ sink.writeln('a {');
+ sink.writeln(' color: #000000;');
+ sink.writeln(' text-decoration: none;');
+ sink.writeln('}');
+ sink.writeln('a.menuItem {');
+ sink.writeln(' font-weight: bold;');
+ sink.writeln('}');
+ sink.writeln('body {');
+ sink.writeln(' font-family: sans-serif;');
+ sink.writeln(' height: 100%;');
+ sink.writeln(' margin: 0px;');
+ sink.writeln(' overflow: hidden;');
+ sink.writeln(' padding: 0px;');
+ sink.writeln(' width: 100%;');
+ sink.writeln('}');
+ sink.writeln('div.columnHeader {');
+ sink.writeln('}');
+ sink.writeln('div.button {');
+ sink.writeln(' display: inline-block;');
+ sink.writeln(' border-radius: 4px;');
+ sink.writeln(' border: 1px solid;');
+ sink.writeln(' height: 16px;');
+ sink.writeln(' text-align: center;');
+ sink.writeln(' vertical-align: middle;');
+ sink.writeln(' width: 16px;');
+ sink.writeln('}');
+ sink.writeln('div.inset {');
+ sink.writeln(' padding: 10px;');
+ sink.writeln('}');
+ sink.writeln('div.menu {');
+ sink.writeln(' background-color: #cce6ff;');
+ sink.writeln(' padding: 5px;');
+ sink.writeln('}');
+ sink.writeln('html {');
+ sink.writeln(' height: 100%;');
+ sink.writeln(' width: 100%;');
+ sink.writeln('}');
+ sink.writeln('span.button {');
+ sink.writeln(' border-radius: 5px;');
+ sink.writeln(' border: 1px solid;');
+ sink.writeln(' height: 16px;');
+ sink.writeln(' width: 16px;');
+ sink.writeln('}');
+ sink.writeln('span.error {');
+ sink.writeln(' color: #ff0000;');
+ sink.writeln('}');
+ sink.writeln('span.gray {');
+ sink.writeln(' color: #777777;');
+ sink.writeln('}');
+ sink.writeln('span.label {');
+ sink.writeln(' font-weight: bold;');
+ sink.writeln('}');
+ sink.writeln('table.fullWidth {');
+ sink.writeln(' border: 0px;');
+ sink.writeln(' width: 100%;');
+ sink.writeln('}');
+ sink.writeln('td.halfWidth {');
+ sink.writeln(' width: 50%;');
+ sink.writeln(' vertical-align: top;');
+ sink.writeln('}');
+ sink.writeln('td.int {');
+ sink.writeln(' text-align: right;');
+ sink.writeln('}');
+ sink.writeln('th {');
+ sink.writeln(' text-align: left;');
+ sink.writeln('}');
+ sink.writeln('th.narrow {');
+ sink.writeln(' width: 16px;');
+ sink.writeln('}');
+
+ sink.writeln('#container {');
+ sink.writeln(' height: 100%;');
+ sink.writeln(' min-height: 100%;');
+ sink.writeln(' position: relative;');
+ sink.writeln(' width: 100%;');
+ sink.writeln('}');
+ sink.writeln('#content {');
+ sink.writeln(' height: 90%;');
+ sink.writeln(' width: 100%;');
+ sink.writeln('}');
+ }
+
+ /**
+ * Write to the given [sink] the HTML required to display content in two
+ * columns. The content of the columns will be written by the functions
+ * [writeLeftColumn], [writeCenterColumn] and [writeRightColumn] and will be
+ * contained in 'div' elements with the id's [leftColumnId], [centerColumnId]
+ * and [rightColumnId].
+ */
+ void writeThreeColumns(
+ StringSink sink,
+ String leftColumnId,
+ Writer writeLeftColumn,
+ String centerColumnId,
+ Writer writeCenterColumn,
+ String rightColumnId,
+ Writer writeRightColumn) {
+ sink.writeln('<div>');
+ sink.writeln(' <div>');
+ sink.writeln(' <div id="$leftColumnId">');
+ sink.writeln(' <div class="inset">');
+ writeLeftColumn(sink);
+ sink.writeln(' </div>');
+ sink.writeln(' </div>');
+ sink.writeln(' <div id="$rightColumnId">');
+ sink.writeln(' <div class="inset">');
+ writeRightColumn(sink);
+ sink.writeln(' </div>');
+ sink.writeln(' </div>');
+ sink.writeln(' <div id="$centerColumnId">');
+ sink.writeln(' <div class="inset">');
+ writeCenterColumn(sink);
+ sink.writeln(' </div>');
+ sink.writeln(' </div>');
+ sink.writeln(' </div>');
+ sink.writeln('</div>');
+ }
+
+ /**
+ * Writeto the given [sink] the styles needed by a three column section where
+ * the columns have the ids [leftColumnId], [centerColumnId] and
+ * [rightColumnId].
+ */
+ void writeThreeColumnStyles(StringSink sink, String leftColumnId,
+ String centerColumnId, String rightColumnId) {
+ sink.writeln('#$leftColumnId {');
+ sink.writeln(' float: left;');
+ sink.writeln(' height: 100%;');
+ sink.writeln(' overflow: auto;');
+ sink.writeln(' width: 33%;');
+ sink.writeln('}');
+ sink.writeln('#$centerColumnId {');
+ sink.writeln(' height: 100%;');
+ sink.writeln(' overflow: auto;');
+ sink.writeln(' width: 33%;');
+ sink.writeln('}');
+ sink.writeln('#$rightColumnId {');
+ sink.writeln(' float: right;');
+ sink.writeln(' height: 100%;');
+ sink.writeln(' overflow: auto;');
+ sink.writeln(' width: 33%;');
+ sink.writeln('}');
+ }
+
+ /**
+ * Write to the given [sink] the HTML required to display content in two
+ * columns. The content of the columns will be written by the functions
+ * [writeLeftColumn] and [writeRightColumn] and will be contained in 'div'
+ * elements with the id's [leftColumnId] and [rightColumnId].
+ */
+ void writeTwoColumns(StringSink sink, String leftColumnId,
+ Writer writeLeftColumn, String rightColumnId, Writer writeRightColumn) {
+ sink.writeln('<div>');
+ sink.writeln(' <div>');
+ sink.writeln(' <div id="$leftColumnId">');
+ sink.writeln(' <div class="inset">');
+ writeLeftColumn(sink);
+ sink.writeln(' </div>');
+ sink.writeln(' </div>');
+ sink.writeln(' <div id="$rightColumnId">');
+ sink.writeln(' <div class="inset">');
+ writeRightColumn(sink);
+ sink.writeln(' </div>');
+ sink.writeln(' </div>');
+ sink.writeln(' </div>');
+ sink.writeln('</div>');
+ }
+
+ /**
+ * Writeto the given [sink] the styles needed by a two column section where
+ * the columns have the ids [leftColumnId] and [rightColumnId].
+ */
+ void writeTwoColumnStyles(
+ StringSink sink, String leftColumnId, String rightColumnId) {
+ sink.writeln('#$leftColumnId {');
+ sink.writeln(' float: left;');
+ sink.writeln(' height: 100%;');
+ sink.writeln(' overflow: auto;');
+ sink.writeln(' width: 50%;');
+ sink.writeln('}');
+ sink.writeln('#$rightColumnId {');
+ sink.writeln(' float: right;');
+ sink.writeln(' height: 100%;');
+ sink.writeln(' overflow: auto;');
+ sink.writeln(' width: 50%;');
+ sink.writeln('}');
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698