mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Debug log updates
This commit is contained in:
parent
2b9a4bcdbc
commit
544bbd3621
8 changed files with 174 additions and 29 deletions
|
|
@ -208,6 +208,7 @@
|
|||
DDF45C372BC46A5A005ED5F2 /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF45C362BC46A5A005ED5F2 /* TimeZone.swift */; };
|
||||
DDF6B2482A9AEBF500BA6931 /* StoreForwardConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF6B2472A9AEBF500BA6931 /* StoreForwardConfig.swift */; };
|
||||
DDF8E1F42C10125B0019C87E /* AppLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF8E1F32C10125B0019C87E /* AppLog.swift */; };
|
||||
DDF8E1F92C115CCE0019C87E /* LogDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF8E1F82C115CCE0019C87E /* LogDetail.swift */; };
|
||||
DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF924C926FBB953009FE055 /* ConnectedDevice.swift */; };
|
||||
DDFEB3BB29900C1200EE7472 /* CurrentConditionsCompact.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFEB3BA29900C1200EE7472 /* CurrentConditionsCompact.swift */; };
|
||||
DDFFA7472B3A7F3C004730DB /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDFFA7462B3A7F3C004730DB /* Bundle.swift */; };
|
||||
|
|
@ -483,6 +484,7 @@
|
|||
DDF6B2472A9AEBF500BA6931 /* StoreForwardConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreForwardConfig.swift; sourceTree = "<group>"; };
|
||||
DDF6B24B2A9C2FC800BA6931 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
DDF8E1F32C10125B0019C87E /* AppLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLog.swift; sourceTree = "<group>"; };
|
||||
DDF8E1F82C115CCE0019C87E /* LogDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogDetail.swift; sourceTree = "<group>"; };
|
||||
DDF924C926FBB953009FE055 /* ConnectedDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectedDevice.swift; sourceTree = "<group>"; };
|
||||
DDFEB3BA29900C1200EE7472 /* CurrentConditionsCompact.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentConditionsCompact.swift; sourceTree = "<group>"; };
|
||||
DDFFA7462B3A7F3C004730DB /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -894,6 +896,7 @@
|
|||
DDB75A1D2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift */,
|
||||
DDB75A202A12B954006ED576 /* LoRaSignalStrength.swift */,
|
||||
DDB75A222A13CDA9006ED576 /* BatteryLevelCompact.swift */,
|
||||
DDF8E1F82C115CCE0019C87E /* LogDetail.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1197,6 +1200,7 @@
|
|||
DD5E5208298EE33B00D21B61 /* rtttl.pb.swift in Sources */,
|
||||
DD6193792863875F00E59241 /* SerialConfig.swift in Sources */,
|
||||
DDDB263F2AABEE20003AFCB7 /* NodeList.swift in Sources */,
|
||||
DDF8E1F92C115CCE0019C87E /* LogDetail.swift in Sources */,
|
||||
DDA0B6B2294CDC55001356EC /* Channels.swift in Sources */,
|
||||
DDE9659C2B1C3B6A00531070 /* RouteRecorder.swift in Sources */,
|
||||
B399E8A42B6F486400E4488E /* RetryButton.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -37,14 +37,8 @@ extension Logger {
|
|||
|
||||
try Task.checkCancellation()
|
||||
|
||||
if let log = entry as? OSLogEntryLog {
|
||||
logs.append(log)
|
||||
// logs.append("""
|
||||
// \(entry.date.formatted(.dateTime.hour(.twoDigits(amPM: .omitted)).minute().second().secondFraction(.fractional(3)))) \(log.level.description) \
|
||||
// \(log.category) \(entry.composedMessage)\n
|
||||
// """)
|
||||
} else {
|
||||
// logs.append("\(entry.date): \(entry.composedMessage)\n")
|
||||
if let log = entry as? OSLogEntryLog {
|
||||
logs.append(log)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,14 +48,14 @@ extension Logger {
|
|||
}
|
||||
|
||||
extension OSLogEntryLog.Level {
|
||||
fileprivate var description: String {
|
||||
var description: String {
|
||||
switch self {
|
||||
case .undefined: "undefined"
|
||||
case .debug: "Debug"
|
||||
case .info: "Info"
|
||||
case .notice: "Notice"
|
||||
case .error: "Error"
|
||||
case .fault: "Fault"
|
||||
case .debug: "🐛 Debug"
|
||||
case .info: "ℹ️ Info"
|
||||
case .notice: "⚠️ Notice"
|
||||
case .error: "🚨 Error"
|
||||
case .fault: "💥 Fault"
|
||||
@unknown default: "default"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
let context = ["name": "\(peripheral.name ?? "Unknown")"]
|
||||
timeoutTimer = Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(timeoutTimerFired), userInfo: context, repeats: true)
|
||||
RunLoop.current.add(timeoutTimer!, forMode: .common)
|
||||
Logger.services.info("ℹ️ BLE Connecting: \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.info("ℹ️ BLE Connecting: \(peripheral.name ?? "Unknown", privacy: .public)")
|
||||
}
|
||||
|
||||
// Disconnect Connected Peripheral
|
||||
|
|
@ -259,12 +259,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
manager.schedule()
|
||||
}
|
||||
lastConnectionError = "🚨 \(e.localizedDescription)"
|
||||
Logger.services.error("🚨 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(e.localizedDescription)")
|
||||
Logger.services.error("🚫 BLE Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode) Error: \(e.localizedDescription)")
|
||||
}
|
||||
} else {
|
||||
// Disconnected without error which indicates user intent to disconnect
|
||||
// Happens when swiping to disconnect
|
||||
Logger.services.info("ℹ️ BLE Disconnected: \(peripheral.name ?? "Unknown"): User Initiated Disconnect")
|
||||
Logger.services.info("🚫 BLE Disconnected: \(peripheral.name ?? "Unknown"): User Initiated Disconnect")
|
||||
}
|
||||
// Start a scan so the disconnected peripheral is moved to the peripherals[] if it is awake
|
||||
self.startScanning()
|
||||
|
|
@ -3021,7 +3021,7 @@ extension BLEManager: CBCentralManagerDelegate {
|
|||
|
||||
if self.automaticallyReconnect && peripheral.identifier.uuidString == UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? "" {
|
||||
self.connectTo(peripheral: peripheral)
|
||||
Logger.services.info("BLE Reconnecting to prefered peripheral: \(peripheral.name ?? "Unknown")")
|
||||
Logger.services.info("🔄 BLE Reconnecting to prefered peripheral: \(peripheral.name ?? "Unknown")")
|
||||
}
|
||||
let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String
|
||||
let device = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: name ?? "Unknown", shortName: "?", longName: name ?? "Unknown", firmwareVersion: "Unknown", rssi: RSSI.intValue, lastUpdate: Date(), peripheral: peripheral)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import OSLog
|
|||
|
||||
class MeshtasticAppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, ObservableObject {
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
||||
Logger.services.info("🚀 Meshtstic Apple App launched!")
|
||||
Logger.services.info("🚀 Meshtastic Apple App launched!")
|
||||
// Default User Default Values
|
||||
UserDefaults.standard.register(defaults: ["meshMapRecentering": true])
|
||||
UserDefaults.standard.register(defaults: ["meshMapShowNodeHistory": true])
|
||||
|
|
|
|||
129
Meshtastic/Views/Helpers/LogDetail.swift
Normal file
129
Meshtastic/Views/Helpers/LogDetail.swift
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
//
|
||||
// LogDetail.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Copyright(c) Garth Vander Houwen 6/5/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
import OSLog
|
||||
|
||||
@available(iOS 17.0, macOS 14.0, *)
|
||||
struct LogDetail: View {
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
var log: OSLogEntryLog
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack {
|
||||
HStack {
|
||||
Text("OS Log Entry Details")
|
||||
.font(.largeTitle)
|
||||
}
|
||||
Divider()
|
||||
HStack(alignment: .top) {
|
||||
VStack(alignment: .leading) {
|
||||
List {
|
||||
/// Time
|
||||
Label {
|
||||
Text("time".localized + ":")
|
||||
.font(.title)
|
||||
LastHeardText(lastHeard: log.date)
|
||||
.font(.title)
|
||||
} icon: {
|
||||
Image(systemName: "timer")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(.title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
/// Subsystem
|
||||
Label {
|
||||
Text("subsystem".localized + ":")
|
||||
.font(.title)
|
||||
Text(log.subsystem)
|
||||
.font(.title)
|
||||
} icon: {
|
||||
Image(systemName: "gear")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(.title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
/// Process
|
||||
Label {
|
||||
Text("process".localized + ":")
|
||||
.font(.title)
|
||||
Text(log.process)
|
||||
.font(.title)
|
||||
} icon: {
|
||||
Image(systemName: "tag")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(.title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
/// Category
|
||||
Label {
|
||||
Text("category".localized + ":")
|
||||
.font(.title)
|
||||
Text(log.category)
|
||||
.font(.title)
|
||||
} icon: {
|
||||
Image(systemName: "rectangle.3.group")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(.title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
/// Level
|
||||
Label {
|
||||
Text("level".localized + ":")
|
||||
.font(.title)
|
||||
Text(log.level.description)
|
||||
.font(.title)
|
||||
} icon: {
|
||||
Image(systemName: "shield")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(.title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
/// message
|
||||
Label {
|
||||
Text("message".localized + ":")
|
||||
.font(.title)
|
||||
Text(log.composedMessage)
|
||||
.font(.title)
|
||||
} icon: {
|
||||
Image(systemName: "text.bubble")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.font(.title)
|
||||
.frame(width: 35)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.top)
|
||||
#if targetEnvironment(macCatalyst)
|
||||
Spacer()
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("close", systemImage: "xmark")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
.controlSize(.large)
|
||||
.padding(.bottom)
|
||||
#endif
|
||||
}
|
||||
.presentationDetents([.fraction(0.65), .fraction(0.75), .fraction(0.85)])
|
||||
.presentationDragIndicator(.visible)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ struct PositionPopover: View {
|
|||
var popover: Bool = true
|
||||
let distanceFormatter = MKDistanceFormatter()
|
||||
var delay: Double = 0
|
||||
|
||||
@State private var scale: CGFloat = 0.5
|
||||
var body: some View {
|
||||
// Node Color from node.num
|
||||
|
|
|
|||
|
|
@ -13,12 +13,11 @@ struct AppLog: View {
|
|||
|
||||
@State private var logs: [OSLogEntryLog] = []
|
||||
@State private var sortOrder = [KeyPathComparator(\OSLogEntryLog.date)]
|
||||
@State private var selection = Set<OSLogEntryLog.ID>()
|
||||
@State private var selection: OSLogEntry.ID?
|
||||
@State private var selectedLog: OSLogEntryLog?
|
||||
@State private var presentingErrorDetails: Bool = false
|
||||
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
|
||||
let dateFormatStyle = Date.FormatStyle()
|
||||
.year(.twoDigits)
|
||||
.month(.defaultDigits)
|
||||
.day(.defaultDigits)
|
||||
private let dateFormatStyle = Date.FormatStyle()
|
||||
.hour(.twoDigits(amPM: .omitted))
|
||||
.minute()
|
||||
.second()
|
||||
|
|
@ -28,23 +27,41 @@ struct AppLog: View {
|
|||
|
||||
Table(logs, selection: $selection, sortOrder: $sortOrder) {
|
||||
if idiom != .phone {
|
||||
TableColumn("Date", value: \.date) { value in
|
||||
TableColumn("Time", value: \.date) { value in
|
||||
Text(value.date.formatted(dateFormatStyle))
|
||||
}
|
||||
.width(min: 150, max: 200)
|
||||
.width(min: 100, max: 125)
|
||||
TableColumn("Category", value: \.category)
|
||||
.width(min: 100, max: 125)
|
||||
TableColumn("Level") { value in
|
||||
Text(value.level.description)
|
||||
}
|
||||
.width(min: 50, max: 100)
|
||||
}
|
||||
TableColumn("Message", value: \.composedMessage)
|
||||
.width(ideal: 200, max: .infinity)
|
||||
|
||||
}
|
||||
.onChange(of: sortOrder) { _, sortOrder in
|
||||
logs.sort(using: sortOrder)
|
||||
withAnimation {
|
||||
logs.sort(using: sortOrder)
|
||||
}
|
||||
}
|
||||
.onChange(of: selection) { newSelection in
|
||||
presentingErrorDetails = true
|
||||
let log = logs.first {
|
||||
$0.id == newSelection
|
||||
}
|
||||
selectedLog = log
|
||||
}
|
||||
.sheet(item: $selectedLog) { log in
|
||||
LogDetail(log: log)
|
||||
.padding()
|
||||
}
|
||||
.task {
|
||||
logs = await fetchLogs()
|
||||
}
|
||||
.navigationTitle("Debug Logs")
|
||||
.navigationBarTitle("Debug Logs", displayMode: .inline)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ struct Settings: View {
|
|||
Label {
|
||||
Text("Debug Logs")
|
||||
} icon: {
|
||||
Image(systemName: "building.columns")
|
||||
Image(systemName: "ladybug")
|
||||
}
|
||||
}
|
||||
.tag(SettingsSidebar.appLog)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue