Skip to content

Commit 8f2a4d2

Browse files
authored
Framework for emitting metrics data (#32223)
* Rerouted tracing macros to Darwin signposts * Initial framework for logging scalar data event * Handled the new metrics event changes in collector * Modified VerifyOrExit macro to accept an optional metric key as third argument * Removed direct use of chrono in metrics_event.h Switched MTRMetrics to vend dictionary for metric keys * Modified SuccessOrExit to optionally accept metric key * Moved metric keys to separate header Reworked metric_event names for more clarity * Switched MATTER_TRACE_METRIC usage to MATTER_LOG_METRIC * Restyle fixes * Fixed unit tests * Fixed build failure due to MetricEvent hidden inside tracing enabled * Fixing one source of build error * Fixing darwin build failure * Code Review: Rename LogMetric to LogMetricEvent * Code Review Suggestions: 1. Metric Macros take full string constants and no longer use preprocessor to prefix. Allows free flowing strings 2. Reworked MetricEvent class and documented 3. Handled LogEventMetric for Darwin, ESP32, Perfetto, JSON to account for all types 4. Removed timePoint from MetricEvent class. Timestamps and duration calculation is now responsibility for the handlers of the event 5. Reverted BUILD.gn in system to not break out SystemClock.h * Code Review Feedback #2: 1. Added SuccessOrExitWithMetric and VerifyOrExitWithMetric 2. Cleaned up support .gn to remove dependedency on metrics * Code Review Feedback #3: 1. Added ScopedMetricEvent to use RAII to track begin and end within a scope * Code Review #4: Reverted an accidental removal * Added MTRMetricData to description as per review comment * Restyler fixes * Sample code of how Begin and End log metrics can be used * Fixed compilation error when tracing is disabled * Fixes for build failures when tracing is disabled * Picked up code review suggestion accidently dropped * Code Review Feedback: 1. Begin metric does not take value 2. Allow undefined value for metric 3. Misc other feedback * Handle undefined value and error value * Revert a comment change * Review Feedback: Changed ScopedMetricEvent to capture error by reference * Fixed another build failure * Reverting usage of LOG_METRICS * Review feedback: Fix incorrect documentation * Code Review Feedback: Remove access to Value in MetricEvent to avoid incorrect access * Restyler fixes * Unregistering backend in Darwin shutdown * Resytler fixes...
1 parent c5a0720 commit 8f2a4d2

37 files changed

+1167
-54
lines changed

src/app/clusters/wifi-network-diagnostics-server/wifi-network-diagnostics-server.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <lib/core/Optional.h>
2929
#include <platform/DiagnosticDataProvider.h>
3030
#include <tracing/macros.h>
31+
#include <tracing/metric_event.h>
3132

3233
using namespace chip;
3334
using namespace chip::app;
@@ -163,7 +164,7 @@ CHIP_ERROR WiFiDiagosticsAttrAccess::ReadWiFiRssi(AttributeValueEncoder & aEncod
163164
{
164165
rssi.SetNonNull(value);
165166
ChipLogProgress(Zcl, "The current RSSI of the Node’s Wi-Fi radio in dB: %d", value);
166-
MATTER_TRACE_METRIC("wifi_rssi", value);
167+
MATTER_LOG_METRIC(chip::Tracing::kMetricWiFiRSSI, value);
167168
}
168169
else
169170
{

src/darwin/Framework/CHIP/MTRDeviceControllerDelegateBridge.mm

+5-9
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717

1818
#import "MTRDeviceControllerDelegateBridge.h"
1919
#import "MTRDeviceController.h"
20+
#import "MTRDeviceController_Internal.h"
2021
#import "MTRError_Internal.h"
2122
#import "MTRLogging_Internal.h"
22-
#import "MTRMetrics_Internal.h"
23+
#import "MTRMetricsCollector.h"
2324

2425
MTRDeviceControllerDelegateBridge::MTRDeviceControllerDelegateBridge(void)
2526
: mDelegate(nil)
@@ -130,15 +131,10 @@
130131
nodeID = @(nodeId);
131132
}
132133

134+
// If the client implements the metrics delegate, prefer that over others
133135
if ([strongDelegate respondsToSelector:@selector(controller:commissioningComplete:nodeID:metrics:)]) {
134-
MTRMetrics * metrics = [MTRMetrics new];
135-
136-
if (nsError) {
137-
[metrics setValue:nsError forKey:MTRMetricCommissioningStatusKey];
138-
} else {
139-
auto * error = [NSError errorWithDomain:MTRErrorDomain code:0 userInfo:nil];
140-
[metrics setValue:error forKey:MTRMetricCommissioningStatusKey];
141-
}
136+
// Create a snapshot and clear for next operation
137+
MTRMetrics * metrics = [[MTRMetricsCollector sharedInstance] metricSnapshot:TRUE];
142138
[strongDelegate controller:strongController commissioningComplete:nsError nodeID:nodeID metrics:metrics];
143139
} else {
144140
[strongDelegate controller:strongController commissioningComplete:nsError nodeID:nodeID];

src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm

+7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#import "MTRFabricInfo_Internal.h"
4040
#import "MTRFramework.h"
4141
#import "MTRLogging_Internal.h"
42+
#import "MTRMetricsCollector.h"
4243
#import "MTROTAProviderDelegateBridge.h"
4344
#import "MTROperationalBrowser.h"
4445
#import "MTRP256KeypairBridge.h"
@@ -349,6 +350,8 @@ - (void)cleanupStartupObjects
349350
}
350351

351352
_diagnosticLogsDownloader = nil;
353+
354+
ShutdownMetricsCollection();
352355
}
353356

354357
- (CHIP_ERROR)_initFabricTable:(FabricTable &)fabricTable
@@ -414,6 +417,10 @@ - (BOOL)startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParams
414417
return YES;
415418
}
416419

