mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-16 12:30:29 +00:00
Add rust logs
This commit is contained in:
parent
3c8cb48b85
commit
d6a9e190c2
2 changed files with 158 additions and 1 deletions
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import os.log
|
||||
|
||||
class LogManager: ObservableObject {
|
||||
static let shared = LogManager()
|
||||
|
|
@ -13,6 +14,13 @@ class LogManager: ObservableObject {
|
|||
@Published var logs: [LogEntry] = []
|
||||
@Published var errorCount: Int = 0
|
||||
|
||||
// Add properties to capture stdout/stderr
|
||||
private var stdoutPipe: Pipe?
|
||||
private var stderrPipe: Pipe?
|
||||
private var originalStdout: Int32 = -1
|
||||
private var originalStderr: Int32 = -1
|
||||
private let logQueue = DispatchQueue(label: "com.stikjit.logQueue")
|
||||
|
||||
struct LogEntry: Identifiable {
|
||||
let id = UUID()
|
||||
let timestamp: Date
|
||||
|
|
@ -31,6 +39,155 @@ class LogManager: ObservableObject {
|
|||
// Add initial system info logs
|
||||
addInfoLog("StikJIT starting up")
|
||||
addInfoLog("Initializing environment")
|
||||
|
||||
// Set up stdout and stderr capture
|
||||
captureStandardOutput()
|
||||
|
||||
// Register for system log notifications
|
||||
#if os(macOS)
|
||||
// On macOS, also listen for system log messages
|
||||
setupMacOSLogCapture()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
private func setupMacOSLogCapture() {
|
||||
// On macOS we can use the OSLog system
|
||||
// This is a placeholder for macOS-specific log capture
|
||||
// Start a background task to read system logs
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
self.captureSystemLogs()
|
||||
}
|
||||
}
|
||||
|
||||
private func captureSystemLogs() {
|
||||
// This is a basic implementation to capture macOS logs
|
||||
// A more comprehensive solution would use the OSLog framework
|
||||
let task = Process()
|
||||
let pipe = Pipe()
|
||||
|
||||
task.executableURL = URL(fileURLWithPath: "/usr/bin/log")
|
||||
task.arguments = ["stream", "--style", "compact"]
|
||||
task.standardOutput = pipe
|
||||
|
||||
pipe.fileHandleForReading.readabilityHandler = { [weak self] handle in
|
||||
let data = handle.availableData
|
||||
if let string = String(data: data, encoding: .utf8), !string.isEmpty {
|
||||
self?.processStandardOutputLine(string, isError: false)
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
try task.run()
|
||||
} catch {
|
||||
self.addErrorLog("Failed to capture system logs: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Function to capture standard output and standard error
|
||||
private func captureStandardOutput() {
|
||||
#if DEBUG && targetEnvironment(simulator)
|
||||
// Skip capturing in simulator debug builds to ensure logs appear in Xcode console
|
||||
return
|
||||
#endif
|
||||
|
||||
// Save original file descriptors safely
|
||||
if FileHandle.standardOutput.fileDescriptor >= 0 {
|
||||
originalStdout = dup(FileHandle.standardOutput.fileDescriptor)
|
||||
}
|
||||
if FileHandle.standardError.fileDescriptor >= 0 {
|
||||
originalStderr = dup(FileHandle.standardError.fileDescriptor)
|
||||
}
|
||||
|
||||
// Create pipes
|
||||
stdoutPipe = Pipe()
|
||||
stderrPipe = Pipe()
|
||||
|
||||
// Redirect stdout and stderr to our pipes only if valid
|
||||
if let stdoutPipe = stdoutPipe, FileHandle.standardOutput.fileDescriptor >= 0 {
|
||||
dup2(stdoutPipe.fileHandleForWriting.fileDescriptor, FileHandle.standardOutput.fileDescriptor)
|
||||
}
|
||||
if let stderrPipe = stderrPipe, FileHandle.standardError.fileDescriptor >= 0 {
|
||||
dup2(stderrPipe.fileHandleForWriting.fileDescriptor, FileHandle.standardError.fileDescriptor)
|
||||
}
|
||||
|
||||
// Start reading from the pipes on a background queue to avoid blocking
|
||||
stdoutPipe?.fileHandleForReading.readabilityHandler = { [weak self] handle in
|
||||
let data = handle.availableData
|
||||
if !data.isEmpty, let string = String(data: data, encoding: .utf8) {
|
||||
// Write back to original stdout for console viewing
|
||||
if let strongSelf = self, strongSelf.originalStdout >= 0 {
|
||||
write(strongSelf.originalStdout, string, string.utf8.count)
|
||||
}
|
||||
|
||||
self?.logQueue.async {
|
||||
self?.processStandardOutputLine(string, isError: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stderrPipe?.fileHandleForReading.readabilityHandler = { [weak self] handle in
|
||||
let data = handle.availableData
|
||||
if !data.isEmpty, let string = String(data: data, encoding: .utf8) {
|
||||
// Write back to original stderr for console viewing
|
||||
if let strongSelf = self, strongSelf.originalStderr >= 0 {
|
||||
write(strongSelf.originalStderr, string, string.utf8.count)
|
||||
}
|
||||
|
||||
self?.logQueue.async {
|
||||
self?.processStandardOutputLine(string, isError: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also set up a timer to periodically flush stdout/stderr
|
||||
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] _ in
|
||||
self?.flushPipes()
|
||||
}
|
||||
}
|
||||
|
||||
private func flushPipes() {
|
||||
// Force flush the pipes to ensure all output is captured
|
||||
fflush(stdout)
|
||||
fflush(stderr)
|
||||
}
|
||||
|
||||
// Process standard output/error lines and add to logs
|
||||
private func processStandardOutputLine(_ line: String, isError: Bool) {
|
||||
// Split multi-line output
|
||||
let lines = line.components(separatedBy: .newlines)
|
||||
|
||||
for line in lines where !line.isEmpty {
|
||||
// Determine log type based on content
|
||||
let type: LogEntry.LogType
|
||||
|
||||
// Check for error indicators
|
||||
if line.contains("[ERROR]") || line.contains("Error:") || line.contains("error:") ||
|
||||
line.contains("ERROR:") || line.contains("Failed") || (isError && !line.contains("DEBUG")) {
|
||||
type = .error
|
||||
}
|
||||
// Check for warning indicators
|
||||
else if line.contains("[WARNING]") || line.contains("Warning:") || line.contains("warning:") ||
|
||||
line.contains("WARN:") || line.contains("WARNING:") {
|
||||
type = .warning
|
||||
}
|
||||
// Check for debug indicators
|
||||
else if line.contains("[DEBUG]") || line.contains("DEBUG:") || line.contains("debug:") {
|
||||
type = .debug
|
||||
}
|
||||
// Check for info indicators
|
||||
else if line.contains("[INFO]") || line.contains("INFO:") || line.contains("info:") {
|
||||
type = .info
|
||||
}
|
||||
// Default to info for anything else
|
||||
else {
|
||||
type = isError ? .error : .info
|
||||
}
|
||||
|
||||
// Add to logs
|
||||
addLog(message: line, type: type)
|
||||
}
|
||||
}
|
||||
|
||||
func addLog(message: String, type: LogEntry.LogType) {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ struct ConsoleLogsView: View {
|
|||
VStack(spacing: 16) {
|
||||
// Error count with red theme
|
||||
HStack {
|
||||
Text("\(logManager.errorCount) Critical Errors.")
|
||||
Text("\(logManager.errorCount) Errors")
|
||||
.font(.headline)
|
||||
.foregroundColor(.white)
|
||||
.padding(.vertical, 12)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue