| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2014, 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 /// Instrument your code with counters, gauges, and more. | |
| 6 library dart.profiler; | |
| 7 | |
| 8 import 'dart:convert'; | |
| 9 | |
| 10 /// A UserTag can be used to group samples in the Observatory profiler. | |
| 11 abstract class UserTag { | |
| 12 /// The maximum number of UserTag instances that can be created by a program. | |
| 13 static const MAX_USER_TAGS = 64; | |
| 14 | |
| 15 factory UserTag(String label) => new _FakeUserTag(label); | |
| 16 | |
| 17 /// Label of [this]. | |
| 18 String get label; | |
| 19 | |
| 20 /// Make [this] the current tag for the isolate. Returns the current tag | |
| 21 /// before setting. | |
| 22 UserTag makeCurrent(); | |
| 23 | |
| 24 /// The default [UserTag] with label 'Default'. | |
| 25 static UserTag get defaultTag => _FakeUserTag._defaultTag; | |
| 26 } | |
| 27 | |
| 28 // This is a fake implementation of UserTag so that code can compile and run | |
| 29 // in dart2js. | |
| 30 class _FakeUserTag implements UserTag { | |
| 31 static Map _instances = {}; | |
| 32 | |
| 33 _FakeUserTag.real(this.label); | |
| 34 | |
| 35 factory _FakeUserTag(String label) { | |
| 36 // Canonicalize by name. | |
| 37 var existingTag = _instances[label]; | |
| 38 if (existingTag != null) { | |
| 39 return existingTag; | |
| 40 } | |
| 41 // Throw an exception if we've reached the maximum number of user tags. | |
| 42 if (_instances.length == UserTag.MAX_USER_TAGS) { | |
| 43 throw new UnsupportedError( | |
| 44 'UserTag instance limit (${UserTag.MAX_USER_TAGS}) reached.'); | |
| 45 } | |
| 46 // Create a new instance and add it to the instance map. | |
| 47 var instance = new _FakeUserTag.real(label); | |
| 48 _instances[label] = instance; | |
| 49 return instance; | |
| 50 } | |
| 51 | |
| 52 final String label; | |
| 53 | |
| 54 UserTag makeCurrent() { | |
| 55 var old = _currentTag; | |
| 56 _currentTag = this; | |
| 57 return old; | |
| 58 } | |
| 59 | |
| 60 static final UserTag _defaultTag = new _FakeUserTag('Default'); | |
| 61 } | |
| 62 | |
| 63 var _currentTag = _FakeUserTag._defaultTag; | |
| 64 | |
| 65 /// Returns the current [UserTag] for the isolate. | |
| 66 UserTag getCurrentTag() { | |
| 67 return _currentTag; | |
| 68 } | |
| 69 | |
| 70 /// Abstract [Metric] class. Metric names must be unique, are hierarchical, | |
| 71 /// and use periods as separators. For example, 'a.b.c'. Uniqueness is only | |
| 72 /// enforced when a Metric is registered. The name of a metric cannot contain | |
| 73 /// the slash ('/') character. | |
| 74 abstract class Metric { | |
| 75 /// [name] of this metric. | |
| 76 final String name; | |
| 77 /// [description] of this metric. | |
| 78 final String description; | |
| 79 | |
| 80 Metric(this.name, this.description) { | |
| 81 if ((name == 'vm') || name.contains('/')) { | |
| 82 throw new ArgumentError('Invalid Metric name.'); | |
| 83 } | |
| 84 | |
| 85 } | |
| 86 | |
| 87 Map _toJSON(); | |
| 88 } | |
| 89 | |
| 90 /// A measured value with a min and max. Initial value is min. Value will | |
| 91 /// be clamped to the interval [min, max]. | |
| 92 class Gauge extends Metric { | |
| 93 final double min; | |
| 94 final double max; | |
| 95 | |
| 96 double _value; | |
| 97 double get value => _value; | |
| 98 set value(double v) { | |
| 99 if (v < min) { | |
| 100 v = min; | |
| 101 } else if (v > max) { | |
| 102 v = max; | |
| 103 } | |
| 104 _value = v; | |
| 105 } | |
| 106 | |
| 107 Gauge(String name, String description, this.min, this.max) | |
| 108 : super(name, description) { | |
| 109 if (min is! double) { | |
| 110 throw new ArgumentError('min must be a double'); | |
| 111 } | |
| 112 if (max is! double) { | |
| 113 throw new ArgumentError('max must be a double'); | |
| 114 } | |
| 115 if (!(min < max)) { | |
| 116 throw new ArgumentError('min must be less than max'); | |
| 117 } | |
| 118 _value = min; | |
| 119 } | |
| 120 | |
| 121 Map _toJSON() { | |
| 122 var map = { | |
| 123 'type': 'Gauge', | |
| 124 'id': 'metrics/$name', | |
| 125 'name': name, | |
| 126 'description': description, | |
| 127 'value': value, | |
| 128 'min': min, | |
| 129 'max': max, | |
| 130 }; | |
| 131 return map; | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 | |
| 136 /// A changing value. Initial value is 0.0. | |
| 137 class Counter extends Metric { | |
| 138 Counter(String name, String description) | |
| 139 : super(name, description); | |
| 140 | |
| 141 double _value = 0.0; | |
| 142 double get value => _value; | |
| 143 set value(double v) { | |
| 144 _value = v; | |
| 145 } | |
| 146 | |
| 147 Map _toJSON() { | |
| 148 var map = { | |
| 149 'type': 'Counter', | |
| 150 'id': 'metrics/$name', | |
| 151 'name': name, | |
| 152 'description': description, | |
| 153 'value': value, | |
| 154 }; | |
| 155 return map; | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 class Metrics { | |
| 160 static final Map<String, Metric> _metrics = new Map<String, Metric>(); | |
| 161 | |
| 162 /// Register [Metric]s to make them visible to Observatory. | |
| 163 static void register(Metric metric) { | |
| 164 if (metric is! Metric) { | |
| 165 throw new ArgumentError('metric must be a Metric'); | |
| 166 } | |
| 167 if (_metrics[metric.name] != null) { | |
| 168 throw new ArgumentError('Registered metrics have unique names'); | |
| 169 } | |
| 170 _metrics[metric.name] = metric; | |
| 171 } | |
| 172 | |
| 173 /// Deregister [Metric]s to make them not visible to Observatory. | |
| 174 static void deregister(Metric metric) { | |
| 175 if (metric is! Metric) { | |
| 176 throw new ArgumentError('metric must be a Metric'); | |
| 177 } | |
| 178 _metrics.remove(metric.name); | |
| 179 } | |
| 180 | |
| 181 static String _printMetric(String id) { | |
| 182 var metric = _metrics[id]; | |
| 183 if (metric == null) { | |
| 184 return null; | |
| 185 } | |
| 186 return JSON.encode(metric._toJSON()); | |
| 187 } | |
| 188 | |
| 189 static String _printMetrics() { | |
| 190 var metrics = []; | |
| 191 for (var metric in _metrics.values) { | |
| 192 metrics.add(metric._toJSON()); | |
| 193 } | |
| 194 var map = { | |
| 195 'type': 'MetricList', | |
| 196 'metrics': metrics, | |
| 197 }; | |
| 198 return JSON.encode(map); | |
| 199 } | |
| 200 } | |
| OLD | NEW |