commit 3745daec876d0e23aca0b827481fb9ad6d76c287
parent 5a206a0935844ddfea8079e4fc1108fcfd5ddc2d
Author: Marc Stibane <marc@taler.net>
Date: Tue, 27 Jun 2023 14:40:22 +0200
Logging
Diffstat:
8 files changed, 64 insertions(+), 57 deletions(-)
diff --git a/TalerWallet1/Backend/WalletCore.swift b/TalerWallet1/Backend/WalletCore.swift
@@ -70,43 +70,46 @@ class WalletCore: QuickjsMessageHandler {
}
deinit {
- symLog.log()
+ logger.log("shutdown Quickjs")
// TODO: send shutdown message to talerWalletInstance
// quickjs.waitStopped()
}
init() throws {
- symLog.log("alloc.init wallet-core")
+ logger.info("init Quickjs")
requestsMade = 0
queue = DispatchQueue(label: "net.taler.myQueue", attributes: .concurrent)
semaphore = DispatchSemaphore(value: 1)
quickjs = Quickjs()
quickjs.messageHandler = self
- symLog.log("wallet-core done")
+ logger.log("Quickjs running")
}
}
// MARK: - completionHandler functions
extension WalletCore {
private func handleError(_ decoded: ResponseOrNotification) throws {
guard let requestId = decoded.id else {
- symLog.log(decoded) // TODO: .error
+ logger.error("didn't find requestId in error response")
+ // TODO: show error alert
throw WalletBackendError.deserializationError
}
guard let (timeSent, completion) = completions[requestId] else {
- symLog.log("requestId \(requestId) not in list") // TODO: .error
+ logger.error("requestId \(requestId, privacy: .public) not in list")
+ // TODO: show error alert
throw WalletBackendError.deserializationError
}
completions[requestId] = nil
if let walletError = decoded.error { // wallet-core sent an error message
do {
let jsonData = try JSONEncoder().encode(walletError)
- // TODO: Error handling
} catch { // JSON encoding of response.result failed / should never happen
- symLog.log(walletError) // TODO: .error
+ symLog.log(decoded)
+ logger.error("cannot encode wallet-core Error")
+ // TODO: show error alert
completion(requestId, timeSent, nil, WalletCore.parseFailureError())
}
-
// TODO: decode jsonData to WalletBackendResponseError - or HTTPError
+ logger.error("wallet-core sent back an error for request \(requestId, privacy: .public)")
// completion(requestId, timeSent, nil, walletError)
completion(requestId, timeSent, nil, WalletCore.parseFailureError())
} else { // JSON decoding of error message failed
@@ -115,21 +118,23 @@ extension WalletCore {
}
private func handleResponse(_ decoded: ResponseOrNotification) throws {
guard let requestId = decoded.id else {
+ logger.error("didn't find requestId in response")
symLog.log(decoded) // TODO: .error
throw WalletBackendError.deserializationError
}
guard let (timeSent, completion) = completions[requestId] else {
- symLog.log("requestId \(requestId) not in list") // TODO: .error
+ logger.error("requestId \(requestId, privacy: .public) not in list")
throw WalletBackendError.deserializationError
}
completions[requestId] = nil
guard let result = decoded.result else {
- symLog.log("requestId \(requestId) got no result") // TODO: .error
+ logger.error("requestId \(requestId, privacy: .public) got no result")
throw WalletBackendError.deserializationError
}
do {
let jsonData = try JSONEncoder().encode(result)
- symLog.log(result) // TODO: .info
+ symLog.log(result)
+// logger.info(result) TODO: log result
completion(requestId, timeSent, jsonData, nil)
} catch { // JSON encoding of response.result failed / should never happen
symLog.log(result) // TODO: .error
@@ -149,7 +154,7 @@ extension WalletCore {
Task {
if let userInfo { symLog.log(userInfo) } else { symLog.log(aName) }
await postNotificationM(aName, object: anObject, userInfo: userInfo)
- symLog.log("sent " + aName.rawValue)
+ logger.log("Notification sent: \(aName.rawValue)")
}
}
@@ -174,8 +179,7 @@ extension WalletCore {
// symLog.log("\(pendingOp): \(id)")
} else {
// TODO: handle other pending-operation-processed
-print("\n❗️ \(pendingOp): \(id)\n") // this is a new pendingOp I haven't seen before
- print("\n")
+ logger.log("❗️ \(pendingOp, privacy: .public): \(id, privacy: .public)") // this is a new pendingOp I haven't seen before
}
}
private func handleStateTransition(_ jsonData: Data) throws {
@@ -298,16 +302,17 @@ print("\n❗️ WalletCore.swift:226 Notification: ", anyPayload, "\n") /
let now = Date.now
do {
let full = FullRequest(operation: request.operation, id: requestId, args: request.args)
-// symLog.log(full)
+// symLog.log(full)
let encoded = try JSONEncoder().encode(full)
guard let jsonString = String(data: encoded, encoding: .utf8) else { throw WalletBackendError.serializationError }
self.completions[requestId] = (now, completionHandler)
self.requestsMade += 1
self.semaphore.signal() // free requestsMade
- self.symLog.log(jsonString)
+ self.symLog.log(jsonString)
self.quickjs.sendMessage(message: jsonString)
} catch { // call completion
self.semaphore.signal()
+ self.symLog.log(error)
completionHandler(requestId, now, nil, WalletCore.serializeRequestError());
}
}
diff --git a/TalerWallet1/Controllers/DebugViewC.swift b/TalerWallet1/Controllers/DebugViewC.swift
@@ -21,6 +21,7 @@
*/
import SwiftUI
import SymLog
+import os.log
// Numbering Scheme for Views
// MARK: - Main View
@@ -97,8 +98,8 @@ struct DebugViewV: View {
var body: some View {
#if DEBUG
- let _ = Self._printChanges()
- let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear
+// let _ = Self._printChanges()
+// let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear
#endif
let viewIDString = debugViewC.viewID > 0 ? String(debugViewC.viewID)
: ""
@@ -118,6 +119,7 @@ class DebugViewC: ObservableObject {
private let symLog = SymLogC(0) // 0 to switch off viewID change logging
public static let shared = DebugViewC()
@AppStorage("developerMode") var developerMode: Bool = false
+ let logger = Logger (subsystem: "net.taler.gnu", category: "DebugView")
@Published var viewID: Int = 0
@Published var sheetID: Int = 0
@@ -126,19 +128,24 @@ class DebugViewC: ObservableObject {
if developerMode {
if viewID == 0 {
symLog.log("switching ON, \(newID)")
+ logger.info("switching ON, \(newID, privacy: .public)")
viewID = newID // publish ON
} else if viewID != newID {
symLog.log("switching from \(viewID) to \(newID)")
+ logger.info("switching from \(self.viewID, privacy: .public) to \(newID, privacy: .public)")
viewID = newID // publish new viewID
} else {
symLog.log("\(newID) stays")
+ logger.info("\(newID, privacy: .public) stays")
// don't set viewID to the same value, it would just trigger an unneccessary redraw
}
} else if viewID > 0 {
symLog.log("switching OFF, will not use \(newID)")
+ logger.info("switching OFF, will not use \(newID, privacy: .public)")
viewID = 0 // publish OFF
} else {
symLog.log("off, will not use \(newID)")
+ logger.info("off, will not use \(newID, privacy: .public)")
// don't set viewID from 0 to 0 again, it would just trigger an unneccessary redraw
}
}
@@ -147,17 +154,21 @@ class DebugViewC: ObservableObject {
if developerMode {
if sheetID != newID {
symLog.log("switching from \(sheetID) to \(newID)")
+ logger.info("switching from \(self.sheetID, privacy: .public) to \(newID, privacy: .public) for sheet")
sheetID = newID // publish new sheetID
} else {
symLog.log("\(newID) stays")
+ logger.info("\(newID, privacy: .public) stays for sheet")
// don't set sheetID to the same value, it would just trigger an unneccessary redraw
}
} else if sheetID > 0 {
// might happen after switching DevMode off, if sheetID still has the old value of the last sheet
symLog.log("switching OFF, will not use \(newID)")
+ logger.info("switching OFF, will not use \(newID, privacy: .public) for sheet")
sheetID = 0 // publish OFF
} else {
symLog.log("off, will not use \(newID)")
+ logger.info("off, will not use \(newID, privacy: .public) for sheet")
// don't set sheetID from 0 to 0 again, it would just trigger an unneccessary redraw
}
}
diff --git a/TalerWallet1/Controllers/TalerWallet1App.swift b/TalerWallet1/Controllers/TalerWallet1App.swift
@@ -11,6 +11,7 @@
import BackgroundTasks
import SwiftUI
import SymLog
+import os.log
@main
struct TalerWallet1App: App {
@@ -24,9 +25,10 @@ struct TalerWallet1App: App {
private let controller = Controller.shared
private let model = WalletModel.shared
private let debugViewC = DebugViewC.shared
+ let logger = Logger (subsystem: "net.taler.gnu", category: "Main App")
func scheduleAppRefresh() {
- let request = BGAppRefreshTaskRequest(identifier: "net.taler.refresh")
+ let request = BGAppRefreshTaskRequest(identifier: "net.taler.gnu.refresh")
request.earliestBeginDate = .now.addingTimeInterval(24 * 3600)
try? BGTaskScheduler.shared.submit(request)
}
@@ -42,33 +44,31 @@ struct TalerWallet1App: App {
/// we handle them in .onOpenURL in MainView.swift
.handlesExternalEvents(preferring: ["*"], allowing: ["*"])
.task {
- symLog.log("task -> initWalletCore")
- try! await controller.initWalletCoreM(model) // will (and should) crash on failure
- symLog.log("task -> initWalletCore done")
+ try! await controller.initWalletCore(model) // will (and should) crash on failure
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification, object: nil)) { _ in
- symLog.log("❗️App Did Become Active notification")
+ logger.log("❗️App Did Become Active")
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification, object: nil)) { _ in
- symLog.log("❗️App Will Resign notification")
+ logger.log("❗️App Will Resign")
isActive = false
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification, object: nil)) { _ in
- symLog.log("❗️App Will Enter Foreground notification")
+ logger.log("❗️App Will Enter Foreground")
isActive = true
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willTerminateNotification, object: nil)) { _ in
- symLog.log("❗️App Will Terminate notification")
+ logger.log("❗️App Will Terminate")
}
}
.onChange(of: phase) { newPhase in
switch newPhase {
case .active:
- symLog.log("❗️ .onChange(of: phase) ==> newPhase: Active")
+ logger.log("❗️.onChange() ==> Active")
case .background:
- symLog.log("❗️ .onChange(of: phase) ==> newPhase: Background)")
- scheduleAppRefresh()
+ logger.log("❗️.onChange() ==> Background)")
+// scheduleAppRefresh()
default: break
}
}
@@ -101,9 +101,10 @@ struct TalerWallet1App: App {
final class ViewState : ObservableObject {
static let shared = ViewState()
@Published var rootViewId = UUID()
+ let logger = Logger (subsystem: "net.taler.gnu", category: "ViewState")
public func popToRootView() -> Void {
- let _ = symLog()
+ logger.info("popToRootView")
rootViewId = UUID() // setting a new ID will cause tableView popToRootView behaviour
}
diff --git a/TalerWallet1/Model/Model+Balances.swift b/TalerWallet1/Model/Model+Balances.swift
@@ -47,7 +47,6 @@ extension WalletModel {
async -> [Balance] { // M for MainActor
do {
let request = Balances()
- logger.info("balancesM")
let response = try await sendRequest(request, ASYNCDELAY)
return response.balances // trigger view update in BalancesListView
} catch {
diff --git a/TalerWallet1/Model/Model+Exchange.swift b/TalerWallet1/Model/Model+Exchange.swift
@@ -81,14 +81,12 @@ fileprivate struct AddExchange: WalletBackendFormattedRequest {
extension WalletModel {
/// ask wallet-core for its list of known exchanges
@MainActor func listExchangesM()
- async -> [Exchange] { // M for MainActor
+ async -> [Exchange] { // M for MainActor
do {
let request = ListExchanges()
- logger.info("ListExchanges")
let response = try await sendRequest(request, ASYNCDELAY)
return response.exchanges
} catch {
- logger.error("listExchangesM failed: \(error)")
return [] // empty, but not nil
}
}
@@ -96,9 +94,8 @@ extension WalletModel {
/// add a new exchange with URL to the wallet's list of known exchanges
func addExchange(url: String)
async throws {
- symLog?.log("adding exchange: \(url)") // TODO: .notice
let request = AddExchange(exchangeBaseUrl: url)
- logger.info("adding exchange: \(url, privacy: .public)")
+ logger.info("adding exchange: \(url, privacy: .public)")
_ = try await sendRequest(request)
}
}
diff --git a/TalerWallet1/Model/WalletModel.swift b/TalerWallet1/Model/WalletModel.swift
@@ -4,7 +4,7 @@
*/
import Foundation
import SymLog
-import os
+import os.log
fileprivate let DATABASE = "talerwalletdb-v30"
fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for debugging
@@ -16,31 +16,28 @@ class WalletModel: ObservableObject {
public static let shared = WalletModel(0)
static func className() -> String {"\(self)"}
var symLog: SymLogC?
- let logger = Logger (subsystem: "net.taler.gnu", category: "wallet-core")
init(_ symbol: Int) { // init with 0 to disable logging for this class
self.symLog = SymLogC(symbol == 0 ? 0 : -1, funcName: Self.className())
}
+ let logger = Logger (subsystem: "net.taler.gnu", category: "WalletModel")
func sendRequest<T: WalletBackendFormattedRequest> (_ request: T, _ delay: UInt = 0)
async throws -> T.Response { // T for any Thread
- symLog?.log("sending: \(request)")
+ logger.log("sending: \(request.operation(), privacy: .public)")
let sendTime = Date.now
do {
let (response, id) = try await WalletCore.shared.sendFormattedRequest(request: request)
let timeUsed = Date.now - sendTime
+ logger.log("received: \(request.operation(), privacy: .public) (\(id, privacy: .public)) after \(timeUsed.milliseconds, privacy: .public) ms")
let asyncDelay: UInt = delay > 0 ? delay : UInt(ASYNCDELAY)
if asyncDelay > 0 { // test LoadingView, sleep some seconds
- symLog?.log("received: (\(id)) after \(timeUsed.milliseconds) ms, going to sleep for \(asyncDelay) seconds...")
try? await Task.sleep(nanoseconds: 1_000_000_000 * UInt64(asyncDelay))
- symLog?.log("(\(id)) waking up again after \(asyncDelay) seconds, will deliver \(response)")
- } else {
- symLog?.log("received: (\(id)) after \(timeUsed.milliseconds) ms, \(response)")
}
return response
} catch { // rethrows
let timeUsed = Date.now - sendTime
- symLog?.log("Yikes❗️ \(request.operation()) failed after \(timeUsed.milliseconds) ms")
+ logger.error("\(request.operation(), privacy: .public) failed after \(timeUsed.milliseconds, privacy: .public) ms\n\(error)")
throw error
}
}
@@ -106,16 +103,11 @@ fileprivate struct InitRequest: WalletBackendFormattedRequest {
extension WalletModel {
/// initalize Wallet-Core. Will do networking
func initWalletCoreT() async throws -> VersionInfo {
- do { // T for any Thread
- let docPath = try docPath()
- let request = InitRequest(persistentStoragePath: docPath)
- logger.info("initWalletCoreT")
- let response = try await sendRequest(request, 0) // no Delay
- return response.versionInfo
- } catch {
- logger.error("initWalletCoreT failed: \(error)")
- throw error
- }
+ // T for any Thread
+ let docPath = try docPath()
+ let request = InitRequest(persistentStoragePath: docPath)
+ let response = try await sendRequest(request, 0) // no Delay
+ return response.versionInfo
}
private func docPath () throws -> String {
@@ -128,7 +120,6 @@ extension WalletModel {
logger.debug("\(docPath)")
return docPath
} else { // should never happen
- symLog?.log("Yikes❗️ documentURLs empty")
logger.error("documentURLs empty")
throw WalletBackendError.initializationError
}
diff --git a/TalerWallet1/Views/Balances/BalancesListView.swift b/TalerWallet1/Views/Balances/BalancesListView.swift
@@ -95,7 +95,7 @@ struct BalancesListView: View {
Sheet(sheetView: sheet)
} // sheet
.task {
- symLog.log(".task fetchBalancesM")
+ symLog.log(".task getBalances")
await reloadAction()
} // task
}
diff --git a/TalerWallet1/Views/Balances/BalancesSectionView.swift b/TalerWallet1/Views/Balances/BalancesSectionView.swift
@@ -190,12 +190,15 @@ struct BalancesSectionView: View {
}.id(sectionID)
.task {
if shownSectionID != sectionID {
- symLog.log("task for BalancesSectionView \(sectionID)")
let response = await model.fetchTransactionsT(currency: currency)
+ symLog.log("task for BalancesSectionView \(sectionID) - reload Transactions")
transactions = response
pendingTransactions = WalletModel.pendingTransactions(response)
uncompletedTransactions = WalletModel.uncompletedTransactions(response)
shownSectionID = sectionID
+ } else {
+ symLog.log("task for BalancesSectionView \(sectionID) ❗️ skip reloading Transactions")
+
}
}
} // body