|
35 | 35 | #import "MTRError_Internal.h"
|
36 | 36 | #import "MTREventTLVValueDecoder_Internal.h"
|
37 | 37 | #import "MTRLogging_Internal.h"
|
| 38 | +#import "MTRMetricKeys.h" |
| 39 | +#import "MTRMetricsCollector.h" |
38 | 40 | #import "MTRTimeUtils.h"
|
39 | 41 | #import "MTRUnfairLock.h"
|
40 | 42 | #import "zap-generated/MTRCommandPayloads_Internal.h"
|
@@ -91,6 +93,39 @@ - (id)strongObject
|
91 | 93 | }
|
92 | 94 | @end
|
93 | 95 |
|
| 96 | +// Stores essential-for-logging attributes immutably for use in logs |
| 97 | +@interface MTRDeviceEssentialAttributes : NSObject |
| 98 | +@property (readonly) UInt16 vendorID; |
| 99 | +@property (readonly) UInt16 productID; |
| 100 | +@property (readonly) BOOL usesThread; |
| 101 | + |
| 102 | +- (void)addEssentialAttributesToCurrentMetricScope; |
| 103 | + |
| 104 | +@end |
| 105 | + |
| 106 | +@implementation MTRDeviceEssentialAttributes |
| 107 | + |
| 108 | +- (instancetype)initWithVendorID:(UInt16)vendorID productID:(UInt16)productID usesThread:(BOOL)usesThread { |
| 109 | + self = [super init]; |
| 110 | + |
| 111 | + if (self) { |
| 112 | + _vendorID = vendorID; |
| 113 | + _productID = productID; |
| 114 | + _usesThread = usesThread; |
| 115 | + } |
| 116 | + |
| 117 | + return self; |
| 118 | +} |
| 119 | + |
| 120 | +- (void)addEssentialAttributesToCurrentMetricScope { |
| 121 | + using namespace chip::Tracing::DarwinFramework; |
| 122 | + MATTER_LOG_METRIC(kMetricDeviceVendorID, _vendorID); |
| 123 | + MATTER_LOG_METRIC(kMetricDeviceProductID, _productID); |
| 124 | + MATTER_LOG_METRIC(kMetricDeviceUsesThread, _usesThread); |
| 125 | +} |
| 126 | + |
| 127 | +@end |
| 128 | + |
94 | 129 | NSNumber * MTRClampedNumber(NSNumber * aNumber, NSNumber * min, NSNumber * max)
|
95 | 130 | {
|
96 | 131 | if ([aNumber compare:min] == NSOrderedAscending) {
|
@@ -319,6 +354,10 @@ @interface MTRDevice ()
|
319 | 354 |
|
320 | 355 | @property (nonatomic) MTRInternalDeviceState internalDeviceState;
|
321 | 356 |
|
| 357 | +// TODO: cache this once I understand the point in the MTRDevice lifecycle that the relevant attributes will be present. |
| 358 | +// kmo 22 may 2024 14h55 |
| 359 | +// @property (nonatomic) MTRDeviceEssentialAttributes * essentialAttributes; |
| 360 | + |
322 | 361 | #define MTRDEVICE_SUBSCRIPTION_ATTEMPT_MIN_WAIT_SECONDS (1)
|
323 | 362 | #define MTRDEVICE_SUBSCRIPTION_ATTEMPT_MAX_WAIT_SECONDS (3600)
|
324 | 363 | @property (nonatomic) uint32_t lastSubscriptionAttemptWait;
|
@@ -1695,6 +1734,8 @@ - (void)_handleEventReport:(NSArray<NSDictionary<NSString *, id> *> *)eventRepor
|
1695 | 1734 | BOOL isStartUpEvent = (eventPath.cluster.unsignedLongValue == MTRClusterIDTypeBasicInformationID)
|
1696 | 1735 | && (eventPath.event.unsignedLongValue == MTREventIDTypeClusterBasicInformationEventStartUpID);
|
1697 | 1736 | if (isStartUpEvent) {
|
| 1737 | + // REVIEWERS: this seems like a good place to set up / cache |
| 1738 | + // the essential device attributes - is it? |
1698 | 1739 | if (_estimatedStartTimeFromGeneralDiagnosticsUpTime) {
|
1699 | 1740 | // If UpTime was received, make use of it as mark of system start time
|
1700 | 1741 | MTR_LOG("%@ StartUp event: set estimated start time forward to %@", self,
|
@@ -1866,9 +1907,18 @@ - (void)_setCachedAttributeValue:(MTRDeviceDataValueDictionary _Nullable)value f
|
1866 | 1907 | && isFromSubscription
|
1867 | 1908 | && !_receivingPrimingReport
|
1868 | 1909 | && AttributeHasChangesOmittedQuality(path)) {
|
1869 |
| - // Do not persist new values for Changes Omitted Quality attributes unless |
1870 |
| - // they're part of a Priming Report or from a read response. |
| 1910 | + // Do not persist new values for Changes Omitted Quality (aka C Quality) |
| 1911 | + // attributes unless they're part of a Priming Report or from a read response. |
1871 | 1912 | // (removals are OK)
|
| 1913 | + |
| 1914 | + // log when a device violates expectations for Changes Omitted Quality attributes. |
| 1915 | + MTRDeviceEssentialAttributes * attributes = [self _essentialAttributesForCurrentState]; |
| 1916 | + |
| 1917 | + using namespace chip::Tracing::DarwinFramework; |
| 1918 | + MATTER_LOG_METRIC_BEGIN(kMetricUnexpectedCQualityUpdate); |
| 1919 | + [attributes addEssentialAttributesToCurrentMetricScope]; |
| 1920 | + MATTER_LOG_METRIC_END(kMetricUnexpectedCQualityUpdate); |
| 1921 | + |
1872 | 1922 | return;
|
1873 | 1923 | }
|
1874 | 1924 |
|
@@ -3521,6 +3571,22 @@ - (void)removeClientDataForKey:(NSString *)key endpointID:(NSNumber *)endpointID
|
3521 | 3571 | [self.temporaryMetaDataCache removeObjectForKey:[NSString stringWithFormat:@"%@:%@", key, endpointID]];
|
3522 | 3572 | }
|
3523 | 3573 |
|
| 3574 | +#pragma mark Log Help |
| 3575 | + |
| 3576 | +- (MTRDeviceEssentialAttributes *)_essentialAttributesForCurrentState { |
| 3577 | + MTRClusterPath * basicInfoClusterPath = [MTRClusterPath clusterPathWithEndpointID:@(kRootEndpointId) clusterID:@(MTRClusterIDTypeBasicInformationID)]; |
| 3578 | + MTRDeviceClusterData * basicInfoClusterData = [self _clusterDataForPath:basicInfoClusterPath]; |
| 3579 | + |
| 3580 | + NSNumber * vidObj = basicInfoClusterData.attributes[@(MTRAttributeIDTypeClusterBasicInformationAttributeVendorIDID)][MTRValueKey]; |
| 3581 | + UInt16 vendorID = vidObj.unsignedShortValue; |
| 3582 | + NSNumber * pidObj = basicInfoClusterData.attributes[@(MTRAttributeIDTypeClusterBasicInformationAttributeProductIDID)][MTRValueKey]; |
| 3583 | + UInt16 productID = pidObj.unsignedShortValue; |
| 3584 | + |
| 3585 | + BOOL usesThread = [self _deviceUsesThread]; |
| 3586 | + |
| 3587 | + return [[MTRDeviceEssentialAttributes alloc] initWithVendorID:vendorID productID:productID usesThread:usesThread]; |
| 3588 | +} |
| 3589 | + |
3524 | 3590 | @end
|
3525 | 3591 |
|
3526 | 3592 | /* BEGIN DRAGONS: Note methods here cannot be renamed, and are used by private callers, do not rename, remove or modify behavior here */
|
|
0 commit comments