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

Side by Side Diff: runtime/observatory/lib/src/elements/logging.dart

Issue 1250853006: Logging page (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library logging_page;
6
7 import 'dart:async';
8 import 'dart:html';
9 import 'observatory_element.dart';
10 import 'package:logging/logging.dart';
11 import 'package:observatory/service.dart';
12 import 'package:observatory/app.dart';
13 import 'package:observatory/elements.dart';
14 import 'package:observatory/utils.dart';
15 import 'package:polymer/polymer.dart';
16
17 @CustomTag('logging-page')
18 class LoggingPageElement extends ObservatoryElement {
19 static const _kPageSelector = '#page';
20 static const _kLogSelector = '#log';
21 static const _kSeverityLevelSelector = '#severityLevelSelector';
22
23 LoggingPageElement.created() : super.created();
24
25 domReady() {
26 super.domReady();
27 _insertLevels();
28 }
29
30 attached() {
31 super.attached();
32 _sub();
33 _resizeSubscription = window.onResize.listen((_) => _updatePageHeight());
34 _updatePageHeight();
35 // Turn on the periodic poll timer for this page.
36 pollPeriod = const Duration(milliseconds:100);
37 }
38
39 detached() {
40 super.detached();
41 if (_resizeSubscription != null) {
42 _resizeSubscription.cancel();
43 _resizeSubscription = null;
44 }
45 _unsub();
46 }
47
48 void onPoll() {
49 _flushPendingLogs();
50 }
51
52 _updatePageHeight() {
53 HtmlElement e = shadowRoot.querySelector(_kPageSelector);
54 final totalHeight = window.innerHeight;
55 final top = e.offset.top;
56 final bottomMargin = 32;
57 final mainHeight = totalHeight - top - bottomMargin;
58 e.style.setProperty('height', '${mainHeight}px');
59 }
60
61 _insertLevels() {
62 SelectElement severityLevelSelector =
63 shadowRoot.querySelector(_kSeverityLevelSelector);
64 severityLevelSelector.children.clear();
65 _maxLevelLabelLength = 0;
66 for (var level in Level.LEVELS) {
67 var option = new OptionElement();
68 option.value = level.value.toString();
69 option.label = level.name;
70 if (level.name.length > _maxLevelLabelLength) {
71 _maxLevelLabelLength = level.name.length;
72 }
73 severityLevelSelector.children.add(option);
74 }
75 severityLevelSelector.selectedIndex = 0;
76 severityLevel = Level.ALL.value.toString();
77 }
78
79 _reset() {
80 logRecords.clear();
81 _unsub();
82 _sub();
83 _renderFull();
84 }
85
86 _unsub() {
87 cancelFutureSubscription(_loggingSubscriptionFuture);
88 _loggingSubscriptionFuture = null;
89 }
90
91 _sub() {
92 if (_loggingSubscriptionFuture != null) {
93 // Already subscribed.
94 return;
95 }
96 _loggingSubscriptionFuture =
97 app.vm.listenEventStream(Isolate.kLoggingStream, _onEvent);
98 }
99
100 _append(Map logRecord) {
101 logRecords.add(logRecord);
102 if (_shouldDisplay(logRecord)) {
103 // Queue for display.
104 pendingLogRecords.add(logRecord);
105 }
106 }
107
108 Element _renderAppend(Map logRecord) {
109 DivElement logContainer = shadowRoot.querySelector(_kLogSelector);
110 var element = new DivElement();
111 element.classes.add('logItem');
112 element.classes.add(logRecord['level'].name);
113 element.appendText(
114 '${logRecord["level"].name.padLeft(_maxLevelLabelLength)} '
115 '${Utils.formatDateTime(logRecord["time"])} '
116 '${logRecord["message"].valueAsString}\n');
117 logContainer.children.add(element);
118 return element;
119 }
120
121 _renderFull() {
122 DivElement logContainer = shadowRoot.querySelector(_kLogSelector);
123 logContainer.children.clear();
124 pendingLogRecords.clear();
125 for (var logRecord in logRecords) {
126 if (_shouldDisplay(logRecord)) {
127 _renderAppend(logRecord);
128 }
129 }
130 _scrollToBottom(logContainer);
131 }
132
133 /// Is [container] scrolled to the within [threshold] pixels of the bottom?
134 static bool _isScrolledToBottom(DivElement container, [int threshold = 2]) {
135 if (container == null) {
136 return false;
137 }
138 // scrollHeight -> complete height of element including scrollable area.
139 // clientHeight -> height of element on page.
140 // scrollTop -> how far is an element scrolled (from 0 to scrollHeight).
141 final distanceFromBottom =
142 container.scrollHeight - container.clientHeight - container.scrollTop;
143 const threshold = 2; // 2 pixel slop.
144 return distanceFromBottom <= threshold;
145 }
146
147 /// Scroll [container] so the bottom content is visible.
148 static _scrollToBottom(DivElement container) {
149 if (container == null) {
150 return;
151 }
152 // Adjust scroll so that the bottom of the content is visible.
153 container.scrollTop = container.scrollHeight - container.clientHeight;
154 }
155
156 _flushPendingLogs() {
157 DivElement logContainer = shadowRoot.querySelector(_kLogSelector);
158 bool autoScroll = _isScrolledToBottom(logContainer);
159 var lastElement;
160 for (var logRecord in pendingLogRecords) {
161 lastElement = _renderAppend(logRecord);
162 }
163 if (autoScroll) {
164 _scrollToBottom(logContainer);
165 }
166 pendingLogRecords.clear();
167 }
168
169 _onEvent(ServiceEvent event) {
170 assert(event.kind == Isolate.kLoggingStream);
171 _append(event.logRecord);
172 }
173
174 void isolateChanged(oldValue) {
175 _reset();
176 }
177
178 void severityLevelChanged(oldValue) {
179 _severityLevelValue = int.parse(severityLevel);
180 _renderFull();
181 }
182
183 Future clear() {
184 logRecords.clear();
185 pendingLogRecords.clear();
186 _renderFull();
187 return new Future.value(null);
188 }
189
190 bool _shouldDisplay(Map logRecord) {
191 return logRecord['level'].value >= _severityLevelValue;
192 }
193
194 @observable Isolate isolate;
195 @observable String severityLevel;
196 int _severityLevelValue = 0;
197 int _maxLevelLabelLength = 0;
198 Future<StreamSubscription> _loggingSubscriptionFuture;
199 StreamSubscription _resizeSubscription;
200 final List<Map> logRecords = new List<Map>();
201 final List<Map> pendingLogRecords = new List<Map>();
202 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/src/elements/isolate_summary.html ('k') | runtime/observatory/lib/src/elements/logging.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698