secant-ios-wallet/modules/Sources/Dependencies/LogsHandler/LogsHandlerLive.swift

96 lines
3.4 KiB
Swift

//
// LogsHandlerLive.swift
// Zashi
//
// Created by Lukáš Korba on 30.01.2023.
//
import Foundation
import ComposableArchitecture
import OSLog
import Utils
extension LogsHandlerClient: DependencyKey {
public static let liveValue = LogsHandlerClient(
exportAndStoreLogs: { sdkLogs, tcaLogs, walletLogs in
// create a directory
let logsURL = FileManager.default.temporaryDirectory.appendingPathComponent("zashiPrivateData")
try FileManager.default.createDirectory(atPath: logsURL.path, withIntermediateDirectories: true)
// export the logs
async let sdkLogsVerbose = LogsHandlerClient.exportAndStoreLogsFor(
key: sdkLogs,
atURL: logsURL.appendingPathComponent("sdkLogs_verbose.txt")
)
async let sdkLogsSync = LogsHandlerClient.exportAndStoreLogsFor(
key: sdkLogs,
atURL: logsURL.appendingPathComponent("sdkLogs_sync.txt"),
level: .info // The info level represents the sync log in the SDK
)
async let tcaLogs = LogsHandlerClient.exportAndStoreLogsFor(
key: tcaLogs,
atURL: logsURL.appendingPathComponent("tcaLogs.txt")
)
async let walletLogs = LogsHandlerClient.exportAndStoreLogsFor(
key: walletLogs,
atURL: logsURL.appendingPathComponent("walletLogs.txt")
)
let logs = try await [sdkLogsVerbose, sdkLogsSync, tcaLogs, walletLogs]
// store the log files into the logs folder
try logs.forEach { logsHandler in
try logsHandler.result.write(to: logsHandler.dir, atomically: true, encoding: String.Encoding.utf8)
}
// zip the logs folder
let coordinator = NSFileCoordinator()
var zipError: NSError?
var archiveURL: URL?
archiveURL = await withCheckedContinuation { continuation in
coordinator.coordinate(readingItemAt: logsURL, options: [.forUploading], error: &zipError) { zipURL in
do {
let tmpURL = try FileManager.default.url(
for: .itemReplacementDirectory,
in: .userDomainMask,
appropriateFor: zipURL,
create: true
)
.appendingPathComponent("zashiPrivateData.zip")
try FileManager.default.moveItem(at: zipURL, to: tmpURL)
continuation.resume(returning: tmpURL)
} catch {
continuation.resume(returning: nil)
}
}
}
return archiveURL
}
)
}
private extension LogsHandlerClient {
static func exportAndStoreLogsFor(
key: String,
atURL: URL,
level: OSLogEntryLog.Level = .debug
) async throws -> (result: String, dir: URL) {
let logsStr = try await LogStore.exportCategory(
key,
level: level,
fileSize: 2_000_000 // ~ 2MB of data
)
var result = ""
logsStr?.forEach({ line in
result.append(line)
result.append("\n\n")
})
return (result: result, dir: atURL)
}
}