1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * All rights reserved. 4 * 5 * This source code is licensed under the BSD-style license found in the 6 * LICENSE file in the root directory of this source tree. 7 */ 8 9 import SwiftUI 10 11 import ExecuTorch 12 13 struct LogView: View { 14 @ObservedObject var logManager: LogManager 15 16 var body: some View { 17 ScrollView { 18 VStack(alignment: .leading) { 19 ForEach(logManager.logs) { log in 20 Text("\(format(timestamp: log.timestamp)) \(log.filename):\(log.line)") 21 .padding(.top) 22 .foregroundColor(.secondary) 23 .textSelection(.enabled) 24 Text(log.message) 25 .padding(.bottom) 26 .foregroundColor(color(for: log.level)) 27 .textSelection(.enabled) 28 } 29 } 30 } 31 .padding() 32 .defaultScrollAnchor(.bottom) 33 .navigationBarTitle("Logs", displayMode: .inline) 34 .navigationBarItems(trailing: 35 Button(action: { logManager.clear() }) { 36 Image(systemName: "trash") 37 } 38 ) 39 } 40 formatnull41 private func format(timestamp: TimeInterval) -> String { 42 let totalSeconds = Int(timestamp) 43 let hours = (totalSeconds / 3600) % 24 44 let minutes = (totalSeconds / 60) % 60 45 let seconds = totalSeconds % 60 46 let microseconds = Int((timestamp - Double(totalSeconds)) * 1000000) 47 return String(format: "%02d:%02d:%02d.%06d", hours, minutes, seconds, microseconds) 48 } 49 colornull50 private func color(for level: Int) -> Color { 51 switch LogLevel(rawValue: level) { 52 case .debug: 53 return .blue 54 case .info: 55 return .primary 56 case .error: 57 return .red 58 case .fatal: 59 return .purple 60 default: 61 return .secondary 62 } 63 } 64 } 65