Browse Source

logging: NSLog -> UTMLog to support logging to file

osy 5 years ago
parent
commit
342fdb86b4

+ 6 - 6
CocoaSpice/CSConnection.m

@@ -136,14 +136,14 @@ static void cs_channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data
         SPICE_DEBUG("new main channel");
         g_assert(!self->_main); // should only be 1 main channel
         self->_main = SPICE_MAIN_CHANNEL(channel);
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         g_signal_connect(channel, "channel-event",
                          G_CALLBACK(cs_main_channel_event), GLIB_OBJC_RETAIN(self));
     }
     
     if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
         SPICE_DEBUG("new display channel (#%d)", chid);
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         g_signal_connect(channel, "notify::monitors",
                          G_CALLBACK(cs_display_monitors), GLIB_OBJC_RETAIN(self));
         spice_channel_connect(channel);
@@ -172,14 +172,14 @@ static void cs_channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer
     
     g_object_get(channel, "channel-id", &chid, NULL);
     if (SPICE_IS_MAIN_CHANNEL(channel)) {
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         SPICE_DEBUG("zap main channel");
         self->_main = NULL;
         g_signal_handlers_disconnect_by_func(channel, G_CALLBACK(cs_main_channel_event), GLIB_OBJC_RELEASE(self));
     }
     
     if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         SPICE_DEBUG("zap display channel (#%d)", chid);
         g_signal_handlers_disconnect_by_func(channel, G_CALLBACK(cs_display_monitors), GLIB_OBJC_RELEASE(self));
         [self->_monitors[chid] removeAllObjects];
