"Add rust logs"

This commit is contained in:
neoarz 2025-03-29 15:49:40 -04:00
parent 54fbfc87f0
commit 2b4f55edcb
3 changed files with 171 additions and 8 deletions

View file

@ -435,10 +435,11 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = StikJIT/StikJIT.entitlements;
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"StikJIT/Preview Content\"";
DEVELOPMENT_TEAM = SZ977XLF24;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5W322N3S53;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@ -463,8 +464,10 @@
);
MACOSX_DEPLOYMENT_TARGET = 15.1;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.stik.StikJIT;
PRODUCT_BUNDLE_IDENTIFIER = com.stikjit.neosign;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = StikJIT;
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
SWIFT_EMIT_LOC_STRINGS = YES;
@ -483,10 +486,11 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = StikJIT/StikJIT.entitlements;
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"StikJIT/Preview Content\"";
DEVELOPMENT_TEAM = SZ977XLF24;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 5W322N3S53;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@ -511,8 +515,10 @@
);
MACOSX_DEPLOYMENT_TARGET = 15.1;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.stik.StikJIT;
PRODUCT_BUNDLE_IDENTIFIER = com.stikjit.neosign;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = StikJIT;
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
SWIFT_EMIT_LOC_STRINGS = YES;
@ -655,4 +661,4 @@
/* End XCConfigurationList section */
};
rootObject = DC6F1D2F2D94EADD0071B2B6 /* Project object */;
}
}

View file

@ -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) {

View file

@ -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)