|
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) {
|
@@ -324,6 +359,10 @@ @interface MTRDevice ()
|
324 | 359 |
|
325 | 360 | @property (nonatomic) MTRInternalDeviceState internalDeviceState;
|
326 | 361 |
|
| 362 | +// TODO: cache this once I understand the point in the MTRDevice lifecycle that the relevant attributes will be present. |
| 363 | +// kmo 22 may 2024 14h55 |
| 364 | +// @property (nonatomic) MTRDeviceEssentialAttributes * essentialAttributes; |
| 365 | + |
327 | 366 | #define MTRDEVICE_SUBSCRIPTION_ATTEMPT_MIN_WAIT_SECONDS (1)
|
328 | 367 | #define MTRDEVICE_SUBSCRIPTION_ATTEMPT_MAX_WAIT_SECONDS (3600)
|
329 | 368 | @property (nonatomic) uint32_t lastSubscriptionAttemptWait;
|
@@ -1715,6 +1754,8 @@ - (void)_handleEventReport:(NSArray<NSDictionary<NSString *, id> *> *)eventRepor
|
1715 | 1754 | BOOL isStartUpEvent = (eventPath.cluster.unsignedLongValue == MTRClusterIDTypeBasicInformationID)
|
1716 | 1755 | && (eventPath.event.unsignedLongValue == MTREventIDTypeClusterBasicInformationEventStartUpID);
|
1717 | 1756 | if (isStartUpEvent) {
|
| 1757 | + // REVIEWERS: this seems like a good place to set up / cache |
| 1758 | + // the essential device attributes - is it? |
1718 | 1759 | if (_estimatedStartTimeFromGeneralDiagnosticsUpTime) {
|
1719 | 1760 | // If UpTime was received, make use of it as mark of system start time
|
1720 | 1761 | MTR_LOG("%@ StartUp event: set estimated start time forward to %@", self,
|
@@ -1886,9 +1927,18 @@ - (void)_setCachedAttributeValue:(MTRDeviceDataValueDictionary _Nullable)value f
|
1886 | 1927 | && isFromSubscription
|
1887 | 1928 | && !_receivingPrimingReport
|
1888 | 1929 | && AttributeHasChangesOmittedQuality(path)) {
|
1889 |
| - // Do not persist new values for Changes Omitted Quality attributes unless |
1890 |
| - // they're part of a Priming Report or from a read response. |
| 1930 | + // Do not persist new values for Changes Omitted Quality (aka C Quality) |
| 1931 | + // attributes unless they're part of a Priming Report or from a read response. |
1891 | 1932 | // (removals are OK)
|
| 1933 | + |
| 1934 | + // log when a device violates expectations for Changes Omitted Quality attributes. |
| 1935 | + MTRDeviceEssentialAttributes * attributes = [self _essentialAttributesForCurrentState]; |
| 1936 | + |
| 1937 | + using namespace chip::Tracing::DarwinFramework; |
| 1938 | + MATTER_LOG_METRIC_BEGIN(kMetricUnexpectedCQualityUpdate); |
| 1939 | + [attributes addEssentialAttributesToCurrentMetricScope]; |
| 1940 | + MATTER_LOG_METRIC_END(kMetricUnexpectedCQualityUpdate); |
| 1941 | + |
1892 | 1942 | return;
|
1893 | 1943 | }
|
1894 | 1944 |
|
@@ -3642,6 +3692,22 @@ - (void)removeClientDataForKey:(NSString *)key endpointID:(NSNumber *)endpointID
|
3642 | 3692 | [self.temporaryMetaDataCache removeObjectForKey:[NSString stringWithFormat:@"%@:%@", key, endpointID]];
|
3643 | 3693 | }
|
3644 | 3694 |
|
| 3695 | +#pragma mark Log Help |
| 3696 | + |
| 3697 | +- (MTRDeviceEssentialAttributes *)_essentialAttributesForCurrentState { |
| 3698 | + MTRClusterPath * basicInfoClusterPath = [MTRClusterPath clusterPathWithEndpointID:@(kRootEndpointId) clusterID:@(MTRClusterIDTypeBasicInformationID)]; |
| 3699 | + MTRDeviceClusterData * basicInfoClusterData = [self _clusterDataForPath:basicInfoClusterPath]; |
| 3700 | + |
| 3701 | + NSNumber * vidObj = basicInfoClusterData.attributes[@(MTRAttributeIDTypeClusterBasicInformationAttributeVendorIDID)][MTRValueKey]; |
| 3702 | + UInt16 vendorID = vidObj.unsignedShortValue; |
| 3703 | + NSNumber * pidObj = basicInfoClusterData.attributes[@(MTRAttributeIDTypeClusterBasicInformationAttributeProductIDID)][MTRValueKey]; |
| 3704 | + UInt16 productID = pidObj.unsignedShortValue; |
| 3705 | + |
| 3706 | + BOOL usesThread = [self _deviceUsesThread]; |
| 3707 | + |
| 3708 | + return [[MTRDeviceEssentialAttributes alloc] initWithVendorID:vendorID productID:productID usesThread:usesThread]; |
| 3709 | +} |
| 3710 | + |
3645 | 3711 | @end
|
3646 | 3712 |
|
3647 | 3713 | /* 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