@@ -247,7 +247,7 @@ static void cs_connection_destroy(SpiceSession *session,
     self = [super init];
     if (self) {
         _session = spice_session_new();
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         g_signal_connect(_session, "channel-new",
                          G_CALLBACK(cs_channel_new), GLIB_OBJC_RETAIN(self));
         g_signal_connect(_session, "channel-destroy",
@@ -259,7 +259,7 @@ static void cs_connection_destroy(SpiceSession *session,
 }
 
 - (void)dealloc {
-    NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+    UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
     g_signal_handlers_disconnect_by_func(_session, G_CALLBACK(cs_channel_new), GLIB_OBJC_RELEASE(self));
     g_signal_handlers_disconnect_by_func(_session, G_CALLBACK(cs_channel_destroy), GLIB_OBJC_RELEASE(self));
     g_signal_handlers_disconnect_by_func(_session, G_CALLBACK(cs_connection_destroy), GLIB_OBJC_RELEASE(self));

+ 5 - 5
CocoaSpice/CSDisplayMetal.m

@@ -173,7 +173,7 @@ static void cs_channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data
         }
         self->_display = SPICE_DISPLAY_CHANNEL(channel);
         NSCAssert(!self->_sigsconnected, @"Signals already connected!");
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         g_signal_connect(channel, "display-primary-create",
                          G_CALLBACK(cs_primary_create), GLIB_OBJC_RETAIN(self));
         g_signal_connect(channel, "display-primary-destroy",
@@ -217,7 +217,7 @@ static void cs_channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer
         cs_primary_destroy(self->_display, (__bridge void *)self);
         self->_display = NULL;
         NSCAssert(self->_sigsconnected, @"Signals not connected!");
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         g_signal_handlers_disconnect_by_func(channel, G_CALLBACK(cs_primary_create), GLIB_OBJC_RELEASE(self));
         g_signal_handlers_disconnect_by_func(channel, G_CALLBACK(cs_primary_destroy), GLIB_OBJC_RELEASE(self));
         g_signal_handlers_disconnect_by_func(channel, G_CALLBACK(cs_invalidate), GLIB_OBJC_RELEASE(self));
@@ -295,7 +295,7 @@ static void cs_channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer
         _sigsconnected = NO;
         g_object_ref(session);
         
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         g_signal_connect(session, "channel-new",
                          G_CALLBACK(cs_channel_new), GLIB_OBJC_RETAIN(self));
         g_signal_connect(session, "channel-destroy",
@@ -319,7 +319,7 @@ static void cs_channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer
     if (_display) {
         cs_channel_destroy(self.session, SPICE_CHANNEL(_display), (__bridge void *)self);
     }
-    NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+    UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
     g_signal_handlers_disconnect_by_func(self.session, G_CALLBACK(cs_channel_new), GLIB_OBJC_RELEASE(self));
     g_signal_handlers_disconnect_by_func(self.session, G_CALLBACK(cs_channel_destroy), GLIB_OBJC_RELEASE(self));
     g_object_unref(self.session);
@@ -403,7 +403,7 @@ static void cs_channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer
 
 - (void)requestResolution:(CGRect)bounds {
     if (!_main) {
-        NSLog(@"ignoring change resolution because main channel not found");
+        UTMLog(@"ignoring change resolution because main channel not found");
         return;
     }
     spice_main_channel_update_display_enabled(_main, (int)self.monitorID, TRUE, FALSE);

+ 3 - 3
CocoaSpice/CSInput.m

@@ -430,7 +430,7 @@ static int cs_button_to_spice(SendButtonType button)
         self.session = session;
         g_object_ref(session);
         
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         g_signal_connect(session, "channel-new",
                          G_CALLBACK(cs_channel_new), GLIB_OBJC_RETAIN(self));
         g_signal_connect(session, "channel-destroy",
@@ -453,7 +453,7 @@ static int cs_button_to_spice(SendButtonType button)
     if (_main) {
         cs_channel_destroy(self.session, SPICE_CHANNEL(_main), (__bridge void *)self);
     }
-    NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+    UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
     g_signal_handlers_disconnect_by_func(self.session, G_CALLBACK(cs_channel_new), GLIB_OBJC_RELEASE(self));
     g_signal_handlers_disconnect_by_func(self.session, G_CALLBACK(cs_channel_destroy), GLIB_OBJC_RELEASE(self));
     g_object_unref(self.session);
@@ -473,7 +473,7 @@ static int cs_button_to_spice(SendButtonType button)
 - (void)rebuildTexture:(CGSize)size center:(CGPoint)hotspot {
     // hotspot is the offset in buffer for the center of the pointer
     if (!_device) {
-        NSLog(@"MTL device not ready for cursor draw");
+        UTMLog(@"MTL device not ready for cursor draw");
         return;
     }
     dispatch_semaphore_wait(_drawLock, DISPATCH_TIME_FOREVER);

+ 6 - 6
CocoaSpice/CSSession.m

@@ -306,7 +306,7 @@ static void cs_channel_destroy(SpiceSession *session, SpiceChannel *channel,
         self.session = session;
         g_object_ref(session);
         
-        NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+        UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
         g_signal_connect(session, "channel-new",
                          G_CALLBACK(cs_channel_new), GLIB_OBJC_RETAIN(self));
         g_signal_connect(session, "channel-destroy",
@@ -321,7 +321,7 @@ static void cs_channel_destroy(SpiceSession *session, SpiceChannel *channel,
 }
 
 - (void)dealloc {
-    NSLog(@"%s:%d", __FUNCTION__, __LINE__);
+    UTMLog(@"%s:%d", __FUNCTION__, __LINE__);
     g_signal_handlers_disconnect_by_func(self.session, G_CALLBACK(cs_channel_new), GLIB_OBJC_RELEASE(self));
     g_signal_handlers_disconnect_by_func(self.session, G_CALLBACK(cs_channel_destroy), GLIB_OBJC_RELEASE(self));
     g_object_unref(self.session);
@@ -343,12 +343,12 @@ static void cs_channel_destroy(SpiceSession *session, SpiceChannel *channel,
 #pragma mark - Notification handler
 
 - (void)pasteboardDidChange:(NSNotification *)notification {
-    NSLog(@"seen UIPasteboardChangedNotification");
+    UTMLog(@"seen UIPasteboardChangedNotification");
     if (!self.shareClipboard || self.sessionReadOnly) {
         return;
     }
     if ([UIPasteboard generalPasteboard].changeCount <= _pasteboardChanges) {
-        NSLog(@"ignoring excess pasteboard change");
+        UTMLog(@"ignoring excess pasteboard change");
         return;
     } else {
         _pasteboardChanges = [UIPasteboard generalPasteboard].changeCount;
@@ -366,7 +366,7 @@ static void cs_channel_destroy(SpiceSession *session, SpiceChannel *channel,
     } else if ([[UIPasteboard generalPasteboard] hasStrings]) {
         type = VD_AGENT_CLIPBOARD_UTF8_TEXT;
     } else {
-        NSLog(@"pasteboard with unrecognized type");
+        UTMLog(@"pasteboard with unrecognized type");
     }
     if (spice_main_channel_agent_test_capability(self->_main, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND)) {
         spice_main_channel_clipboard_selection_grab(self->_main, VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD, &type, 1);
@@ -374,7 +374,7 @@ static void cs_channel_destroy(SpiceSession *session, SpiceChannel *channel,
 }
 
 - (void)pasteboardDidRemove:(NSNotification *)notification {
-    NSLog(@"seen UIPasteboardRemovedNotification");
+    UTMLog(@"seen UIPasteboardRemovedNotification");
     if (!self.shareClipboard || self.sessionReadOnly) {
         return;
     }

+ 1 - 0
CocoaSpice/CocoaSpice.h

@@ -22,6 +22,7 @@
 #include "CSInput.h"
 #include "CSMain.h"
 #include "CSSession.h"
+#include "UTMLogging.h"
 
 #define GLIB_OBJC_RETAIN(x) (__bridge_retained void *)(x)
 #define GLIB_OBJC_RELEASE(x) (__bridge void *)(__bridge_transfer NSObject *)(__bridge void *)(x)

+ 2 - 1
Configuration/UTMConfiguration+System.m

@@ -16,6 +16,7 @@
 
 #import "UTMConfiguration+Constants.h"
 #import "UTMConfiguration+System.h"
+#import "UTMLogging.h"
 
 extern const NSString *const kUTMConfigSystemKey;
 
@@ -56,7 +57,7 @@ static const NSString *const kUTMConfigSystemUUIDKey = @"SystemUUID";
     NSArray<NSString *> *bootPretty = [UTMConfiguration supportedBootDevicesPretty];
     if ([bootPretty containsObject:self.systemBootDevice]) {
         NSUInteger index = [bootPretty indexOfObject:self.systemBootDevice];
-        NSLog(@"Fixing wrong BootDevice entry '%@', index %lu", self.systemBootDevice, index);
+        UTMLog(@"Fixing wrong BootDevice entry '%@', index %lu", self.systemBootDevice, index);
         self.systemBootDevice = [UTMConfiguration supportedBootDevices][index];
     }
 }

+ 5 - 4
ConfigurationViews/VMConfigSharingViewController.m

@@ -19,6 +19,7 @@
 #import "VMConfigSharingViewController.h"
 #import "UTMConfiguration.h"
 #import "UTMConfiguration+Sharing.h"
+#import "UTMLogging.h"
 #import "VMConfigSwitch.h"
 #import "VMConfigDirectoryPickerViewController.h"
 
@@ -88,12 +89,12 @@
                                     bookmarkDataIsStale:&stale
                                                   error:&err];
     if (!bookmark) {
-        NSLog(@"bookmark invalid: %@", err);
+        UTMLog(@"bookmark invalid: %@", err);
         [self showAlert:NSLocalizedString(@"Shared path is no longer valid. Please re-choose.", @"VMConfigSharingViewController") actions:nil completion:nil];
         self.configuration.shareDirectoryBookmark = [NSData data];
         self.configuration.shareDirectoryName = @"";
     } else if (stale) {
-        NSLog(@"bookmark stale");
+        UTMLog(@"bookmark stale");
         if ([bookmark startAccessingSecurityScopedResource]) {
             data = [bookmark bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
                       includingResourceValuesForKeys:nil
@@ -101,7 +102,7 @@
                                                error:&err];
             [bookmark stopAccessingSecurityScopedResource];
             if (!data) {
-                NSLog(@"cannot recreate bookmark: %@", err);
+                UTMLog(@"cannot recreate bookmark: %@", err);
                 [self showAlert:NSLocalizedString(@"Shared path has moved. Please re-choose.", @"VMConfigSharingViewController") actions:nil completion:nil];
                 self.configuration.shareDirectoryBookmark = [NSData data];
                 self.configuration.shareDirectoryName = @"";
@@ -122,7 +123,7 @@
     if (!bookmark) {
         [self showAlert:err.localizedDescription actions:nil completion:nil];
     } else {
-        NSLog(@"Saving bookmark for %@", url);
+        UTMLog(@"Saving bookmark for %@", url);
         self.configuration.shareDirectoryBookmark = bookmark;
         self.configuration.shareDirectoryName = url.lastPathComponent;
     }

+ 2 - 1
ConfigurationViews/VMConfigSystemViewController.m

@@ -21,6 +21,7 @@
 #import "VMConfigSystemViewController.h"
 #import "UTMConfiguration+Constants.h"
 #import "UTMConfiguration+System.h"
+#import "UTMLogging.h"
 #import "VMConfigPickerView.h"
 #import "VMConfigTextField.h"
 #import "VMConfigTogglePickerCell.h"
@@ -199,7 +200,7 @@ const float kMemoryWarningThreshold = 0.8;
     vm_statistics_data_t vm_stat;
 
     if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
-        NSLog(@"Failed to fetch vm statistics");
+        UTMLog(@"Failed to fetch vm statistics");
     }
 
     /* Stats in bytes */

+ 5 - 4
ConfigurationViews/VMConfigViewController.m

@@ -23,6 +23,7 @@
 #import "VMConfigTogglePickerCell.h"
 #import "UTMConfiguration.h"
 #import "UTMConfiguration+Constants.h"
+#import "UTMLogging.h"
 
 void *kVMConfigViewControllerContext = &kVMConfigViewControllerContext;
 
@@ -92,7 +93,7 @@ void *kVMConfigViewControllerContext = &kVMConfigViewControllerContext;
             if ([control.configurationPath isEqualToString:keyPath]) {
                 id value = change[NSKeyValueChangeNewKey];
                 if (value != change[NSKeyValueChangeOldKey]) {
-                    NSLog(@"seen configuration change %@ = %@", keyPath, value);
+                    UTMLog(@"seen configuration change %@ = %@", keyPath, value);
                     [control valueChanged:value];
                 }
             }
@@ -164,7 +165,7 @@ void *kVMConfigViewControllerContext = &kVMConfigViewControllerContext;
 
 - (IBAction)configTextFieldEditEnd:(VMConfigTextField *)sender {
     // validate input in super-class
-    NSLog(@"config edited for text %@", sender.configurationPath);
+    UTMLog(@"config edited for text %@", sender.configurationPath);
     if (sender.isNumber) {
         [self.configuration setValue:@([sender.text integerValue]) forKey:sender.configurationPath];
     } else {
@@ -173,12 +174,12 @@ void *kVMConfigViewControllerContext = &kVMConfigViewControllerContext;
 }
 
 - (IBAction)configSwitchChanged:(VMConfigSwitch *)sender {
-    NSLog(@"config changed for switch %@", sender.configurationPath);
+    UTMLog(@"config changed for switch %@", sender.configurationPath);
     [self.configuration setValue:@(sender.on) forKey:sender.configurationPath];
 }
 
 - (IBAction)configStepperChanged:(VMConfigStepper *)sender {
-    NSLog(@"config changed for stepper %@", sender.configurationPath);
+    UTMLog(@"config changed for stepper %@", sender.configurationPath);
     [self.configuration setValue:@(sender.value) forKey:sender.configurationPath];
 }
 

+ 9 - 8
Managers/UTMJSONStream.m

@@ -15,6 +15,7 @@
 //
 
 #import "UTMJSONStream.h"
+#import "UTMLogging.h"
 
 extern NSString *const kUTMErrorDomain;
 const int kMaxBufferSize = 1024;
@@ -108,7 +109,7 @@ enum ParserState {
                         if (self->_state == PARSER_NOT_IN_STRING) {
                             self->_open_curly_count--;
                             if (self->_open_curly_count < 0) {
-                                NSLog(@"Saw too many close curly!");
+                                UTMLog(@"Saw too many close curly!");
                                 self->_state = PARSER_INVALID;
                                 NSError *err = [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Error parsing JSON.", "UTMJSONStream")}];
                                 [self.delegate jsonStream:self seenError:err];
@@ -120,7 +121,7 @@ enum ParserState {
                         if (self->_state == PARSER_IN_STRING) {
                             self->_state = PARSER_IN_STRING_ESCAPE;
                         } else {
-                            NSLog(@"Saw escape in invalid context");
+                            UTMLog(@"Saw escape in invalid context");
                             self->_state = PARSER_INVALID;
                             NSError *err = [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Error parsing JSON.", "UTMJSONStream")}];
                             [self.delegate jsonStream:self seenError:err];
@@ -139,7 +140,7 @@ enum ParserState {
                         // force reset parser
                         if (str[i] == (char)0xFF ||
                             (str[i] >= '\0' && str[i] < ' ' && str[i] != '\t' && str[i] != '\r' && str[i] != '\n')) {
-                            NSLog(@"Resetting parser...");
+                            UTMLog(@"Resetting parser...");
                             self->_state = PARSER_NOT_IN_STRING;
                             self->_open_curly_count = 0;
                         }
@@ -171,7 +172,7 @@ enum ParserState {
         return;
     }
     NSAssert([json isKindOfClass:[NSDictionary class]], @"JSON data not dictionary");
-    NSLog(@"Debug JSON recieved <- %@", json);
+    UTMLog(@"Debug JSON recieved <- %@", json);
     dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
         [self.delegate jsonStream:self receivedDictionary:(NSDictionary *)json];
     });
@@ -197,7 +198,7 @@ enum ParserState {
             break;
         }
         case NSStreamEventErrorOccurred: {
-            NSLog(@"Stream error %@", [aStream streamError]);
+            UTMLog(@"Stream error %@", [aStream streamError]);
             [self.delegate jsonStream:self seenError:[aStream streamError]];
         }
         case NSStreamEventEndEncountered: {
@@ -205,7 +206,7 @@ enum ParserState {
             break;
         }
         case NSStreamEventOpenCompleted: {
-            NSLog(@"Connected to stream");
+            UTMLog(@"Connected to stream");
             [self.delegate jsonStream:self connected:(aStream == _inputStream)];
             break;
         }
@@ -221,11 +222,11 @@ enum ParserState {
         if (!_outputStream || _outputStream.streamStatus != NSStreamStatusOpen) {
             return NO;
         }
-        NSLog(@"Debug JSON send -> %@", dict);
+        UTMLog(@"Debug JSON send -> %@", dict);
         [NSJSONSerialization writeJSONObject:dict toStream:_outputStream options:0 error:&err];
     }
     if (err) {
-        NSLog(@"Error sending dict: %@", err);
+        UTMLog(@"Error sending dict: %@", err);
         return NO;
     } else {
         return YES;

+ 3 - 2
Managers/UTMLocationManager.m

@@ -15,6 +15,7 @@
 //
 
 #import "UTMLocationManager.h"
+#import "UTMLogging.h"
 @import CoreLocation;
 
 @interface UTMLocationManager () <CLLocationManagerDelegate>
@@ -43,14 +44,14 @@
 
 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
     CLLocation *mostRecentLocation = locations.lastObject;
-    NSLog(@"Current location: %@ %@", @(mostRecentLocation.coordinate.latitude), @(mostRecentLocation.coordinate.longitude));
+    UTMLog(@"Current location: %@ %@", @(mostRecentLocation.coordinate.latitude), @(mostRecentLocation.coordinate.longitude));
 }
 
 - (void)startUpdatingLocation {
     CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
 
     if (status == kCLAuthorizationStatusDenied) {
-        NSLog(@"Location services are disabled in settings.");
+        UTMLog(@"Location services are disabled in settings.");
     } else {
         [self.locationManager requestAlwaysAuthorization];
         self.locationManager.allowsBackgroundLocationUpdates = YES;

+ 3 - 0
Managers/UTMLogging.h

@@ -18,6 +18,8 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+void UTMLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2) NS_NO_TAIL_CALL;
+
 @interface UTMLogging : NSObject
 
 @property (nonatomic) NSString *lastErrorLine;
@@ -26,6 +28,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 - (void)logToFile:(NSURL *)path;
 - (void)endLog;
+- (void)writeLine:(NSString *)line;
 
 @end
 

+ 16 - 3
Managers/UTMLogging.m

@@ -22,6 +22,15 @@
 static const int kLogBufferSize = 4096;
 static UTMLogging *gLoggingInstance;
 
+void UTMLog(NSString *format, ...) {
+    va_list args;
+    va_start(args, format);
+    NSString *line = [[NSString alloc] initWithFormat:[format stringByAppendingString:@"\n"] arguments:args];
+    [[UTMLogging sharedInstance] writeLine:line];
+    va_end(args);
+    NSLog(@"%@", line);
+}
+
 @interface UTMLogging ()
 
 - (void)didRecieveNewLine:(NSString *)line onDescriptor:(int)fd;
@@ -84,7 +93,7 @@ void *utm_logging_thread_stderr(void *arg) {
     self = [super init];
     if (self) {
         if (gLoggingInstance != nil) {
-            NSLog(@"Trying to init more than one instance of UTMLogging!");
+            UTMLog(@"Trying to init more than one instance of UTMLogging!");
             return nil;
         }
         int success = 0;
@@ -160,7 +169,7 @@ void *utm_logging_thread_stderr(void *arg) {
         _real_stdout = -1;
     }
     if (_real_stderr != -1) {
-        dup2(_real_stderr, STDOUT_FILENO);
+        dup2(_real_stderr, STDERR_FILENO);
         close(_real_stderr);
         _real_stderr = -1;
     }
@@ -198,7 +207,7 @@ void *utm_logging_thread_stderr(void *arg) {
     } else {
         NSAssert(0, @"Invalid descriptor %d", fd);
     }
-    [_stream write:(void *)[line cStringUsingEncoding:NSASCIIStringEncoding] maxLength:line.length];
+    [self writeLine:line];
 }
 
 - (void)logToFile:(NSURL *)path {
@@ -222,4 +231,8 @@ void *utm_logging_thread_stderr(void *arg) {
     _stream = nil;
 }
 
+- (void)writeLine:(NSString *)line {
+    [_stream write:(void *)[line cStringUsingEncoding:NSASCIIStringEncoding] maxLength:line.length];
+}
+
 @end

+ 2 - 2
Managers/UTMQemu.m

@@ -62,14 +62,14 @@ void *start_qemu(void *args) {
             args = [args stringByAppendingFormat:@" %@", arg];
         }
     }
-    NSLog(@"Running: %@", args);
+    UTMLog(@"Running: %@", args);
 }
 
 - (void)startDylib:(nonnull NSString *)dylib main:(nonnull NSString *)main completion:(void(^)(BOOL,NSString *))completion {
     void *dlctx;
     __block pthread_t qemu_thread;
     
-    NSLog(@"Loading %@", dylib);
+    UTMLog(@"Loading %@", dylib);
     dlctx = dlopen([dylib UTF8String], RTLD_LOCAL);
     if (dlctx == NULL) {
         NSString *err = [NSString stringWithUTF8String:dlerror()];

+ 2 - 1
Managers/UTMQemuImg.m

@@ -15,6 +15,7 @@
 //
 
 #import "UTMQemuImg.h"
+#import "UTMLogging.h"
 #import <dlfcn.h>
 #import <pthread.h>
 
@@ -55,7 +56,7 @@
             break;
         }
         default: {
-            NSLog(@"Operation %lu not implemented!", self.op);
+            UTMLog(@"Operation %lu not implemented!", self.op);
             break;
         }
     }

+ 8 - 7
Managers/UTMQemuManager.m

@@ -16,6 +16,7 @@
 
 #import "UTMQemuManager.h"
 #import "UTMJSONStream.h"
+#import "UTMLogging.h"
 #import "qapi-commands.h"
 #import "qapi-dispatch-events.h"
 #import "qapi-events.h"
@@ -135,7 +136,7 @@ void qmp_rpc_call(CFDictionaryRef args, CFDictionaryRef *ret, Error **err, void
     dict = nil;
     if (nserr) {
         error_setg(err, "%s", [nserr.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding]);
-        NSLog(@"RPC: %@", nserr);
+        UTMLog(@"RPC: %@", nserr);
     }
     dispatch_semaphore_signal(self->_cmd_lock);
 }
@@ -165,19 +166,19 @@ void qmp_rpc_call(CFDictionaryRef args, CFDictionaryRef *ret, Error **err, void
 }
 
 - (void)jsonStream:(UTMJSONStream *)stream connected:(BOOL)readStream {
-    NSLog(@"QMP connection successful! (readStream:%d)", readStream);
+    UTMLog(@"QMP connection successful! (readStream:%d)", readStream);
     self.retries = 0; // connection was successful
 }
 
 - (void)jsonStream:(UTMJSONStream *)stream seenError:(NSError *)error {
-    NSLog(@"QMP stream error seen: %@", error);
+    UTMLog(@"QMP stream error seen: %@", error);
     if (_rpc_finish) {
         _rpc_finish(nil, error);
     }
     [self disconnect];
     if (self.retries > 0) {
         self.retries--;
-        NSLog(@"QMP connection failed, retries left: %d", self.retries);
+        UTMLog(@"QMP connection failed, retries left: %d", self.retries);
         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, kRetryWait), dispatch_get_main_queue(), ^{
             [self->_jsonStream connect];
         });
@@ -190,14 +191,14 @@ void qmp_rpc_call(CFDictionaryRef args, CFDictionaryRef *ret, Error **err, void
             if (self->_rpc_finish) {
                 self->_rpc_finish(dict, nil);
             } else {
-                NSLog(@"Got unexpected 'return' response: %@", dict);
+                UTMLog(@"Got unexpected 'return' response: %@", dict);
             }
             *stop = YES;
         } else if ([key isEqualToString:@"error"]) {
             if (self->_rpc_finish) {
                 self->_rpc_finish(nil, [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: dict[@"error"][@"desc"]}]);
             } else {
-                NSLog(@"Got unexpected 'error' response: %@", dict);
+                UTMLog(@"Got unexpected 'error' response: %@", dict);
             }
             *stop = YES;
         } else if ([key isEqualToString:@"event"]) {
@@ -205,7 +206,7 @@ void qmp_rpc_call(CFDictionaryRef args, CFDictionaryRef *ret, Error **err, void
             qapi_event_dispatch(event, (__bridge CFTypeRef)dict, (__bridge void *)self);
             *stop = YES;
         } else if ([key isEqualToString:@"QMP"]) {
-            NSLog(@"Got QMP handshake: %@", dict);
+            UTMLog(@"Got QMP handshake: %@", dict);
             qmp_qmp_capabilities(false, NULL, NULL, (__bridge void *)self);
             *stop = YES;
         }

+ 2 - 1
Managers/UTMQemuSystem.m

@@ -24,6 +24,7 @@
 #import "UTMConfiguration+Sharing.h"
 #import "UTMConfiguration+System.h"
 #import "UTMConfigurationPortForward.h"
+#import "UTMLogging.h"
 
 @implementation UTMQemuSystem
 
@@ -100,7 +101,7 @@
                 break;
             }
             default: {
-                NSLog(@"WARNING: unknown image type %lu, ignoring image %@", type, fullPathURL);
+                UTMLog(@"WARNING: unknown image type %lu, ignoring image %@", type, fullPathURL);
                 break;
             }
         }

+ 7 - 6
Managers/UTMSpiceIO.m

@@ -18,6 +18,7 @@
 #import "UTMConfiguration.h"
 #import "UTMConfiguration+Miscellaneous.h"
 #import "UTMConfiguration+Sharing.h"
+#import "UTMLogging.h"
 #import "UTMViewState.h"
 #import "CocoaSpice.h"
 
@@ -187,7 +188,7 @@ const int kMaxConnectionTries = 10; // qemu needs to start spice server first
         [self endSharingDirectory:session];
     }
     if (self.configuration.shareDirectoryEnabled) {
-        NSLog(@"enabling shared directory");
+        UTMLog(@"enabling shared directory");
         BOOL stale;
         NSError *err;
         NSURL *shareURL = [NSURL URLByResolvingBookmarkData:self.configuration.shareDirectoryBookmark
@@ -196,18 +197,18 @@ const int kMaxConnectionTries = 10; // qemu needs to start spice server first
                                         bookmarkDataIsStale:&stale
                                                       error:&err];
         if (!shareURL) {
-            NSLog(@"error getting bookmark: %@", err);
+            UTMLog(@"error getting bookmark: %@", err);
             return;
         }
         if (stale) {
-            NSLog(@"bookmark stale, should get new bookmark!");
+            UTMLog(@"bookmark stale, should get new bookmark!");
         }
         //if ([shareURL startAccessingSecurityScopedResource]) {
             _sharedDirectory = shareURL;
-            NSLog(@"setting share directory to %@", shareURL.path);
+            UTMLog(@"setting share directory to %@", shareURL.path);
             [session setSharedDirectory:shareURL.path readOnly:self.configuration.shareDirectoryReadOnly];
         //} else {
-        //    NSLog(@"failed to access security scope for shared directory, was access revoked?");
+        //    UTMLog(@"failed to access security scope for shared directory, was access revoked?");
         //}
     }
 }
@@ -216,7 +217,7 @@ const int kMaxConnectionTries = 10; // qemu needs to start spice server first
     if (_sharedDirectory) {
         //[_sharedDirectory stopAccessingSecurityScopedResource];
         _sharedDirectory = nil;
-        NSLog(@"ended share directory sharing");
+        UTMLog(@"ended share directory sharing");
     }
 }
 

+ 12 - 11
Managers/UTMTerminal.m

@@ -6,6 +6,7 @@
 //  Copyright © 2020 Kacper Raczy. All rights reserved.
 //
 
+#import "UTMLogging.h"
 #import "UTMTerminal.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -22,7 +23,7 @@ dispatch_io_t createInputIO(NSURL* url, dispatch_queue_t queue) {
             0,
             queue,
             ^(int error) {
-            NSLog(@"Input dispatch_io is being closed");
+            UTMLog(@"Input dispatch_io is being closed");
         });
     
     return io;
@@ -51,14 +52,14 @@ dispatch_io_t createInputIO(NSURL* url, dispatch_queue_t queue) {
         
         self->_outPipeFd = -1;
         if (![self configurePipesUsingURL: url]) {
-            NSLog(@"Terminal configutation failed!");
+            UTMLog(@"Terminal configutation failed!");
             [self cleanup];
             return nil;
         }
         // setup non-blocking io for writing
         self->_inputPipeIO = createInputIO(_inPipeURL, _inputQueue);
         if (self->_inputPipeIO == nil) {
-            NSLog(@"Terminal configutation failed!");
+            UTMLog(@"Terminal configutation failed!");
             [self cleanup];
             return nil;
         }
@@ -79,21 +80,21 @@ dispatch_io_t createInputIO(NSURL* url, dispatch_queue_t queue) {
     // create named pipes usign mkfifos
     const char* outPipeCPath = [[outPipeURL path] cStringUsingEncoding: NSUTF8StringEncoding];
     if (access(outPipeCPath, F_OK) != -1 && remove(outPipeCPath) != 0) {
-        NSLog(@"Failed to remove existing out pipe");
+        UTMLog(@"Failed to remove existing out pipe");
         return NO;
     }
     if (mkfifo(outPipeCPath, 0666) != 0) {
-        NSLog(@"Failed to create output pipe using mkfifo!");
+        UTMLog(@"Failed to create output pipe using mkfifo!");
         return NO;
     }
     
     const char* inPipeCPath = [[inPipeURL path] cStringUsingEncoding: NSUTF8StringEncoding];
     if (access(inPipeCPath, F_OK) != -1 && remove(inPipeCPath) != 0) {
-        NSLog(@"Failed to remove existing in pipe");
+        UTMLog(@"Failed to remove existing in pipe");
         return NO;
     }
     if (mkfifo(inPipeCPath, 0666) != 0) {
-        NSLog(@"Failed to create input pipe using mkfifo!");
+        UTMLog(@"Failed to create input pipe using mkfifo!");
         return NO;
     }
     
@@ -144,7 +145,7 @@ dispatch_io_t createInputIO(NSURL* url, dispatch_queue_t queue) {
     if (_inputPipeIO != nil) {
         dispatch_io_close(_inputPipeIO, DISPATCH_IO_STOP);
     }
-    NSLog(@"Successfuly disconnected!");
+    UTMLog(@"Successfuly disconnected!");
 }
 
 - (BOOL)isConnected {
@@ -166,7 +167,7 @@ dispatch_io_t createInputIO(NSURL* url, dispatch_queue_t queue) {
         }
     });
     dispatch_source_set_cancel_handler(source, ^{
-        NSLog(@"Source got cancelled");
+        UTMLog(@"Source got cancelled");
     });
     dispatch_resume(source);
     
@@ -190,7 +191,7 @@ dispatch_io_t createInputIO(NSURL* url, dispatch_queue_t queue) {
     NSUInteger length = [inputStr lengthOfBytesUsingEncoding: NSUTF8StringEncoding];
     dispatch_data_t messageData = dispatch_data_create(bytes, length, _inputQueue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
     dispatch_io_write(_inputPipeIO, 0, messageData, _inputQueue, ^(bool done, dispatch_data_t  _Nullable data, int error) {
-        NSLog(@"Input write done: %d with error: %d", done, error);
+        UTMLog(@"Input write done: %d with error: %d", done, error);
     });
 }
 
@@ -215,7 +216,7 @@ dispatch_io_t createInputIO(NSURL* url, dispatch_queue_t queue) {
     if (_outPipeURL != nil) {
         [fm removeItemAtURL: _outPipeURL error: nil];
     }
-    NSLog(@"Cleanup completed!");
+    UTMLog(@"Cleanup completed!");
 }
 
 #pragma mark - Custom errors

+ 2 - 1
Managers/UTMTerminalIO.m

@@ -14,6 +14,7 @@
 // limitations under the License.
 //
 
+#import "UTMLogging.h"
 #import "UTMTerminalIO.h"
 #import "UTMConfiguration.h"
 #import <UIKit/UIKit.h>
@@ -73,7 +74,7 @@
 }
 
 - (void)setDebugMode:(BOOL)debugMode {
-    NSLog(@"%@ does not support debug mode.", NSStringFromClass([self class]));
+    UTMLog(@"%@ does not support debug mode.", NSStringFromClass([self class]));
 }
 
 - (void)syncViewState:(UTMViewState *)viewState {

+ 31 - 31
Managers/UTMVirtualMachine.m

@@ -96,7 +96,7 @@ NSString *const kSuspendSnapshotName = @"suspend";
         NSString *name = [UTMVirtualMachine virtualMachineName:url];
         NSMutableDictionary *plist = [self loadPlist:[url URLByAppendingPathComponent:kUTMBundleConfigFilename] withError:nil];
         if (!plist) {
-            NSLog(@"Failed to parse config for %@", url);
+            UTMLog(@"Failed to parse config for %@", url);
             self = nil;
             return self;
         }
@@ -270,7 +270,7 @@ NSString *const kSuspendSnapshotName = @"suspend";
     [_qemu vmQuitWithCompletion:nil];
     if (dispatch_semaphore_wait(_will_quit_sema, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
         // TODO: force shutdown
-        NSLog(@"Stop operation timeout");
+        UTMLog(@"Stop operation timeout");
     }
     [_qemu disconnect];
     _qemu.delegate = nil;
@@ -280,7 +280,7 @@ NSString *const kSuspendSnapshotName = @"suspend";
     
     if (dispatch_semaphore_wait(_qemu_exit_sema, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
         // TODO: force shutdown
-        NSLog(@"Exit operation timeout");
+        UTMLog(@"Exit operation timeout");
     }
     _qemu_system = nil;
     [self changeState:kVMStopped];
@@ -307,15 +307,15 @@ NSString *const kSuspendSnapshotName = @"suspend";
     __block BOOL success = YES;
     dispatch_semaphore_t reset_sema = dispatch_semaphore_create(0);
     [_qemu vmResetWithCompletion:^(NSError *err) {
-        NSLog(@"reset callback: err? %@", err);
+        UTMLog(@"reset callback: err? %@", err);
         if (err) {
-            NSLog(@"error: %@", err);
+            UTMLog(@"error: %@", err);
             success = NO;
         }
         dispatch_semaphore_signal(reset_sema);
     }];
     if (dispatch_semaphore_wait(reset_sema, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        NSLog(@"Reset operation timeout");
+        UTMLog(@"Reset operation timeout");
         success = NO;
     }
     if (success) {
@@ -341,15 +341,15 @@ NSString *const kSuspendSnapshotName = @"suspend";
     __block BOOL success = YES;
     dispatch_semaphore_t suspend_sema = dispatch_semaphore_create(0);
     [_qemu vmStopWithCompletion:^(NSError * err) {
-        NSLog(@"stop callback: err? %@", err);
+        UTMLog(@"stop callback: err? %@", err);
         if (err) {
-            NSLog(@"error: %@", err);
+            UTMLog(@"error: %@", err);
             success = NO;
         }
         dispatch_semaphore_signal(suspend_sema);
     }];
     if (dispatch_semaphore_wait(suspend_sema, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        NSLog(@"Stop operation timeout");
+        UTMLog(@"Stop operation timeout");
         success = NO;
     }
     if (success) {
@@ -374,21 +374,21 @@ NSString *const kSuspendSnapshotName = @"suspend";
     __block BOOL success = YES;
     dispatch_semaphore_t save_sema = dispatch_semaphore_create(0);
     [_qemu vmSaveWithCompletion:^(NSString *result, NSError *err) {
-        NSLog(@"save callback: %@", result);
+        UTMLog(@"save callback: %@", result);
         if (err) {
-            NSLog(@"error: %@", err);
+            UTMLog(@"error: %@", err);
             success = NO;
         } else if ([result localizedCaseInsensitiveContainsString:@"Error"]) {
-            NSLog(@"save result: %@", result);
+            UTMLog(@"save result: %@", result);
             success = NO; // error message
         }
         dispatch_semaphore_signal(save_sema);
     } snapshotName:kSuspendSnapshotName];
     if (dispatch_semaphore_wait(save_sema, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        NSLog(@"Save operation timeout");
+        UTMLog(@"Save operation timeout");
         success = NO;
     } else if (success) {
-        NSLog(@"Save completed");
+        UTMLog(@"Save completed");
         self.viewState.suspended = YES;
         [self saveViewState];
         [self saveScreenshot];
@@ -402,21 +402,21 @@ NSString *const kSuspendSnapshotName = @"suspend";
     __block BOOL success = YES;
     dispatch_semaphore_t save_sema = dispatch_semaphore_create(0);
     [_qemu vmDeleteSaveWithCompletion:^(NSString *result, NSError *err) {
-        NSLog(@"delete save callback: %@", result);
+        UTMLog(@"delete save callback: %@", result);
         if (err) {
-            NSLog(@"error: %@", err);
+            UTMLog(@"error: %@", err);
             success = NO;
         } else if ([result localizedCaseInsensitiveContainsString:@"Error"]) {
-            NSLog(@"save result: %@", result);
+            UTMLog(@"save result: %@", result);
             success = NO; // error message
         }
         dispatch_semaphore_signal(save_sema);
     } snapshotName:kSuspendSnapshotName];
     if (dispatch_semaphore_wait(save_sema, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        NSLog(@"Delete save operation timeout");
+        UTMLog(@"Delete save operation timeout");
         success = NO;
     } else {
-        NSLog(@"Delete save completed");
+        UTMLog(@"Delete save completed");
     }
     self.viewState.suspended = NO;
     [self saveViewState];
@@ -435,15 +435,15 @@ NSString *const kSuspendSnapshotName = @"suspend";
     __block BOOL success = YES;
     dispatch_semaphore_t resume_sema = dispatch_semaphore_create(0);
     [_qemu vmResumeWithCompletion:^(NSError *err) {
-        NSLog(@"resume callback: err? %@", err);
+        UTMLog(@"resume callback: err? %@", err);
         if (err) {
-            NSLog(@"error: %@", err);
+            UTMLog(@"error: %@", err);
             success = NO;
         }
         dispatch_semaphore_signal(resume_sema);
     }];
     if (dispatch_semaphore_wait(resume_sema, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        NSLog(@"Resume operation timeout");
+        UTMLog(@"Resume operation timeout");
         success = NO;
     }
     if (success) {
@@ -478,27 +478,27 @@ NSString *const kSuspendSnapshotName = @"suspend";
 #pragma mark - Qemu manager delegate
 
 - (void)qemuHasWakeup:(UTMQemuManager *)manager {
-    NSLog(@"qemuHasWakeup");
+    UTMLog(@"qemuHasWakeup");
 }
 
 - (void)qemuHasResumed:(UTMQemuManager *)manager {
-    NSLog(@"qemuHasResumed");
+    UTMLog(@"qemuHasResumed");
 }
 
 - (void)qemuHasStopped:(UTMQemuManager *)manager {
-    NSLog(@"qemuHasStopped");
+    UTMLog(@"qemuHasStopped");
 }
 
 - (void)qemuHasReset:(UTMQemuManager *)manager guest:(BOOL)guest reason:(ShutdownCause)reason {
-    NSLog(@"qemuHasReset, reason = %s", ShutdownCause_str(reason));
+    UTMLog(@"qemuHasReset, reason = %s", ShutdownCause_str(reason));
 }
 
 - (void)qemuHasSuspended:(UTMQemuManager *)manager {
-    NSLog(@"qemuHasSuspended");
+    UTMLog(@"qemuHasSuspended");
 }
 
 - (void)qemuWillQuit:(UTMQemuManager *)manager guest:(BOOL)guest reason:(ShutdownCause)reason {
-    NSLog(@"qemuWillQuit, reason = %s", ShutdownCause_str(reason));
+    UTMLog(@"qemuWillQuit, reason = %s", ShutdownCause_str(reason));
     dispatch_semaphore_signal(_will_quit_sema);
     if (!_is_busy) {
         [self quitVM];
@@ -602,15 +602,15 @@ NSString *const kSuspendSnapshotName = @"suspend";
     if (*p_index < 0) {
         [_qemu mouseIndexForAbsolute:tablet withCompletion:^(int64_t index, NSError *err) {
             if (err) {
-                NSLog(@"error finding index: %@", err);
+                UTMLog(@"error finding index: %@", err);
             } else {
-                NSLog(@"found index:%lld absolute:%d", index, tablet);
+                UTMLog(@"found index:%lld absolute:%d", index, tablet);
                 *p_index = index;
                 [self->_qemu mouseSelect:*p_index withCompletion:completion];
             }
         }];
     } else {
-        NSLog(@"selecting input device %lld", *p_index);
+        UTMLog(@"selecting input device %lld", *p_index);
         [_qemu mouseSelect:*p_index withCompletion:completion];
     }
 }

+ 2 - 1
Renderer/UTMRenderer.m

@@ -9,6 +9,7 @@ Implementation of renderer class which performs Metal setup and per frame render
 @import MetalKit;
 
 #import "UTMRenderer.h"
+#import "UTMLogging.h"
 
 // Header shared between C code here, which executes Metal API commands, and .metal files, which
 //   uses these types as inputs to the shaders
@@ -86,7 +87,7 @@ Implementation of renderer class which performs Metal setup and per frame render
             //  If the Metal API validation is enabled, we can find out more information about what
             //  went wrong.  (Metal API validation is enabled by default when a debug build is run
             //  from Xcode)
-            NSLog(@"Failed to created pipeline state, error %@", error);
+            UTMLog(@"Failed to created pipeline state, error %@", error);
         }
 
         // Create the command queue

+ 5 - 4
Views/VMDisplayMetalViewController+Gamepad.m

@@ -22,6 +22,7 @@
 #import "CSDisplayMetal.h"
 #import "UTMConfiguration.h"
 #import "UTMConfiguration+Constants.h"
+#import "UTMLogging.h"
 
 const CGFloat kThumbstickSpeedMultiplier = 1000; // in points per second
 
@@ -41,21 +42,21 @@ const CGFloat kThumbstickSpeedMultiplier = 1000; // in points per second
 - (void)controllerWasConnected:(NSNotification *)notification {
     // a controller was connected
     GCController *controller = (GCController *)notification.object;
-    NSLog(@"Controller connected: %@", controller.vendorName);
+    UTMLog(@"Controller connected: %@", controller.vendorName);
     [self setupController:controller];
 }
 
 - (void)controllerWasDisconnected:(NSNotification *)notification {
     // a controller was disconnected
     GCController *controller = (GCController *)notification.object;
-    NSLog(@"Controller disconnected: %@", controller.vendorName);
+    UTMLog(@"Controller disconnected: %@", controller.vendorName);
 }
 
 - (void)setupController:(GCController *)controller {
     GCExtendedGamepad *gamepad = controller.extendedGamepad;
     __weak typeof(self) _self = self;
     _controller = controller;
-    NSLog(@"active controller switched to: %@", controller.vendorName);
+    UTMLog(@"active controller switched to: %@", controller.vendorName);
     
     gamepad.leftTrigger.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
         [_self gamepadButton:@"GCButtonTriggerLeft" pressed:pressed];
@@ -133,7 +134,7 @@ const CGFloat kThumbstickSpeedMultiplier = 1000; // in points per second
 
 - (void)gamepadButton:(NSString *)identifier pressed:(BOOL)isPressed {
     NSInteger value = [self integerForSetting:identifier];
-    NSLog(@"GC button %@ (%ld) pressed:%d", identifier, value, isPressed);
+    UTMLog(@"GC button %@ (%ld) pressed:%d", identifier, value, isPressed);
     switch (value) {
         case 0:
             break;

+ 3 - 2
Views/VMDisplayMetalViewController+Keyboard.m

@@ -16,6 +16,7 @@
 
 #import "UIViewController+Extensions.h"
 #import "VMDisplayMetalViewController+Keyboard.h"
+#import "UTMLogging.h"
 #import "UTMVirtualMachine.h"
 #import "VMKeyboardView.h"
 #import "VMKeyboardButton.h"
@@ -61,10 +62,10 @@
     UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
     NSString *string = pasteboard.string;
     if (string) {
-        NSLog(@"Pasting: %@", string);
+        UTMLog(@"Pasting: %@", string);
         [self.keyboardView insertText:string];
     } else {
-        NSLog(@"No string to paste.");
+        UTMLog(@"No string to paste.");
     }
 }
 

+ 6 - 5
Views/VMDisplayMetalViewController+Touch.m

@@ -23,6 +23,7 @@
 #import "UTMConfiguration.h"
 #import "UTMConfiguration+Miscellaneous.h"
 #import "UTMSpiceIO.h"
+#import "UTMLogging.h"
 #import "UTMVirtualMachine.h"
 
 const CGFloat kScrollSpeedReduction = 100.0f;
@@ -337,7 +338,7 @@ static CGFloat CGPointToPixel(CGFloat point) {
         [self.vmInput sendMouseMotion:self.mouseButtonDown point:translated];
         [self.vmInput forceCursorPosition:translated]; // required to show cursor on screen
     } else {
-        NSLog(@"Warning: ignored mouse set (%f, %f) while mouse is in server mode", translated.x, translated.y);
+        UTMLog(@"Warning: ignored mouse set (%f, %f) while mouse is in server mode", translated.x, translated.y);
     }
     return translated;
 }
@@ -348,7 +349,7 @@ static CGFloat CGPointToPixel(CGFloat point) {
     if (self.vmInput.serverModeCursor) {
         [self.vmInput sendMouseMotion:self.mouseButtonDown point:translation];
     } else {
-        NSLog(@"Warning: ignored mouse motion (%f, %f) while mouse is in client mode", translation.x, translation.y);
+        UTMLog(@"Warning: ignored mouse motion (%f, %f) while mouse is in client mode", translation.x, translation.y);
     }
     return translation;
 }
@@ -540,7 +541,7 @@ static CGFloat CGPointToPixel(CGFloat point) {
 
 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveEvent:(UIEvent *)event API_AVAILABLE(ios(13.4)) {
     if (event.type == UIEventTypeTransform) {
-        NSLog(@"ignoring UIEventTypeTransform");
+        UTMLog(@"ignoring UIEventTypeTransform");
         return NO;
     } else {
         return YES;
@@ -569,10 +570,10 @@ static CGFloat CGPointToPixel(CGFloat point) {
     BOOL shouldUseServerMouse = (type == VMMouseTypeRelative);
     self.vmInput.inhibitCursor = shouldHideCursor;
     if (shouldUseServerMouse != self.vmInput.serverModeCursor) {
-        NSLog(@"Switching mouse mode to server:%d for type:%ld", shouldUseServerMouse, type);
+        UTMLog(@"Switching mouse mode to server:%d for type:%ld", shouldUseServerMouse, type);
         [self.vm requestInputTablet:!shouldUseServerMouse completion:^(NSString *res, NSError *err) {
             if (err) {
-                NSLog(@"input select returned error: %@", err);
+                UTMLog(@"input select returned error: %@", err);
             } else {
                 [self.spiceIO.primaryInput requestMouseMode:shouldUseServerMouse];
             }

+ 5 - 4
Views/VMDisplayMetalViewController.m

@@ -25,6 +25,7 @@
 #import "UTMQemuManager.h"
 #import "UTMConfiguration.h"
 #import "UTMConfiguration+Display.h"
+#import "UTMLogging.h"
 #import "CSDisplayMetal.h"
 #import "UTMSpiceIO.h"
 
@@ -56,13 +57,13 @@
     // Set the view to use the default device
     self.mtkView.device = MTLCreateSystemDefaultDevice();
     if (!self.mtkView.device) {
-        NSLog(@"Metal is not supported on this device");
+        UTMLog(@"Metal is not supported on this device");
         return;
     }
     
     _renderer = [[UTMRenderer alloc] initWithMetalKitView:self.mtkView];
     if (!_renderer) {
-        NSLog(@"Renderer failed initialization");
+        UTMLog(@"Renderer failed initialization");
         return;
     }
     
@@ -152,7 +153,7 @@
     if ((code & 0xFF00) == 0xE000) {
         code = 0x100 | (code & 0xFF);
     } else if (code >= 0x100) {
-        NSLog(@"warning: ignored invalid keycode 0x%x", code);
+        UTMLog(@"warning: ignored invalid keycode 0x%x", code);
     }
     [self.vmInput sendKey:type code:code];
 }
@@ -193,7 +194,7 @@
 #pragma mark - Notifications
 
 - (void)orientationDidChange:(NSNotification *)notification {
-    NSLog(@"orientation changed");
+    UTMLog(@"orientation changed");
     if (self.vmConfiguration.displayFitScreen) {
         // Bug? on iPad, it seems like [UIScreen mainScreen].bounds does not update when this notification
         // is received. so we race it by waiting 0.1s before getting the new resolution. This does not

+ 2 - 1
Views/VMDisplayTerminalViewController+Keyboard.m

@@ -14,6 +14,7 @@
 // limitations under the License.
 //
 
+#import "UTMLogging.h"
 #import "VMDisplayTerminalViewController+Keyboard.h"
 #import "VMKeyboardButton.h"
 #import "VMKeyboardView.h"
@@ -151,7 +152,7 @@ static int ps2CodeToJs(int ps2Code) {
 - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
     [super traitCollectionDidChange:previousTraitCollection];
     [self updateAccessoryViewHeight];
-    NSLog(@"Trait collection did change");
+    UTMLog(@"Trait collection did change");
 }
 
 - (void)updateAccessoryViewHeight {

+ 10 - 9
Views/VMDisplayTerminalViewController.m

@@ -18,6 +18,7 @@
 #import "VMDisplayTerminalViewController+Keyboard.h"
 #import "UTMConfiguration.h"
 #import "UTMConfiguration+Display.h"
+#import "UTMLogging.h"
 #import "UIViewController+Extensions.h"
 #import "WKWebView+Workarounds.h"
 
@@ -87,10 +88,10 @@ NSString* const kVMSendTerminalSizeHandler = @"UTMSendTerminalSize";
 
 - (void)updateSettings {
     [_webView evaluateJavaScript:[NSString stringWithFormat:@"changeFont('%@', %ld);", self.vmConfiguration.consoleFont, self.vmConfiguration.consoleFontSize.integerValue] completionHandler:^(id _Nullable _, NSError * _Nullable error) {
-        NSLog(@"changeFont error: %@", error);
+        UTMLog(@"changeFont error: %@", error);
     }];
     [_webView evaluateJavaScript:[NSString stringWithFormat:@"setCursorBlink(%@);", self.vmConfiguration.consoleCursorBlink ? @"true" : @"false"] completionHandler:^(id _Nullable _, NSError * _Nullable error) {
-        NSLog(@"setCursorBlink error: %@", error);
+        UTMLog(@"setCursorBlink error: %@", error);
     }];
 }
 
@@ -114,7 +115,7 @@ NSString* const kVMSendTerminalSizeHandler = @"UTMSendTerminalSize";
     NSString* jsString = @"focusTerminal()";
     [_webView evaluateJavaScript: jsString completionHandler:^(id _Nullable _, NSError * _Nullable error) {
         if (error != nil) {
-            NSLog(@"Error while focusing terminal element: %@", error);
+            UTMLog(@"Error while focusing terminal element: %@", error);
         }
         [self->_webView toggleKeyboardDisplayRequiresUserAction:YES];
     }];
@@ -155,16 +156,16 @@ NSString* const kVMSendTerminalSizeHandler = @"UTMSendTerminalSize";
 
 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
     if ([[message name] isEqualToString: kVMSendInputHandler]) {
-        NSLog(@"Received input from HTerm: %@", (NSString*) message.body);
+        UTMLog(@"Received input from HTerm: %@", (NSString*) message.body);
         [_terminal sendInput: (NSString*) message.body];
         [self resetModifierToggles];
     } else if ([[message name] isEqualToString: kVMDebugHandler]) {
-        NSLog(@"Debug message from HTerm: %@", (NSString*) message.body);
+        UTMLog(@"Debug message from HTerm: %@", (NSString*) message.body);
     } else if ([[message name] isEqualToString: kVMSendGestureHandler]) {
-        NSLog(@"Gesture message from HTerm: %@", (NSString*) message.body);
+        UTMLog(@"Gesture message from HTerm: %@", (NSString*) message.body);
         [self handleGestureFromJs:message.body];
     } else if ([[message name] isEqualToString: kVMSendTerminalSizeHandler]) {
-        NSLog(@"Terminal resize: %@", message.body);
+        UTMLog(@"Terminal resize: %@", message.body);
         self.columns = message.body[0];
         self.rows = message.body[1];
     }
@@ -179,11 +180,11 @@ NSString* const kVMSendTerminalSizeHandler = @"UTMSendTerminalSize";
         [dataString appendFormat: @"%u,", buf[i]];
     }
     [dataString appendString:@"]"];
-    //NSLog(@"Array: %@", dataString);
+    //UTMLog(@"Array: %@", dataString);
     NSString* jsString = [NSString stringWithFormat: @"writeData(new Uint8Array(%@));", dataString];
     [_webView evaluateJavaScript: jsString completionHandler:^(id _Nullable _, NSError * _Nullable error) {
         if (error != nil) {
-            NSLog(@"JS evaluation failed: %@", [error localizedDescription]);
+            UTMLog(@"JS evaluation failed: %@", [error localizedDescription]);
         }
     }];
 }

+ 9 - 8
Views/VMDisplayViewController.m

@@ -17,6 +17,7 @@
 #import "VMDisplayViewController.h"
 #import "UIViewController+Extensions.h"
 #import "UTMLocationManager.h"
+#import "UTMLogging.h"
 #import "UTMVirtualMachine.h"
 #import "VMConfigExistingViewController.h"
 #import "VMDisplayViewSoftKeyboard.h"
@@ -119,7 +120,7 @@
 - (void)viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
     if (self.runInBackground) {
-        NSLog(@"Start location tracking to enable running in background");
+        UTMLog(@"Start location tracking to enable running in background");
         [[UTMLocationManager sharedInstance] startUpdatingLocation];
     }
 }
@@ -304,18 +305,18 @@
 #pragma mark - Notification Handling
 
 - (void)handleEnteredBackground:(NSNotification *)notification {
-    NSLog(@"Entering background");
+    UTMLog(@"Entering background");
     if (self.autosaveBackground && self.vm.state == kVMStarted) {
-        NSLog(@"Saving snapshot");
+        UTMLog(@"Saving snapshot");
         __block UIBackgroundTaskIdentifier task = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
-            NSLog(@"Background task end");
+            UTMLog(@"Background task end");
             [[UIApplication sharedApplication] endBackgroundTask:task];
             task = UIBackgroundTaskInvalid;
         }];
         dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
             [self.vm saveVM];
             self->_hasAutoSave = YES;
-            NSLog(@"Save snapshot complete");
+            UTMLog(@"Save snapshot complete");
             [[UIApplication sharedApplication] endBackgroundTask:task];
             task = UIBackgroundTaskInvalid;
         });
@@ -323,9 +324,9 @@
 }
 
 - (void)handleEnteredForeground:(NSNotification *)notification {
-    NSLog(@"Entering foreground!");
+    UTMLog(@"Entering foreground!");
     if (_hasAutoSave && self.vm.state == kVMStarted) {
-        NSLog(@"Deleting snapshot");
+        UTMLog(@"Deleting snapshot");
         dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
             [self.vm deleteSaveVM];
         });
@@ -338,7 +339,7 @@
     [super didReceiveMemoryWarning];
     
     if (self.autosaveLowMemory) {
-        NSLog(@"Saving VM state on low memory warning.");
+        UTMLog(@"Saving VM state on low memory warning.");
         dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
             [self.vm saveVM];
         });

+ 8 - 7
Views/VMKeyboardView.m

@@ -37,6 +37,7 @@
  */
 
 #import "VMKeyboardView.h"
+#import "UTMLogging.h"
 #import "ctype.h"
 
 typedef struct {
@@ -402,7 +403,7 @@ static int indexForExtChar(const ext_key_mapping_t *table, size_t table_len, cha
 
 - (void)insertUTF8Sequence:(const char *)ctext {
     unsigned long ctext_len = strlen(ctext);
-    NSLog(@"ctext length=%lu\n", ctext_len);
+    UTMLog(@"ctext length=%lu\n", ctext_len);
     unsigned char tc = ctext[0];
     
     int keycode = 0;
@@ -425,7 +426,7 @@ static int indexForExtChar(const ext_key_mapping_t *table, size_t table_len, cha
     
     switch (ctext_len) {
         case 1:
-            NSLog(@"char=%d\n", tc);
+            UTMLog(@"char=%d\n", tc);
             index = indexForChar(_map, _map_len, tc);
             if (index != -1) {
                 keycode = _map[index].key;
@@ -433,8 +434,8 @@ static int indexForExtChar(const ext_key_mapping_t *table, size_t table_len, cha
             }
             break;
         case 2:
-            NSLog(@"char=%d\n", tc);
-            NSLog(@"ext1=%d\n", (unsigned char) ctext[1]);
+            UTMLog(@"char=%d\n", tc);
+            UTMLog(@"ext1=%d\n", (unsigned char) ctext[1]);
             index = indexForExtChar(_ext_map, _ext_map_len, tc, ctext[1], 0);
             if (index != -1) {
                 keycode = _ext_map[index].key;
@@ -444,9 +445,9 @@ static int indexForExtChar(const ext_key_mapping_t *table, size_t table_len, cha
             }
             break;
         case 3:
-            NSLog(@"char=%d\n", tc);
-            NSLog(@"ext1=%d\n", (unsigned char) ctext[1]);
-            NSLog(@"ext2=%d\n", (unsigned char) ctext[2]);
+            UTMLog(@"char=%d\n", tc);
+            UTMLog(@"ext1=%d\n", (unsigned char) ctext[1]);
+            UTMLog(@"ext2=%d\n", (unsigned char) ctext[2]);
             index = indexForExtChar(_ext_map, _ext_map_len, tc, ctext[1], ctext[2]);
             if (index != -1) {
                 keycode = _ext_map[index].key;

+ 0 - 1
Views/WKWebView+Workarounds.m

@@ -146,7 +146,6 @@ static char inputAccessoryViewKey;
     for (UIView* view in self.scrollView.subviews) {
         if ([NSStringFromClass([view class]) hasPrefix: @"WKContent"]) {
             targetView = view;
-            NSLog(@"View class: %@", NSStringFromClass([targetView class]));
             break;
         }
     }