18
18
#import " MTRMetricsCollector.h"
19
19
#import " MTRLogging_Internal.h"
20
20
#include " MTRMetrics_Internal.h"
21
+ #include < MTRMetrics.h>
21
22
#import < MTRUnfairLock.h>
22
23
#include < platform/Darwin/Tracing.h>
23
24
#include < system/SystemClock.h>
26
27
27
28
using MetricEvent = chip::Tracing::MetricEvent;
28
29
29
- static NSString * kMTRMetricDataValueKey = @" value" ;
30
- static NSString * kMTRMetricDataTimepointKey = @" time_point" ;
31
- static NSString * kMTRMetricDataDurationKey = @" duration_us" ;
32
-
33
- @implementation MTRMetricsData {
30
+ @implementation MTRMetricData {
34
31
chip::System::Clock::Microseconds64 _timePoint;
35
- chip::System::Clock::Microseconds64 _duration;
32
+ MetricEvent::Type _type;
33
+ }
34
+
35
+ - (instancetype )init
36
+ {
37
+ // Default is to create data for instant event type.
38
+ // The key can be anything since it is not really used in this context.
39
+ MetricEvent event (MetricEvent::Type::kInstantEvent , " " );
40
+ return [self initWithMetricEvent: event];
36
41
}
37
42
38
43
- (instancetype )initWithMetricEvent : (const MetricEvent &)event
@@ -41,60 +46,50 @@ - (instancetype)initWithMetricEvent:(const MetricEvent &)event
41
46
return nil ;
42
47
}
43
48
49
+ _type = event.type ();
50
+
51
+ using EventType = MetricEvent::Type;
52
+ switch (_type) {
53
+ // Capture timepoint for begin and end to calculate duration
54
+ case EventType::kBeginEvent :
55
+ case EventType::kEndEvent :
56
+ _timePoint = chip::System::SystemClock ().GetMonotonicMicroseconds64 ();
57
+ break ;
58
+ case EventType::kInstantEvent :
59
+ _timePoint = chip::System::Clock::Microseconds64 (0 );
60
+ break ;
61
+ }
62
+
44
63
using ValueType = MetricEvent::Value::Type;
45
64
switch (event.ValueType ()) {
46
65
case ValueType::kInt32 :
47
66
_value = [NSNumber numberWithInteger: event.ValueInt32 ()];
48
67
break ;
49
68
case ValueType::kUInt32 :
50
- _value = [NSNumber numberWithInteger : event.ValueUInt32 ()];
69
+ _value = [NSNumber numberWithUnsignedInteger : event.ValueUInt32 ()];
51
70
break ;
52
71
case ValueType::kChipErrorCode :
53
- _value = [NSNumber numberWithInteger : event.ValueErrorCode ()];
72
+ _errorCode = [NSNumber numberWithUnsignedInteger : event.ValueErrorCode ()];
54
73
break ;
55
74
case ValueType::kUndefined :
56
- default :
57
- _value = nil ;
75
+ break ;
58
76
}
59
-
60
- _timePoint = chip::System::SystemClock ().GetMonotonicMicroseconds64 ();
61
- _duration = chip::System::Clock::Microseconds64 (0 );
62
77
return self;
63
78
}
64
79
65
- - (void )setDurationFromMetricData : (MTRMetricsData *)fromData
66
- {
67
- _duration = _timePoint - fromData->_timePoint ;
68
- }
69
-
70
- - (NSNumber *)timePointMicroseconds
80
+ - (void )setDurationFromMetricDataAndClearCounters : (MTRMetricData *)fromData
71
81
{
72
- return [ NSNumber numberWithUnsignedLongLong: _timePoint. count ()] ;
73
- }
82
+ auto duration = _timePoint - fromData-> _timePoint ;
83
+ _durationMicroseconds = [ NSNumber numberWithUnsignedLongLong: duration. count ()];
74
84
75
- - (NSNumber *)durationMicroseconds
76
- {
77
- return [NSNumber numberWithUnsignedLongLong: _duration.count ()];
85
+ // Clear timepoints to minimize history
86
+ _timePoint = fromData->_timePoint = chip::System::Clock::Microseconds64 (0 );
78
87
}
79
88
80
89
- (NSString *)description
81
90
{
82
- return [NSString stringWithFormat: @" MTRMetricsData: Value = %@ , TimePoint = %@ , Duration = %@ us" , self .value, self .timePointMicroseconds, self .durationMicroseconds];
83
- }
84
-
85
- - (NSDictionary *)toDictionary
86
- {
87
- NSMutableDictionary * dictRepresentation = [NSMutableDictionary dictionary ];
88
- if (self.value ) {
89
- [dictRepresentation setValue: self .value forKey: kMTRMetricDataValueKey ];
90
- }
91
- if (auto tmPt = self.timePointMicroseconds ) {
92
- [dictRepresentation setValue: tmPt forKey: kMTRMetricDataTimepointKey ];
93
- }
94
- if (auto duration = self.durationMicroseconds ) {
95
- [dictRepresentation setValue: duration forKey: kMTRMetricDataDurationKey ];
96
- }
97
- return dictRepresentation;
91
+ return [NSString stringWithFormat: @" <MTRMetricData>: Type %d , Value = %@ , Error Code = %@ , Duration = %@ us" ,
92
+ static_cast <int >(_type), self .value, self .errorCode, self .durationMicroseconds];
98
93
}
99
94
100
95
@end
@@ -123,8 +118,9 @@ void ShutdownMetricsCollection()
123
118
124
119
@implementation MTRMetricsCollector {
125
120
os_unfair_lock _lock;
126
- NSMutableDictionary <NSString *, MTRMetricsData *> * _metricsDataCollection;
121
+ NSMutableDictionary <NSString *, MTRMetricData *> * _metricsDataCollection;
127
122
chip::Tracing::signposts::DarwinTracingBackend _tracingBackend;
123
+ BOOL _tracingBackendRegistered;
128
124
}
129
125
130
126
+ (instancetype )sharedInstance
@@ -152,32 +148,43 @@ - (instancetype)init
152
148
}
153
149
_lock = OS_UNFAIR_LOCK_INIT;
154
150
_metricsDataCollection = [NSMutableDictionary dictionary ];
151
+ _tracingBackendRegistered = FALSE ;
155
152
return self;
156
153
}
157
154
158
155
- (void )registerTracingBackend
159
156
{
160
157
std::lock_guard lock (_lock);
161
- chip::Tracing::Register (_tracingBackend);
162
- MTR_LOG_INFO (" Registered tracing backend with the registry" );
158
+
159
+ // Register only once
160
+ if (!_tracingBackendRegistered) {
161
+ chip::Tracing::Register (_tracingBackend);
162
+ MTR_LOG_INFO (" Registered tracing backend with the registry" );
163
+ _tracingBackendRegistered = TRUE ;
164
+ }
163
165
}
164
166
165
167
- (void )unregisterTracingBackend
166
168
{
167
169
std::lock_guard lock (_lock);
168
- chip::Tracing::Unregister (_tracingBackend);
169
- MTR_LOG_INFO (" Unregistered tracing backend with the registry" );
170
+
171
+ // Unregister only if registered before
172
+ if (_tracingBackendRegistered) {
173
+ chip::Tracing::Unregister (_tracingBackend);
174
+ MTR_LOG_INFO (" Unregistered tracing backend with the registry" );
175
+ _tracingBackendRegistered = FALSE ;
176
+ }
170
177
}
171
178
172
179
static inline NSString * suffixNameForMetricType (MetricEvent::Type type)
173
180
{
174
181
switch (type) {
175
182
case MetricEvent::Type::kBeginEvent :
176
- return @" -begin " ;
183
+ return @" _begin " ;
177
184
case MetricEvent::Type::kEndEvent :
178
- return @" -end " ;
185
+ return @" _end " ;
179
186
case MetricEvent::Type::kInstantEvent :
180
- return @" -instant " ;
187
+ return @" _instant " ;
181
188
}
182
189
}
183
190
@@ -211,14 +218,14 @@ - (void)handleMetricEvent:(MetricEvent)event
211
218
212
219
// Create the new metric key based event type
213
220
auto metricsKey = [NSString stringWithFormat: @" %s %@ " , event.key (), suffixNameForMetric (event)];
214
- MTRMetricsData * data = [[MTRMetricsData alloc ] initWithMetricEvent: event];
221
+ MTRMetricData * data = [[MTRMetricData alloc ] initWithMetricEvent: event];
215
222
216
223
// If End event, compute its duration using the Begin event
217
224
if (event.type () == MetricEvent::Type::kEndEvent ) {
218
225
auto metricsBeginKey = [NSString stringWithFormat: @" %s %@ " , event.key (), suffixNameForMetricType (MetricEvent: :Type: :kBeginEvent )];
219
- MTRMetricsData * beginMetric = _metricsDataCollection[metricsBeginKey];
226
+ MTRMetricData * beginMetric = _metricsDataCollection[metricsBeginKey];
220
227
if (beginMetric) {
221
- [data setDurationFromMetricData : beginMetric];
228
+ [data setDurationFromMetricDataAndClearCounters : beginMetric];
222
229
} else {
223
230
// Unbalanced end
224
231
MTR_LOG_ERROR (" Unable to find Begin event corresponding to Metric Event: %s" , event.key ());
@@ -230,7 +237,7 @@ - (void)handleMetricEvent:(MetricEvent)event
230
237
// If the event is a begin or end event, implicitly emit a corresponding instant event
231
238
if (event.type () == MetricEvent::Type::kBeginEvent || event.type () == MetricEvent::Type::kEndEvent ) {
232
239
MetricEvent instantEvent (MetricEvent::Type::kInstantEvent , event.key ());
233
- data = [[MTRMetricsData alloc ] initWithMetricEvent: instantEvent];
240
+ data = [[MTRMetricData alloc ] initWithMetricEvent: instantEvent];
234
241
metricsKey = [NSString stringWithFormat: @" %s %@ " , event.key (), suffixNameForMetric (instantEvent)];
235
242
[_metricsDataCollection setValue: data forKey: metricsKey];
236
243
}
@@ -240,10 +247,9 @@ - (MTRMetrics *)metricSnapshot:(BOOL)resetCollection
240
247
{
241
248
std::lock_guard lock (_lock);
242
249
243
- // Copy the MTRMetrics as NSDictionary
244
250
MTRMetrics * metrics = [[MTRMetrics alloc ] initWithCapacity: [_metricsDataCollection count ]];
245
251
for (NSString * key in _metricsDataCollection) {
246
- [metrics setValue: [ _metricsDataCollection[key] toDictionary ] forKey: key];
252
+ [metrics setMetricData: _metricsDataCollection[key] forKey: key];
247
253
}
248
254
249
255
// Clear curent stats, if specified
0 commit comments