420+
// Register any tracing backends. This has to be done before starting the event loop to run registering
421+
// the tracing backend in the right queue context
422+
StartupMetricsCollection();
423+
417424
DeviceLayer::PlatformMgrImpl().StartEventLoopTask();
418425

419426
__block CHIP_ERROR errorCode = CHIP_NO_ERROR;

src/darwin/Framework/CHIP/MTRFramework.mm

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#import "MTRFramework.h"
18+
#import "MTRMetricsCollector.h"
1819

1920
#include <dispatch/dispatch.h>
2021
#include <lib/support/CHIPMem.h>
@@ -34,5 +35,8 @@ void MTRFrameworkInit()
3435
// Suppress CHIP logging until we actually need it for redirection
3536
// (see MTRSetLogCallback()). Logging to os_log is always enabled.
3637
chip::Logging::SetLogFilter(chip::Logging::kLogCategory_None);
38+
39+
// Startup metrics collection and tracing framework
40+
StartupMetricsCollection();
3741
});
3842
}

src/darwin/Framework/CHIP/MTRMetrics.h

+15-1
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,28 @@
2121
NS_ASSUME_NONNULL_BEGIN
2222

2323
/**
24-
* A representation of metrics data for an operation.
24+
* A representation of a collection of metrics data for an operation.
2525
*/
2626
MTR_NEWLY_AVAILABLE
2727
@interface MTRMetrics : NSObject
2828

29+
- (instancetype)init NS_UNAVAILABLE;
30+
+ (instancetype)new NS_UNAVAILABLE;
31+
32+
/**
33+
* @brief Returns the names of all the metrics data items collected.
34+
*/
2935
@property (nonatomic, readonly, copy) NSArray<NSString *> * allKeys;
3036

37+
/**
38+
* @brief Returns metric object corresponding to the metric identified by its key
39+
*
40+
* @param [in] key Name of the metric
41+
*
42+
* @return An object containing the metric data, nil if key is invalid
43+
*/
3144
- (nullable id)valueForKey:(NSString *)key;
3245

3346
@end
47+
3448
NS_ASSUME_NONNULL_END

src/darwin/Framework/CHIP/MTRMetrics.mm

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,24 @@
1616
*/
1717
#import "MTRLogging_Internal.h"
1818
#import "MTRMetrics_Internal.h"
19+
#include <Foundation/Foundation.h>
1920
#import <Matter/MTRDefines.h>
21+
#include <Matter/MTRMetrics.h>
2022

2123
@implementation MTRMetrics {
2224
NSMutableDictionary<NSString *, id> * _metricsData;
2325
}
2426

2527
- (instancetype)init
28+
{
29+
NSAssert(false, @"'init' unavailable, use initWithCapacity: instead");
30+
return nil;
31+
}
32+
33+
- (instancetype)initWithCapacity:(NSUInteger)numItems
2634
{
2735
if (self = [super init]) {
28-
_metricsData = [NSMutableDictionary dictionary];
36+
_metricsData = [NSMutableDictionary dictionaryWithCapacity:numItems];
2937
}
3038
return self;
3139
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
*
3+
* Copyright (c) 2024 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include <MTRDefines.h>
19+
#import <Matter/MTRMetrics.h>
20+
21+
NS_ASSUME_NONNULL_BEGIN
22+
23+
/**
24+
* This function initializes any backend required to collect metrics data.
25+
*/
26+
void StartupMetricsCollection();
27+
28+
/**
29+
* This function shuts down any backend created to collect metrics data.
30+
*/
31+
void ShutdownMetricsCollection();
32+
33+
/**
34+
* A representation of metrics data for an operation.
35+
*/
36+
@interface MTRMetricsCollector : NSObject
37+
38+
- (instancetype)init NS_UNAVAILABLE;
39+
+ (instancetype)new NS_UNAVAILABLE;
40+
41+
/**
42+
* Return the singleton MTRMetricsCollector to vend MTRMetrics snapshots
43+
*/
44+
+ (instancetype)sharedInstance;
45+
46+
/**
47+
* @brief This method creates a snapshot of the metrics collected until the current point in time
48+
* and returns an object with the stats.
49+
*
50+
* @param [in] resetCollection Boolean that specifies whether or not to clear the stats collected after
51+
* creating the snapshot.
52+
*
53+
* @return MTRMetric object representing the metric data.
54+
*/
55+
- (MTRMetrics *)metricSnapshot:(BOOL)resetCollection;
56+
57+
@end
58+
59+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)