OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import "dart:_internal"; | 5 import 'dart:_internal'; |
6 import 'dart:convert'; | |
6 | 7 |
7 patch class UserTag { | 8 patch class UserTag { |
8 /* patch */ factory UserTag(String label) { | 9 /* patch */ factory UserTag(String label) { |
9 return new _UserTag(label); | 10 return new _UserTag(label); |
10 } | 11 } |
11 /* patch */ static UserTag get defaultTag => _getDefaultTag(); | 12 /* patch */ static UserTag get defaultTag => _getDefaultTag(); |
12 } | 13 } |
13 | 14 |
14 | 15 |
15 class _UserTag implements UserTag { | 16 class _UserTag implements UserTag { |
16 factory _UserTag(String label) native "UserTag_new"; | 17 factory _UserTag(String label) native "UserTag_new"; |
17 String get label native "UserTag_label"; | 18 String get label native "UserTag_label"; |
18 UserTag makeCurrent() native "UserTag_makeCurrent"; | 19 UserTag makeCurrent() native "UserTag_makeCurrent"; |
19 } | 20 } |
20 | 21 |
21 patch UserTag getCurrentTag() => _getCurrentTag(); | 22 patch UserTag getCurrentTag() => _getCurrentTag(); |
22 UserTag _getCurrentTag() native "Profiler_getCurrentTag"; | 23 UserTag _getCurrentTag() native "Profiler_getCurrentTag"; |
23 | 24 |
24 UserTag _getDefaultTag() native "UserTag_defaultTag"; | 25 UserTag _getDefaultTag() native "UserTag_defaultTag"; |
26 | |
27 /// Abstract [Metric] class. Metric names must be unique, are hierarchical, | |
28 /// and use periods as separators. For example, 'a.b.c'. Uniqueness is only | |
29 /// enforced when a Metric is registered. The name of a metric cannot contain | |
30 /// the slash ('/') character. | |
31 abstract class Metric { | |
32 /// [name] of this metric. | |
33 final String name; | |
34 /// [description] of this metric. | |
35 final String description; | |
36 | |
37 Metric(this.name, this.description) { | |
38 if (name.contains('/')) { | |
39 throw new ArgumentError('Invalid Metric name.'); | |
40 } | |
41 } | |
42 | |
43 Map _toJSON(); | |
44 } | |
45 | |
46 /// A measured value with a min and max. Initial value is min. Value will | |
47 /// be clamped to the interval [min, max]. | |
48 class Gauge extends Metric { | |
49 final double min; | |
50 final double max; | |
turnidge
2014/07/30 19:15:00
double seems reasonable, but will we ever want mor
Cutch
2014/07/30 21:55:03
I could imagine people wanting integers but they g
| |
51 | |
52 double _value; | |
53 double get value => _value; | |
54 set value(double v) { | |
55 if (v < min) { | |
56 v = min; | |
57 } else if (v > max) { | |
58 v = max; | |
59 } | |
60 _value = v; | |
61 } | |
62 | |
63 Gauge(String name, String description, this.min, this.max) | |
64 : super(name, description) { | |
65 if (min is! double) { | |
66 throw new ArgumentError('min must be a double'); | |
67 } | |
68 if (max is! double) { | |
69 throw new ArgumentError('max must be a double'); | |
70 } | |
71 if (!(min < max)) { | |
72 throw new ArgumentError('min must be less than max'); | |
73 } | |
74 _value = min; | |
75 } | |
76 | |
77 Map _toJSON() { | |
78 var map = { | |
79 'type': 'Gauge', | |
80 'id': 'metrics/$name', | |
81 'name': name, | |
82 'description': description, | |
83 'value': value, | |
84 'min': min, | |
85 'max': max, | |
86 }; | |
87 return map; | |
88 } | |
89 } | |
90 | |
91 | |
92 /// A changing value. Initial value is 0.0. | |
93 class Counter extends Metric { | |
turnidge
2014/07/30 19:15:00
The name Counter implies monotonic to me, but the
Cutch
2014/07/30 21:55:03
Initially I had this monotonic but decided to rela
| |
94 Counter(String name, String description) | |
95 : super(name, description); | |
96 | |
97 double _value = 0.0; | |
98 double get value => _value; | |
99 set value(double v) { | |
100 _value = v; | |
101 } | |
102 | |
103 Map _toJSON() { | |
104 var map = { | |
105 'type': 'Counter', | |
106 'id': 'metrics/$name', | |
107 'name': name, | |
108 'description': description, | |
109 'value': value, | |
110 }; | |
111 return map; | |
112 } | |
113 } | |
114 | |
115 /// Register [Metric]s to make them visible to Observatory. | |
116 class Metrics { | |
117 static final List<Metric> _metrics = new List<Metric>(); | |
turnidge
2014/07/30 19:15:00
Why not make this a Map? Then you can avoid the l
Cutch
2014/07/30 21:55:03
Done.
| |
118 | |
119 static bool _nameExists(String name) { | |
120 for (var i = 0; i < _metrics.length; i++) { | |
121 if (_metrics[i].name == name) { | |
122 return true; | |
123 } | |
124 } | |
125 return false; | |
126 } | |
127 | |
128 static void register(Metric metric) { | |
129 if (metric is! Metric) { | |
130 throw new ArgumentError('metric must be a Metric'); | |
131 } | |
132 if (_nameExists(metric.name)) { | |
133 throw new ArgumentError('Registered metrics have unique names'); | |
134 } | |
135 _metrics.add(metric); | |
136 } | |
137 | |
138 static void deregister(Metric metric) { | |
139 if (metric is! Metric) { | |
140 throw new ArgumentError('metric must be a Metric'); | |
141 } | |
142 _metrics.remove(metric); | |
143 } | |
144 | |
145 static String _printMetric(String id) { | |
146 for (var i = 0; i < _metrics.length; i++) { | |
147 var m = _metrics[i]; | |
148 if (m.name == id) { | |
149 return JSON.encode(m._toJSON()); | |
150 } | |
151 } | |
152 return null; | |
153 } | |
154 | |
155 static String _printMetrics() { | |
156 var members = []; | |
157 for (var i = 0; i < _metrics.length; i++) { | |
158 var m = _metrics[i]; | |
159 members.add(m._toJSON()); | |
160 } | |
161 var map = { | |
162 'type': 'MetricList', | |
163 'id': 'metrics', | |
164 'members': members, | |
165 }; | |
166 return JSON.encode(map); | |
167 } | |
168 } | |
OLD | NEW |