| Index: runtime/observatory/lib/src/repositories/metric.dart
|
| diff --git a/runtime/observatory/lib/src/repositories/metric.dart b/runtime/observatory/lib/src/repositories/metric.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5e81b75e9176b1cfac0a8c97b7c3769a52b234d4
|
| --- /dev/null
|
| +++ b/runtime/observatory/lib/src/repositories/metric.dart
|
| @@ -0,0 +1,192 @@
|
| +// 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
|
| +
|
| +part of repositories;
|
| +
|
| +class Metric implements M.Metric {
|
| + final String id;
|
| + String get name => internal.name;
|
| + String get description => internal.description;
|
| + final internal;
|
| +
|
| + Metric(this.id, this.internal);
|
| +}
|
| +
|
| +class MetricSample implements M.MetricSample {
|
| + final double value;
|
| + final DateTime time = new DateTime.now();
|
| + MetricSample(this.value);
|
| +}
|
| +
|
| +class MetricRepository implements M.MetricRepository {
|
| + final Map<S.Isolate, Map<Metric, List<M.MetricSample>>> _samples
|
| + = <S.Isolate, Map<Metric, List<M.MetricSample>>>{};
|
| + final Map<S.Isolate, Map<Metric, int>> _rates
|
| + = <S.Isolate, Map<Metric, int>>{};
|
| + final Map<S.Isolate, Map<Metric, int>> _sizes
|
| + = <S.Isolate, Map<Metric, int>>{};
|
| + Timer _timer;
|
| + int count = 0;
|
| +
|
| + Future<Iterable<Metric>> list(M.IsolateRef i) async{
|
| + S.Isolate isolate = i as S.Isolate;
|
| + assert(isolate != null);
|
| + if (_samples.containsKey(isolate)) {
|
| + return _samples[isolate].keys;
|
| + }
|
| + return const [];
|
| + }
|
| +
|
| + Future startSampling(M.IsolateRef i) async {
|
| + S.Isolate isolate = i as S.Isolate;
|
| + assert(isolate != null);
|
| + if (!_samples.containsKey(isolate)) {
|
| + await isolate.refreshMetrics();
|
| + final samples = _samples[isolate] = <Metric, List<M.MetricSample>>{};
|
| + final rates = _rates[isolate] = <Metric, int>{};
|
| + final sizes = _sizes[isolate] = <Metric, int>{};
|
| + final metrics = []
|
| + ..addAll(isolate.dartMetrics.keys.map((name) =>
|
| + new Metric(name, isolate.dartMetrics[name])).toList())
|
| + ..addAll(isolate.nativeMetrics.keys.map((name) =>
|
| + new Metric(name, isolate.nativeMetrics[name])).toList());
|
| + for (final metric in metrics) {
|
| + samples[metric] = [new MetricSample(metric.internal.value)];
|
| + rates[metric] = _rateToInteger(M.MetricSamplingRate.off);
|
| + sizes[metric] = _sizeToInteger(M.MetricBufferSize.n100samples);
|
| + }
|
| + if (_samples.length == 1) {
|
| + count = 0;
|
| + _timer = new Timer.periodic(new Duration(milliseconds: 100), _update);
|
| + }
|
| + }
|
| + }
|
| +
|
| + Future stopSampling(M.IsolateRef isolate) async {
|
| + if (_samples.containsKey(isolate)) {
|
| + _samples.remove(isolate);
|
| + _rates.remove(isolate);
|
| + _sizes.remove(isolate);
|
| + if (_samples.isEmpty) {
|
| + _timer.cancel();
|
| + }
|
| + }
|
| + }
|
| +
|
| + M.MetricSamplingRate getSamplingRate(M.IsolateRef i, M.Metric m) {
|
| + if (_rates.containsKey(i)) {
|
| + final metrics = _rates[i];
|
| + if (metrics.containsKey(m)) {
|
| + switch (metrics[m]) {
|
| + case 0: return M.MetricSamplingRate.off;
|
| + case 1: return M.MetricSamplingRate.e100ms;
|
| + case 10: return M.MetricSamplingRate.e1s;
|
| + case 20: return M.MetricSamplingRate.e2s;
|
| + case 40: return M.MetricSamplingRate.e4s;
|
| + case 80: return M.MetricSamplingRate.e8s;
|
| + }
|
| + }
|
| + }
|
| + throw new Exception('Sampling for isolate ${i.id} is not started');
|
| + }
|
| +
|
| + void setSamplingRate(M.IsolateRef i, M.Metric m, M.MetricSamplingRate r) {
|
| + if (_rates.containsKey(i)) {
|
| + final metrics = _rates[i];
|
| + if (metrics.containsKey(m)) {
|
| + metrics[m] = _rateToInteger(r);
|
| + }
|
| + } else {
|
| + throw new Exception('Sampling for isolate ${i.id} is not started');
|
| + }
|
| + }
|
| +
|
| + M.MetricBufferSize getBufferSize(M.IsolateRef i, M.Metric m) {
|
| + if (_sizes.containsKey(i)) {
|
| + final metrics = _sizes[i];
|
| + if (metrics.containsKey(m)) {
|
| + switch (metrics[m]) {
|
| + case 10: return M.MetricBufferSize.n10samples;
|
| + case 100: return M.MetricBufferSize.n100samples;
|
| + case 1000: return M.MetricBufferSize.n1000samples;
|
| + }
|
| + }
|
| + }
|
| + throw new Exception('Sampling for isolate ${i.id} is not started');
|
| + }
|
| +
|
| + void setBufferSize(M.IsolateRef i, M.Metric m, M.MetricBufferSize s) {
|
| + if (_sizes.containsKey(i)) {
|
| + final metrics = _sizes[i];
|
| + if (metrics.containsKey(m)) {
|
| + metrics[m] = _sizeToInteger(s);
|
| + }
|
| + } else {
|
| + throw new Exception('Sampling for isolate ${i.id} is not started');
|
| + }
|
| + }
|
| +
|
| + static int _rateToInteger(M.MetricSamplingRate r) {
|
| + switch (r) {
|
| + case M.MetricSamplingRate.off: return 0;
|
| + case M.MetricSamplingRate.e100ms: return 1;
|
| + case M.MetricSamplingRate.e1s: return 10;
|
| + case M.MetricSamplingRate.e2s: return 20;
|
| + case M.MetricSamplingRate.e4s: return 40;
|
| + case M.MetricSamplingRate.e8s: return 80;
|
| + }
|
| + throw new Exception('Unknown MetricSamplingRate ($r)');
|
| + }
|
| +
|
| + static int _sizeToInteger(M.MetricBufferSize s) {
|
| + switch (s) {
|
| + case M.MetricBufferSize.n10samples: return 10;
|
| + case M.MetricBufferSize.n100samples: return 100;
|
| + case M.MetricBufferSize.n1000samples: return 1000;
|
| + }
|
| + throw new Exception('Unknown MetricBufferSize ($s)');
|
| + }
|
| +
|
| + Iterable<M.MetricSample> getSamples(M.IsolateRef i, M.Metric m) {
|
| + if (_samples.containsKey(i)) {
|
| + final metrics = _samples[i];
|
| + if (metrics.containsKey(m)) {
|
| + return metrics[m];
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + double getMinValue(M.IsolateRef i, M.Metric m) {
|
| + Metric metric = m as Metric;
|
| + assert(metric != null);
|
| + return metric.internal.min;
|
| + }
|
| +
|
| + double getMaxValue(M.IsolateRef i, M.Metric m) {
|
| + Metric metric = m as Metric;
|
| + assert(metric != null);
|
| + return metric.internal.max;
|
| + }
|
| +
|
| + void _update(_) {
|
| + for (final isolate in _rates.keys) {
|
| + final metrics = _rates[isolate];
|
| + for (final metric in metrics.keys) {
|
| + final rate = metrics[metric];
|
| + if (rate != 0 && count % rate == 0) {
|
| + final size = _sizes[isolate][metric];
|
| + final samples = _samples[isolate][metric];
|
| + metric.internal.reload().then((m) {
|
| + if (samples.length >= size) {
|
| + samples.removeRange(0, samples.length - size + 1);
|
| + }
|
| + samples.add(new MetricSample(m.value));
|
| + });
|
| + }
|
| + }
|
| + }
|
| + ++count;
|
| + }
|
| +}
|
|
|