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

Unified Diff: runtime/bin/vmservice/observatory/lib/src/service/object.dart

Issue 457803002: Initial UI for Metrics in Observatory (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 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: runtime/bin/vmservice/observatory/lib/src/service/object.dart
diff --git a/runtime/bin/vmservice/observatory/lib/src/service/object.dart b/runtime/bin/vmservice/observatory/lib/src/service/object.dart
index d1bad5f5cfbba99a9d9af8b62ad71f2831d6c61f..bc57bb6647b0587397739c14a0ecced4c2a44ed5 100644
--- a/runtime/bin/vmservice/observatory/lib/src/service/object.dart
+++ b/runtime/bin/vmservice/observatory/lib/src/service/object.dart
@@ -76,12 +76,18 @@ abstract class ServiceObject extends Observable {
case 'Code':
obj = new Code._empty(owner);
break;
+ case 'Counter':
+ obj = new ServiceMetric._empty(owner);
+ break;
case 'Error':
obj = new DartError._empty(owner);
break;
case 'Function':
obj = new ServiceFunction._empty(owner);
break;
+ case 'Gauge':
+ obj = new ServiceMetric._empty(owner);
+ break;
case 'Isolate':
obj = new Isolate._empty(owner.vm);
break;
@@ -701,6 +707,7 @@ class Isolate extends ServiceObjectOwner with Coverage {
String id = map['id'];
var obj = _cache[id];
if (obj != null) {
+ // Consider calling update when map is not a reference.
return obj;
}
// Build the object from the map directly.
@@ -1013,7 +1020,6 @@ class Isolate extends ServiceObjectOwner with Coverage {
}
Future stepInto() {
- print('isolate.stepInto');
return get("debug/resume?step=into").then((result) {
if (result is DartError) {
// TODO(turnidge): Handle this more gracefully.
@@ -1043,6 +1049,44 @@ class Isolate extends ServiceObjectOwner with Coverage {
});
}
+ final ObservableMap<String, ServiceMetric> dartMetrics =
+ new ObservableMap<String, ServiceMetric>();
+
+ final ObservableMap<String, ServiceMetric> vmMetrics =
+ new ObservableMap<String, ServiceMetric>();
+
+ Future<ObservableMap<String, ServiceMetric>> _refreshMetrics(
+ String id,
+ ObservableMap<String, ServiceMetric> metricsMap) {
+ return get(id).then((result) {
+ if (result is DartError) {
+ // TODO(turnidge): Handle this more gracefully.
+ Logger.root.severe(result.message);
+ return null;
+ }
+ // Clear metrics map.
+ metricsMap.clear();
+ // Repopulate metrics map.
+ var members = result['members'];
+ for (var metric in members) {
+ metricsMap[metric.id] = metric;
+ }
+ return metricsMap;
+ });
+ }
+
+ Future<ObservableMap<String, ServiceMetric>> refreshDartMetrics() {
+ return _refreshMetrics('metrics', dartMetrics);
+ }
+
+ Future<ObservableMap<String, ServiceMetric>> refreshVMMetrics() {
+ return _refreshMetrics('metrics/vm', vmMetrics);
+ }
+
+ Future refreshMetrics() {
+ return refreshDartMetrics().then((_) => refreshVMMetrics());
+ }
+
String toString() => "Isolate($_id)";
}
@@ -1541,7 +1585,7 @@ class ScriptLine extends Observable {
ScriptLine(this.script, this.line, this.text) {
possibleBpt = !_isTrivialLine(text);
-
+
// TODO(turnidge): This is not so efficient. Consider improving.
for (var bpt in this.script.isolate.breakpoints['breakpoints']) {
var bptScript = bpt['location']['script'];
@@ -2219,6 +2263,97 @@ class Socket extends ServiceObject {
}
}
+class MetricSample {
+ final double value;
+ final DateTime time;
+ MetricSample(this.value) : time = new DateTime.now();
+}
+
+class ServiceMetric extends ServiceObject {
+ ServiceMetric._empty(ServiceObjectOwner owner) : super._empty(owner) {
+ }
+
+ bool get canCache => true;
+ bool get immutable => false;
+
+ @observable bool recording = false;
+ MetricPoller poller;
+
+ final ObservableList<MetricSample> samples =
+ new ObservableList<MetricSample>();
+ int _sampleBufferSize = 100;
+ int get sampleBufferSize => _sampleBufferSize;
+ set sampleBufferSize(int size) {
+ _sampleBufferSize = size;
+ _removeOld();
+ }
+
+ void addSample(MetricSample sample) {
+ samples.add(sample);
+ _removeOld();
+ }
+
+ void _removeOld() {
+ // TODO(johnmccutchan): If this becomes hot, consider using a circular
+ // buffer.
+ if (samples.length > _sampleBufferSize) {
+ int count = samples.length - _sampleBufferSize;
+ samples.removeRange(0, count);
+ }
+ }
+
+ @observable String description;
+ @observable double value = 0.0;
+ // Only a guage has a non-null min and max.
+ @observable double min;
+ @observable double max;
+
+ bool get isGauge => (min != null) && (max != null);
+
+ void _update(ObservableMap map, bool mapIsRef) {
+ name = map['name'];
+ description = map['description'];
+ vmName = map['name'];
+ value = map['value'];
+ min = map['min'];
+ max = map['max'];
+ }
+
+ String toString() => "ServiceMetric($_id)";
+}
+
+class MetricPoller {
+ // Metrics to be polled.
+ final List<ServiceMetric> metrics = new List<ServiceMetric>();
+ final Duration pollPeriod;
+ Timer _pollTimer;
+
+ MetricPoller(int milliseconds) :
+ pollPeriod = new Duration(milliseconds: milliseconds) {
+ start();
+ }
+
+ void start() {
+ _pollTimer = new Timer.periodic(pollPeriod, _onPoll);
+ }
+
+ void cancel() {
+ if (_pollTimer != null) {
+ _pollTimer.cancel();
+ }
+ _pollTimer = null;
+ }
+
+ void _onPoll(_) {
+ // Reload metrics and add a sample to each.
+ for (var metric in metrics) {
+ metric.reload().then((m) {
+ m.addSample(new MetricSample(m.value));
+ });
+ }
+ }
+}
+
// Convert any ServiceMaps representing a null instance into an actual null.
_convertNull(obj) {
if (obj is ServiceMap &&
« no previous file with comments | « runtime/bin/vmservice/observatory/lib/src/elements/vm_view.html ('k') | runtime/bin/vmservice/observatory/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698