Showing 5 changed files with 89 additions and 81 deletions
+82 -49
USB Meter/AppDelegate.swift
@@ -15,6 +15,22 @@ import UserNotifications
15 15
 //let btSerial = BluetoothSerial(delegate: BSD())
16 16
 let appData = AppData()
17 17
 private let restoreLogger = Logger(subsystem: "ro.xdev.USB-Meter", category: "Restore")
18
+private enum DebugLogFlag: String {
19
+    case all = "USB_METER_DEBUG_LOGS"
20
+    case bluetooth = "USB_METER_BLUETOOTH_LOGS"
21
+    case cloud = "USB_METER_CLOUD_LOGS"
22
+    case meter = "USB_METER_METER_LOGS"
23
+    case migration = "USB_METER_MIGRATION_LOGS"
24
+    case notifications = "USB_METER_NOTIFICATION_LOGS"
25
+    case restore = "USB_METER_RESTORE_LOGS"
26
+    case sync = "USB_METER_SYNC_LOGS"
27
+}
28
+
29
+public func debugLogFlagEnabled(_ flag: String) -> Bool {
30
+    ProcessInfo.processInfo.environment[DebugLogFlag.all.rawValue] == "1" ||
31
+    ProcessInfo.processInfo.environment[flag] == "1"
32
+}
33
+
18 34
 enum Constants {
19 35
     static let chartUnderscan: CGFloat = 0.5
20 36
     static let chartOverscan: CGFloat = 1 - chartUnderscan
@@ -35,16 +51,16 @@ public func track(_ message: String = "", file: String = #file, function: String
35 51
 }
36 52
 
37 53
 public func restoreTrace(_ message: String) {
54
+    guard debugLogFlagEnabled(DebugLogFlag.restore.rawValue) else { return }
38 55
     restoreLogger.debug("\(message, privacy: .public)")
39 56
 }
40 57
 
41 58
 private func shouldEmitTrackMessage(_ message: String, file: String, function: String) -> Bool {
42 59
     #if DEBUG
43
-    if ProcessInfo.processInfo.environment["USB_METER_VERBOSE_LOGS"] == "1" {
60
+    if debugLogFlagEnabled(DebugLogFlag.all.rawValue) {
44 61
         return true
45 62
     }
46 63
 
47
-    #if targetEnvironment(macCatalyst)
48 64
     let importantMarkers = [
49 65
         "Error",
50 66
         "error",
@@ -63,69 +79,85 @@ private func shouldEmitTrackMessage(_ message: String, file: String, function: S
63 79
         "not supported",
64 80
         "Unexpected",
65 81
         "Invalid Context",
66
-        "ignored",
67
-        "Guard:",
68
-        "Skip data request",
69
-        "Dropping unsolicited data",
70 82
         "This is not possible!",
71
-        "Inferred",
72
-        "Clearing",
73
-        "Reconnecting"
83
+        "Buffer overflow"
74 84
     ]
75 85
 
76 86
     if importantMarkers.contains(where: { message.contains($0) }) {
77 87
         return true
78 88
     }
79 89
 
80
-    let noisyFunctions: Set<String> = [
81
-        "logRuntimeICloudDiagnostics()",
82
-        "refreshCloudAvailability(reason:)",
83
-        "start()",
84
-        "centralManagerDidUpdateState(_:)",
85
-        "discoveredMeter(peripheral:advertising:rssi:)",
86
-        "connect()",
87
-        "connectionEstablished()",
88
-        "peripheral(_:didDiscoverServices:)",
89
-        "peripheral(_:didDiscoverCharacteristicsFor:error:)",
90
-        "refreshOperationalStateIfReady()",
91
-        "peripheral(_:didUpdateNotificationStateFor:error:)",
92
-        "scheduleDataDumpRequest(after:reason:)"
93
-    ]
94
-
95
-    if noisyFunctions.contains(function) {
96
-        return false
97
-    }
98
-
99
-    let noisyMarkers = [
100
-        "Runtime iCloud diagnostics",
101
-        "iCloud availability",
102
-        "Starting Bluetooth manager",
103
-        "Bluetooth is On... Start scanning...",
104
-        "adding new USB Meter",
105
-        "Connect called for",
106
-        "Connection established for",
107
-        "Optional([<CBService:",
108
-        "Optional([<CBCharacteristic:",
109
-        "Waiting for notifications on",
110
-        "Notification state updated for",
111
-        "Peripheral ready with notify",
112
-        "Schedule data request in",
113
-        "Operational state changed"
114
-    ]
115
-
116
-    if noisyMarkers.contains(where: { message.contains($0) }) {
117
-        return false
90
+    if isTrackMessageEnabledByCategory(message, file: file, function: function) {
91
+        return true
118 92
     }
119
-    #endif
120 93
 
121
-    return true
94
+    return false
122 95
     #else
96
+    _ = message
123 97
     _ = file
124 98
     _ = function
125 99
     return false
126 100
     #endif
127 101
 }
128 102
 
103
+private func isTrackMessageEnabledByCategory(_ message: String, file: String, function: String) -> Bool {
104
+    let categories = debugLogCategories(for: message, file: file, function: function)
105
+    return categories.contains { debugLogFlagEnabled($0.rawValue) }
106
+}
107
+
108
+private func debugLogCategories(for message: String, file: String, function: String) -> [DebugLogFlag] {
109
+    var categories = [DebugLogFlag]()
110
+
111
+    if file.contains("Bluetooth") ||
112
+        function.contains("centralManager") ||
113
+        function.contains("peripheral(") ||
114
+        message.contains("Bluetooth") ||
115
+        message.contains("BLE discovery") ||
116
+        message.contains("peripheral") ||
117
+        message.contains("characteristic") ||
118
+        message.contains("service") {
119
+        categories.append(.bluetooth)
120
+    }
121
+
122
+    if file.contains("Meter.swift") ||
123
+        message.contains("data request") ||
124
+        message.contains("Operational state") ||
125
+        message.contains("recordingThreshold") ||
126
+        message.contains("screenTimeout") ||
127
+        message.contains("screenBrightness") ||
128
+        message.contains("volatile memory") ||
129
+        message.contains("charger type") {
130
+        categories.append(.meter)
131
+    }
132
+
133
+    if message.contains("CloudKit") ||
134
+        message.contains("iCloud") ||
135
+        message.contains("ubiquityIdentityToken") {
136
+        categories.append(.cloud)
137
+    }
138
+
139
+    if file.contains("MeterNameStore") ||
140
+        file.contains("ChargerStandbyPowerStore") ||
141
+        message.contains("KVS") ||
142
+        message.contains("ubiquitous") {
143
+        categories.append(.sync)
144
+    }
145
+
146
+    if file.contains("ChargeInsightsStore") ||
147
+        message.contains("promoted legacy") ||
148
+        message.contains("synthesized custom") ||
149
+        message.contains("healed duplicate") {
150
+        categories.append(.migration)
151
+    }
152
+
153
+    if message.contains("notification") ||
154
+        message.contains("remote notifications") {
155
+        categories.append(.notifications)
156
+    }
157
+
158
+    return categories
159
+}
160
+
129 161
 @UIApplicationMain
130 162
 class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
131 163
     private let cloudKitContainerIdentifier = "iCloud.ro.xdev.USB-Meter"
@@ -152,6 +184,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
152 184
 
153 185
     private func logRuntimeICloudDiagnostics() {
154 186
         #if DEBUG
187
+        guard debugLogFlagEnabled(DebugLogFlag.cloud.rawValue) else { return }
155 188
         let hasUbiquityIdentityToken = FileManager.default.ubiquityIdentityToken != nil
156 189
         track("Runtime iCloud diagnostics: ubiquityIdentityTokenAvailable=\(hasUbiquityIdentityToken)")
157 190
         CKContainer(identifier: cloudKitContainerIdentifier).accountStatus { status, error in
+0 -1
USB Meter/Extensions/Data.swift
@@ -23,7 +23,6 @@ extension Data {
23 23
     
24 24
     func value<T>(from: Int) -> T {
25 25
         let to = from + MemoryLayout<T>.size
26
-        //track("size: \(self.count) from:\(from) to:\(to)")
27 26
         return self.subdata(in: from..<to).withUnsafeBytes { $0.load(as: T.self) }
28 27
     }
29 28
 
+5 -10
USB Meter/Model/BluetoothManager.swift
@@ -92,7 +92,6 @@ class BluetoothManager : NSObject, ObservableObject {
92 92
         
93 93
         if appData.meters[peripheral.identifier] == nil {
94 94
             logDiscovery("BLE discovery accepted: model='\(model.canonicalName)', radio='\(radio)', advertisedName='\(advertisedName)', match='\(match.reason)', macAddress='\(macAddressString)'. \(discoveryDescription(peripheral: peripheral, advertising: advertismentData, rssi: RSSI))")
95
-            track("adding new USB Meter named '\(advertisedName)' with MAC Address: '\(macAddress)'")
96 95
             let btSerial = BluetoothSerial(peripheral: peripheral, radio: radio, with: macAddress, managedBy: manager!, RSSI: RSSI.intValue)
97 96
             var m = appData.meters
98 97
             let meter = Meter(model: model, with: btSerial)
@@ -158,11 +157,12 @@ class BluetoothManager : NSObject, ObservableObject {
158 157
 
159 158
     private func logDiscovery(_ message: String) {
160 159
         track(message)
161
-        bluetoothDiscoveryLogger.notice("\(message, privacy: .public)")
160
+        guard debugLogFlagEnabled("USB_METER_BLUETOOTH_LOGS") else { return }
161
+        bluetoothDiscoveryLogger.debug("\(message, privacy: .public)")
162 162
     }
163
-
163
+    
164 164
     private func shouldLogDiscoveryDetails(for identifier: UUID) -> Bool {
165
-        guard ProcessInfo.processInfo.environment["USB_METER_VERBOSE_LOGS"] == "1" else {
165
+        guard debugLogFlagEnabled("USB_METER_BLUETOOTH_LOGS") else {
166 166
             return false
167 167
         }
168 168
         return shouldLogDiscoveryDetails(for: identifier.uuidString)
@@ -228,7 +228,6 @@ extension BluetoothManager : CBCentralManagerDelegate {
228 228
     // MARK:  CBCentralManager state Changed
229 229
     func centralManagerDidUpdateState(_ central: CBCentralManager) {
230 230
         managerState = central.state;
231
-        track("\(central.state)")
232 231
         for meter in appData.meters.values {
233 232
             meter.btSerial.centralStateChanged(to: central.state)
234 233
         }
@@ -237,10 +236,8 @@ extension BluetoothManager : CBCentralManagerDelegate {
237 236
         case .poweredOff:
238 237
             scanStartedAt = nil
239 238
             advertisementDataCache.clear()
240
-            track("Bluetooth is Off. How should I behave?")
241 239
         case .poweredOn:
242 240
             scanStartedAt = Date()
243
-            track("Bluetooth is On... Start scanning...")
244 241
             // note that "didDisconnectPeripheral" won't be called if BLE is turned off while connected
245 242
             // connectedPeripheral = nil
246 243
             // pendingPeripheral = nil
@@ -248,7 +245,7 @@ extension BluetoothManager : CBCentralManagerDelegate {
248 245
         case .resetting:
249 246
             scanStartedAt = nil
250 247
             advertisementDataCache.clear()
251
-            track("Bluetooth is reseting... . Whatever that means.")
248
+            track("Bluetooth is resetting.")
252 249
         case .unauthorized:
253 250
             scanStartedAt = nil
254 251
             advertisementDataCache.clear()
@@ -271,13 +268,11 @@ extension BluetoothManager : CBCentralManagerDelegate {
271 268
     // MARK:  CBCentralManager didDiscover peripheral
272 269
     func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
273 270
         let completeAdvertisementData = self.advertisementDataCache.append(peripheral: peripheral, advertisementData: advertisementData)
274
-        //track("Device discoverded UUID: '\(peripheral.identifier)' named '\(peripheral.name ?? "Unknown")'); RSSI: \(RSSI) dBm; Advertisment data: \(advertisementData)")
275 271
         discoveredMeter(peripheral: peripheral, advertising: completeAdvertisementData, rssi: RSSI )
276 272
     }
277 273
     
278 274
     // MARK:  CBCentralManager didConnect peripheral
279 275
     internal func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
280
-        //track("Connected to peripheral: '\(peripheral.identifier)'")
281 276
         if let usbMeter = appData.meters[peripheral.identifier] {
282 277
             usbMeter.btSerial.connectionEstablished()
283 278
         }
+2 -13
USB Meter/Model/BluetoothSerial.swift
@@ -155,20 +155,17 @@ final class BluetoothSerial : NSObject, ObservableObject {
155 155
      - parameter expectedResponseLength: Optional If message sent require a respnse the length for that response must be provideed. Incomming data will be buffered before calling delegate.didReceiveData
156 156
      */
157 157
     func write(_ data: Data, expectedResponseLength: Int = 0) {
158
-        //track("\(self.expectedResponseLength)")
159
-        //track(data.hexEncodedStringValue)
160 158
         guard operationalState == .peripheralReady else {
161
-            track("Guard: \(operationalState)")
159
+            track("Write skipped while peripheral state is \(operationalState)")
162 160
             return
163 161
         }
164 162
         guard self.expectedResponseLength == 0 else {
165
-            track("Guard: \(self.expectedResponseLength)")
163
+            track("Write skipped while waiting for \(self.expectedResponseLength) response bytes")
166 164
             return
167 165
         }
168 166
         
169 167
         self.expectedResponseLength = expectedResponseLength
170 168
         
171
-//        track("Sending...")
172 169
         guard let writeCharacteristic else {
173 170
             track("Missing write characteristic for \(radio)")
174 171
             self.expectedResponseLength = 0
@@ -177,7 +174,6 @@ final class BluetoothSerial : NSObject, ObservableObject {
177 174
 
178 175
         let writeType: CBCharacteristicWriteType = writeCharacteristic.properties.contains(.writeWithoutResponse) ? .withoutResponse : .withResponse
179 176
         peripheral.writeValue(data, for: writeCharacteristic, type: writeType)
180
-//        track("Sent!")
181 177
         if self.expectedResponseLength != 0 {
182 178
             setWDT()
183 179
         }
@@ -299,7 +295,6 @@ extension BluetoothSerial : CBPeripheralDelegate {
299 295
     
300 296
     //  MARK:   didDiscoverServices
301 297
     func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
302
-        track("\(String(describing: peripheral.services))")
303 298
         if error != nil {
304 299
             track( "Error: \(error!)" )
305 300
         }
@@ -334,7 +329,6 @@ extension BluetoothSerial : CBPeripheralDelegate {
334 329
         if error != nil {
335 330
             track( "Error: \(error!)" )
336 331
         }
337
-        track("\(String(describing: service.characteristics))")
338 332
         switch radio {
339 333
         case .BT18, .BT24M:
340 334
             updateBT18Characteristics(for: service)
@@ -357,7 +351,6 @@ extension BluetoothSerial : CBPeripheralDelegate {
357 351
     
358 352
     //  MARK:   didUpdateValueFor
359 353
     func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
360
-//        track("")
361 354
         if error != nil {
362 355
             track( "Error: \(error!)" )
363 356
         }
@@ -378,14 +371,11 @@ extension BluetoothSerial : CBPeripheralDelegate {
378 371
 
379 372
         let previousBufferCount = buffer.count
380 373
         buffer.append(incomingData)
381
-//        track("\n\(buffer.hexEncodedStringValue)")
382 374
         switch buffer.count {
383 375
         case let x where x < expectedResponseLength:
384 376
             setWDT()
385
-            //track("buffering")
386 377
             break;
387 378
         case let x where x == expectedResponseLength:
388
-            //track("buffer ready")
389 379
             wdTimer?.invalidate()
390 380
             expectedResponseLength = 0
391 381
             delegate?.didReceiveData(buffer)
@@ -405,7 +395,6 @@ extension BluetoothSerial : CBPeripheralDelegate {
405 395
     }
406 396
     
407 397
     func peripheralIsReady(toSendWriteWithoutResponse peripheral: CBPeripheral) {
408
-        //track("")
409 398
     }
410 399
     
411 400
 }
+0 -8
USB Meter/Model/Meter.swift
@@ -778,7 +778,6 @@ class Meter : NSObject, ObservableObject, Identifiable {
778 778
                 btSerial.write(TC66Protocol.snapshotRequest, expectedResponseLength: 192)
779 779
             }
780 780
             dataDumpRequestTimestamp = Date()
781
-            // track("\(name) - Request sent!")
782 781
         } else {
783 782
             track("Request delayed for: \(commandQueue.first!.hexEncodedStringValue)")
784 783
             btSerial.write( commandQueue.first! )
@@ -793,7 +792,6 @@ class Meter : NSObject, ObservableObject, Identifiable {
793 792
      - Decription metod for TC66C AES ECB response  found [here](https:github.com/krzyzanowskim/CryptoSwift/issues/693)
794 793
      */
795 794
     func parseData ( from buffer: Data) {
796
-        //track("\(name)")
797 795
         liveDataChanged = false
798 796
         switch model {
799 797
         case .UM25C:
@@ -825,9 +823,6 @@ class Meter : NSObject, ObservableObject, Identifiable {
825 823
             )
826 824
         }
827 825
         appData.observeChargeSnapshot(from: self, observedAt: dataDumpRequestTimestamp)
828
-//        DispatchQueue.global(qos: .userInitiated).asyncAfter( deadline: .now() + 0.33 ) {
829
-//            //track("\(name) - Scheduled new request.")
830
-//        }
831 826
         if operationalState != .dataIsAvailable {
832 827
             operationalState = .dataIsAvailable
833 828
         } else if liveDataChanged {
@@ -1187,19 +1182,16 @@ class Meter : NSObject, ObservableObject, Identifiable {
1187 1182
     
1188 1183
     func selectDataGroup ( id: UInt8) {
1189 1184
         guard supportsDataGroupCommands else { return }
1190
-        track("\(name) - \(id)")
1191 1185
         selectedDataGroup = id
1192 1186
         objectWillChange.send()
1193 1187
         commandQueue.append(UMProtocol.selectDataGroup(selectedDataGroup))
1194 1188
     }
1195 1189
     
1196 1190
     private func setSceeenBrightness ( to value: UInt8) {
1197
-        track("\(name) - \(value)")
1198 1191
         guard supportsUMSettings else { return }
1199 1192
         commandQueue.append(UMProtocol.setScreenBrightness(value))
1200 1193
     }
1201 1194
     private func setScreenSaverTimeout ( to value: UInt8) {
1202
-        track("\(name) - \(value)")
1203 1195
         guard supportsUMSettings else { return }
1204 1196
         commandQueue.append(UMProtocol.setScreenSaverTimeout(value))
1205 1197
     }