diff --git a/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m b/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m index 67c663d..3b7280e 100644 --- a/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m +++ b/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m @@ -216,27 +216,27 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; @"AppDelegateProxy interceptor does not conform to UIApplicationDelegate"); if (!interceptor) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling000], - @"AppDelegateProxy cannot add nil interceptor."); + GULOSLogError(kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString stringWithFormat:@"I-SWZ%06ld", + (long)kGULSwizzlerMessageCodeAppDelegateSwizzling000], + @"AppDelegateProxy cannot add nil interceptor."); return nil; } if (![interceptor conformsToProtocol:@protocol(GULApplicationDelegate)]) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling001], - @"AppDelegateProxy interceptor does not conform to UIApplicationDelegate"); + GULOSLogError(kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString stringWithFormat:@"I-SWZ%06ld", + (long)kGULSwizzlerMessageCodeAppDelegateSwizzling001], + @"AppDelegateProxy interceptor does not conform to UIApplicationDelegate"); return nil; } // The ID should be the same given the same interceptor object. NSString *interceptorID = [NSString stringWithFormat:@"%@%p", kGULAppDelegatePrefix, interceptor]; if (!interceptorID.length) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling002], - @"AppDelegateProxy cannot create Interceptor ID."); + GULOSLogError(kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString stringWithFormat:@"I-SWZ%06ld", + (long)kGULSwizzlerMessageCodeAppDelegateSwizzling002], + @"AppDelegateProxy cannot create Interceptor ID."); return nil; } GULZeroingWeakContainer *weakObject = [[GULZeroingWeakContainer alloc] init]; @@ -251,21 +251,21 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; @"AppDelegateProxy cannot unregister empty interceptor ID."); if (!interceptorID) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling003], - @"AppDelegateProxy cannot unregister empty interceptor ID."); + GULOSLogError(kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString stringWithFormat:@"I-SWZ%06ld", + (long)kGULSwizzlerMessageCodeAppDelegateSwizzling003], + @"AppDelegateProxy cannot unregister empty interceptor ID."); return; } GULZeroingWeakContainer *weakContainer = [GULAppDelegateSwizzler interceptors][interceptorID]; if (!weakContainer.object) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling004], - @"AppDelegateProxy cannot unregister interceptor that was not registered. " - "Interceptor ID %@", - interceptorID); + GULOSLogError(kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString stringWithFormat:@"I-SWZ%06ld", + (long)kGULSwizzlerMessageCodeAppDelegateSwizzling004], + @"AppDelegateProxy cannot unregister interceptor that was not registered. " + "Interceptor ID %@", + interceptorID); return; } @@ -343,12 +343,13 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; [NSString stringWithFormat:@"%@-%@", classNameWithPrefix, [NSUUID UUID].UUIDString]; if (NSClassFromString(newClassName)) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling005], - @"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: " - @"%@, subclass: %@", - NSStringFromClass(realClass), newClassName); + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeAppDelegateSwizzling005], + @"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: " + @"%@, subclass: %@", + NSStringFromClass(realClass), newClassName); return nil; } @@ -356,12 +357,13 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; // size. Class appDelegateSubClass = objc_allocateClassPair(realClass, newClassName.UTF8String, 0); if (appDelegateSubClass == Nil) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling006], - @"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: " - @"%@, subclass: Nil", - NSStringFromClass(realClass)); + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeAppDelegateSwizzling006], + @"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: " + @"%@, subclass: Nil", + NSStringFromClass(realClass)); return nil; } @@ -436,12 +438,13 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; // cannot have more ivars/properties than its superclass since it will cause an offset in memory // that can lead to overwriting the isa of an object in the next frame. if (class_getInstanceSize(realClass) != class_getInstanceSize(appDelegateSubClass)) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling007], - @"Cannot create subclass of App Delegate, because the created subclass is not the " - @"same size. %@", - NSStringFromClass(realClass)); + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeAppDelegateSwizzling007], + @"Cannot create subclass of App Delegate, because the created subclass is not the " + @"same size. %@", + NSStringFromClass(realClass)); NSAssert(NO, @"Classes must be the same size to swizzle isa"); return nil; } @@ -449,12 +452,12 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; // Make the newly created class to be the subclass of the real App Delegate class. objc_registerClassPair(appDelegateSubClass); if (object_setClass(appDelegate, appDelegateSubClass)) { - GULLogDebug(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling008], - @"Successfully created App Delegate Proxy automatically. To disable the " - @"proxy, set the flag %@ to NO (Boolean) in the Info.plist", - [GULAppDelegateSwizzler correctAppDelegateProxyKey]); + GULOSLogDebug(kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString stringWithFormat:@"I-SWZ%06ld", + (long)kGULSwizzlerMessageCodeAppDelegateSwizzling008], + @"Successfully created App Delegate Proxy automatically. To disable the " + @"proxy, set the flag %@ to NO (Boolean) in the Info.plist", + [GULAppDelegateSwizzler correctAppDelegateProxyKey]); } return appDelegateSubClass; @@ -604,11 +607,12 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; IMP methodIMP = method_getImplementation(method); const char *types = method_getTypeEncoding(method); if (!class_addMethod(toClass, destinationSelector, methodIMP, types)) { - GULLogWarning(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling009], - @"Cannot copy method to destination selector %@ as it already exists", - NSStringFromSelector(destinationSelector)); + GULOSLogWarning( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeAppDelegateSwizzling009], + @"Cannot copy method to destination selector %@ as it already exists", + NSStringFromSelector(destinationSelector)); } } @@ -640,8 +644,8 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; GULZeroingWeakContainer *interceptorContainer = obj; id interceptor = interceptorContainer.object; if (!interceptor) { - GULLogWarning( - kGULLoggerSwizzler, NO, + GULOSLogWarning( + kGULLogSubsystem, kGULLoggerSwizzler, NO, [NSString stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeAppDelegateSwizzling010], @"AppDelegateProxy cannot find interceptor with ID %@. Removing the interceptor.", key); @@ -943,8 +947,8 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; + (void)proxyAppDelegate:(id)appDelegate { if (![appDelegate conformsToProtocol:@protocol(GULApplicationDelegate)]) { - GULLogNotice( - kGULLoggerSwizzler, NO, + GULOSLogNotice( + kGULLogSubsystem, kGULLoggerSwizzler, NO, [NSString stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeAppDelegateSwizzlingInvalidAppDelegate], @@ -956,20 +960,20 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; id originalDelegate = appDelegate; // Do not create a subclass if it is not enabled. if (![GULAppDelegateSwizzler isAppDelegateProxyEnabled]) { - GULLogNotice(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling011], - @"App Delegate Proxy is disabled. %@", - [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]); + GULOSLogNotice(kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString stringWithFormat:@"I-SWZ%06ld", + (long)kGULSwizzlerMessageCodeAppDelegateSwizzling011], + @"App Delegate Proxy is disabled. %@", + [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]); return; } // Do not accept nil delegate. if (!originalDelegate) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling012], - @"Cannot create App Delegate Proxy because App Delegate instance is nil. %@", - [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]); + GULOSLogError(kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString stringWithFormat:@"I-SWZ%06ld", + (long)kGULSwizzlerMessageCodeAppDelegateSwizzling012], + @"Cannot create App Delegate Proxy because App Delegate instance is nil. %@", + [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]); return; } @@ -978,11 +982,11 @@ static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken; gAppDelegateSubclass = [self createSubclassWithObject:originalDelegate]; [self reassignAppDelegate]; } @catch (NSException *exception) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeAppDelegateSwizzling013], - @"Cannot create App Delegate Proxy. %@", - [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]); + GULOSLogError(kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString stringWithFormat:@"I-SWZ%06ld", + (long)kGULSwizzlerMessageCodeAppDelegateSwizzling013], + @"Cannot create App Delegate Proxy. %@", + [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]); return; } } diff --git a/GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m b/GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m index 36ba1ca..87adac4 100644 --- a/GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m +++ b/GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m @@ -108,17 +108,19 @@ static NSString *const kGULSceneDelegatePrefix = @"GUL_"; @"SceneDelegateProxy interceptor does not conform to UIApplicationDelegate"); if (!interceptor) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling000], - @"SceneDelegateProxy cannot add nil interceptor."); + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling000], + @"SceneDelegateProxy cannot add nil interceptor."); return nil; } if (![interceptor conformsToProtocol:@protocol(UISceneDelegate)]) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling001], - @"SceneDelegateProxy interceptor does not conform to UIApplicationDelegate"); + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling001], + @"SceneDelegateProxy interceptor does not conform to UIApplicationDelegate"); return nil; } @@ -126,10 +128,11 @@ static NSString *const kGULSceneDelegatePrefix = @"GUL_"; NSString *interceptorID = [NSString stringWithFormat:@"%@%p", kGULSceneDelegatePrefix, interceptor]; if (!interceptorID.length) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling002], - @"SceneDelegateProxy cannot create Interceptor ID."); + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling002], + @"SceneDelegateProxy cannot create Interceptor ID."); return nil; } GULSceneZeroingWeakContainer *weakObject = [[GULSceneZeroingWeakContainer alloc] init]; @@ -144,22 +147,24 @@ static NSString *const kGULSceneDelegatePrefix = @"GUL_"; @"SceneDelegateProxy cannot unregister empty interceptor ID."); if (!interceptorID) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling003], - @"SceneDelegateProxy cannot unregister empty interceptor ID."); + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling003], + @"SceneDelegateProxy cannot unregister empty interceptor ID."); return; } GULSceneZeroingWeakContainer *weakContainer = [GULSceneDelegateSwizzler interceptors][interceptorID]; if (!weakContainer.object) { - GULLogError(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling004], - @"SceneDelegateProxy cannot unregister interceptor that was not registered. " - "Interceptor ID %@", - interceptorID); + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling004], + @"SceneDelegateProxy cannot unregister interceptor that was not registered. " + "Interceptor ID %@", + interceptorID); return; } @@ -247,8 +252,8 @@ static NSString *const kGULSceneDelegatePrefix = @"GUL_"; IMP methodIMP = method_getImplementation(method); const char *types = method_getTypeEncoding(method); if (!class_addMethod(toClass, destinationSelector, methodIMP, types)) { - GULLogWarning( - kGULLoggerSwizzler, NO, + GULOSLogWarning( + kGULLogSubsystem, kGULLoggerSwizzler, NO, [NSString stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling009], @"Cannot copy method to destination selector %@ as it already exists", @@ -285,8 +290,8 @@ static NSString *const kGULSceneDelegatePrefix = @"GUL_"; GULSceneZeroingWeakContainer *interceptorContainer = obj; id interceptor = interceptorContainer.object; if (!interceptor) { - GULLogWarning( - kGULLoggerSwizzler, NO, + GULOSLogWarning( + kGULLogSubsystem, kGULLoggerSwizzler, NO, [NSString stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling010], @"SceneDelegateProxy cannot find interceptor with ID %@. Removing the interceptor.", key); @@ -351,8 +356,8 @@ static NSString *const kGULSceneDelegatePrefix = @"GUL_"; [NSString stringWithFormat:@"%@-%@", classNameWithPrefix, [NSUUID UUID].UUIDString]; if (NSClassFromString(newClassName)) { - GULLogError( - kGULLoggerSwizzler, NO, + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, [NSString stringWithFormat:@"I-SWZ%06ld", (long) @@ -367,8 +372,8 @@ static NSString *const kGULSceneDelegatePrefix = @"GUL_"; // size. Class sceneDelegateSubClass = objc_allocateClassPair(realClass, newClassName.UTF8String, 0); if (sceneDelegateSubClass == Nil) { - GULLogError( - kGULLoggerSwizzler, NO, + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, [NSString stringWithFormat:@"I-SWZ%06ld", (long) @@ -401,8 +406,8 @@ static NSString *const kGULSceneDelegatePrefix = @"GUL_"; // cannot have more ivars/properties than its superclass since it will cause an offset in memory // that can lead to overwriting the isa of an object in the next frame. if (class_getInstanceSize(realClass) != class_getInstanceSize(sceneDelegateSubClass)) { - GULLogError( - kGULLoggerSwizzler, NO, + GULOSLogError( + kGULLogSubsystem, kGULLoggerSwizzler, NO, [NSString stringWithFormat:@"I-SWZ%06ld", (long) @@ -417,8 +422,8 @@ static NSString *const kGULSceneDelegatePrefix = @"GUL_"; // Make the newly created class to be the subclass of the real Scene Delegate class. objc_registerClassPair(sceneDelegateSubClass); if (object_setClass(scene.delegate, sceneDelegateSubClass)) { - GULLogDebug( - kGULLoggerSwizzler, NO, + GULOSLogDebug( + kGULLogSubsystem, kGULLoggerSwizzler, NO, [NSString stringWithFormat:@"I-SWZ%06ld", (long) diff --git a/GoogleUtilities/Logger/GULLogger.m b/GoogleUtilities/Logger/GULLogger.m index 015db14..8a1c2be 100644 --- a/GoogleUtilities/Logger/GULLogger.m +++ b/GoogleUtilities/Logger/GULLogger.m @@ -14,18 +14,13 @@ #import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h" -#include +#import #import "GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h" #import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h" -/// ASL client facility name used by GULLogger. -const char *kGULLoggerASLClientFacilityName = "com.google.utilities.logger"; - static dispatch_once_t sGULLoggerOnceToken; -static aslclient sGULLoggerClient; - static dispatch_queue_t sGULClientQueue; static BOOL sGULLoggerDebugMode; @@ -35,42 +30,25 @@ static GULLoggerLevel sGULLoggerMaximumLevel; // Allow clients to register a version to include in the log. static NSString *sVersion = @""; +NSString *const kGULLogSubsystem = @"com.google.utilities.logger"; + static GULLoggerService kGULLoggerLogger = @"[GULLogger]"; +static NSMutableDictionary *> + *sGULServiceLogs; + #ifdef DEBUG /// The regex pattern for the message code. static NSString *const kMessageCodePattern = @"^I-[A-Z]{3}[0-9]{6}$"; static NSRegularExpression *sMessageCodeRegex; #endif -void GULLoggerInitializeASL(void) { +void GULLoggerInitialize(void) { dispatch_once(&sGULLoggerOnceToken, ^{ - NSInteger majorOSVersion = [[GULAppEnvironmentUtil systemVersion] integerValue]; - uint32_t aslOptions = ASL_OPT_STDERR; -#if TARGET_OS_SIMULATOR - // The iOS 11 simulator doesn't need the ASL_OPT_STDERR flag. - if (majorOSVersion >= 11) { - aslOptions = 0; - } -#else - // Devices running iOS 10 or higher don't need the ASL_OPT_STDERR flag. - if (majorOSVersion >= 10) { - aslOptions = 0; - } -#endif // TARGET_OS_SIMULATOR - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" // asl is deprecated - // Initialize the ASL client handle. - sGULLoggerClient = asl_open(NULL, kGULLoggerASLClientFacilityName, aslOptions); - sGULLoggerMaximumLevel = GULLoggerLevelNotice; - - // Set the filter used by system/device log. Initialize in default mode. - asl_set_filter(sGULLoggerClient, ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE)); - sGULClientQueue = dispatch_queue_create("GULLoggingClientQueue", DISPATCH_QUEUE_SERIAL); dispatch_set_target_queue(sGULClientQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)); + sGULServiceLogs = [NSMutableDictionary dictionary]; #ifdef DEBUG sMessageCodeRegex = [NSRegularExpression regularExpressionWithPattern:kMessageCodePattern options:0 @@ -79,8 +57,12 @@ void GULLoggerInitializeASL(void) { }); } +void GULLoggerInitializeASL(void) { + GULLoggerInitialize(); +} + void GULLoggerEnableSTDERR(void) { - asl_add_log_file(sGULLoggerClient, STDERR_FILENO); + // No-op } void GULLoggerForceDebug(void) { @@ -97,27 +79,24 @@ GULLoggerLevel GULGetLoggerLevel(void) { __attribute__((no_sanitize("thread"))) void GULSetLoggerLevel(GULLoggerLevel loggerLevel) { if (loggerLevel < GULLoggerLevelMin || loggerLevel > GULLoggerLevelMax) { - GULLogError(kGULLoggerLogger, NO, @"I-COR000023", @"Invalid logger level, %ld", - (long)loggerLevel); + GULOSLogError(kGULLogSubsystem, kGULLoggerLogger, NO, @"I-COR000023", + @"Invalid logger level, %ld", (long)loggerLevel); return; } - GULLoggerInitializeASL(); + GULLoggerInitialize(); // We should not raise the logger level if we are running from App Store. if (loggerLevel >= GULLoggerLevelNotice && [GULAppEnvironmentUtil isFromAppStore]) { return; } sGULLoggerMaximumLevel = loggerLevel; - dispatch_async(sGULClientQueue, ^{ - asl_set_filter(sGULLoggerClient, ASL_FILTER_MASK_UPTO(loggerLevel)); - }); } /** * Check if the level is high enough to be loggable. */ __attribute__((no_sanitize("thread"))) BOOL GULIsLoggableLevel(GULLoggerLevel loggerLevel) { - GULLoggerInitializeASL(); + GULLoggerInitialize(); if (sGULLoggerDebugMode) { return YES; } @@ -131,10 +110,6 @@ void GULResetLogger(void) { sGULLoggerMaximumLevel = GULLoggerLevelNotice; } -aslclient getGULLoggerClient(void) { - return sGULLoggerClient; -} - dispatch_queue_t getGULClientQueue(void) { return sGULClientQueue; } @@ -148,13 +123,28 @@ void GULLoggerRegisterVersion(NSString *version) { sVersion = version; } -void GULLogBasic(GULLoggerLevel level, - GULLoggerService service, - BOOL forceLog, - NSString *messageCode, - NSString *message, - va_list args_ptr) { - GULLoggerInitializeASL(); +os_log_type_t GULLoggerLevelToOSLogType(GULLoggerLevel level) { + switch (level) { + case GULLoggerLevelError: + return OS_LOG_TYPE_ERROR; + case GULLoggerLevelWarning: + case GULLoggerLevelNotice: + return OS_LOG_TYPE_DEFAULT; + case GULLoggerLevelInfo: + return OS_LOG_TYPE_INFO; + case GULLoggerLevelDebug: + return OS_LOG_TYPE_DEBUG; + } +} + +void GULOSLogBasic(GULLoggerLevel level, + NSString *subsystem, + NSString *category, + BOOL forceLog, + NSString *messageCode, + NSString *message, + va_list args_ptr) { + GULLoggerInitialize(); if (!(level <= sGULLoggerMaximumLevel || sGULLoggerDebugMode || forceLog)) { return; } @@ -172,12 +162,32 @@ void GULLogBasic(GULLoggerLevel level, } else { logMsg = [[NSString alloc] initWithFormat:message arguments:args_ptr]; } - logMsg = [NSString stringWithFormat:@"%@ - %@[%@] %@", sVersion, service, messageCode, logMsg]; + logMsg = [NSString stringWithFormat:@"%@ - %@[%@] %@", sVersion, category, messageCode, logMsg]; dispatch_async(sGULClientQueue, ^{ - asl_log(sGULLoggerClient, NULL, (int)level, "%s", logMsg.UTF8String); + NSMutableDictionary *subsystemLogs = sGULServiceLogs[subsystem]; + if (!subsystemLogs) { + subsystemLogs = [NSMutableDictionary dictionary]; + sGULServiceLogs[subsystem] = subsystemLogs; + } + + os_log_t serviceLog = [subsystemLogs objectForKey:subsystem]; + if (!serviceLog) { + serviceLog = os_log_create(subsystem.UTF8String, category.UTF8String); + subsystemLogs[category] = serviceLog; + } + + os_log_with_type(serviceLog, GULLoggerLevelToOSLogType(level), "%{public}@", logMsg); }); } -#pragma clang diagnostic pop + +void GULLogBasic(GULLoggerLevel level, + GULLoggerService service, + BOOL forceLog, + NSString *messageCode, + NSString *message, + va_list args_ptr) { + GULOSLogBasic(level, kGULLogSubsystem, service, forceLog, messageCode, message, args_ptr); +} /** * Generates the logging functions using macros. @@ -202,18 +212,53 @@ GUL_LOGGING_FUNCTION(Notice) GUL_LOGGING_FUNCTION(Info) GUL_LOGGING_FUNCTION(Debug) -#undef GUL_MAKE_LOGGER +#undef GUL_LOGGING_FUNCTION + +/** + * Generates the logging functions using macros. + * + * Calling GULLogError({service}, @"I-XYZ000001", @"Configure %@ failed.", @"blah") shows: + * yyyy-mm-dd hh:mm:ss.SSS sender[PID] [{service}][I-XYZ000001] Configure blah failed. + * Calling GULLogDebug({service}, @"I-XYZ000001", @"Configure succeed.") shows: + * yyyy-mm-dd hh:mm:ss.SSS sender[PID] [{service}][I-XYZ000001] Configure succeed. + */ +#define GUL_LOGGING_FUNCTION(level) \ + void GULOSLog##level(NSString *subsystem, NSString *category, BOOL force, NSString *messageCode, \ + NSString *message, ...) { \ + va_list args_ptr; \ + va_start(args_ptr, message); \ + GULOSLogBasic(GULLoggerLevel##level, subsystem, category, force, messageCode, message, \ + args_ptr); \ + va_end(args_ptr); \ + } + +GUL_LOGGING_FUNCTION(Error) +GUL_LOGGING_FUNCTION(Warning) +GUL_LOGGING_FUNCTION(Notice) +GUL_LOGGING_FUNCTION(Info) +GUL_LOGGING_FUNCTION(Debug) + +#undef GUL_LOGGING_FUNCTION #pragma mark - GULLoggerWrapper @implementation GULLoggerWrapper ++ (void)logWithLevel:(GULLoggerLevel)level + subsystem:(NSString *)subsystem + category:(GULLoggerService)category + messageCode:(NSString *)messageCode + message:(NSString *)message + arguments:(va_list)args { + GULOSLogBasic(level, subsystem, category, NO, messageCode, message, args); +} + + (void)logWithLevel:(GULLoggerLevel)level withService:(GULLoggerService)service withCode:(NSString *)messageCode withMessage:(NSString *)message withArgs:(va_list)args { - GULLogBasic(level, service, NO, messageCode, message, args); + GULOSLogBasic(level, kGULLogSubsystem, service, NO, messageCode, message, args); } @end diff --git a/GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h b/GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h index 3643568..f4813ce 100644 --- a/GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h +++ b/GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h @@ -22,6 +22,8 @@ NS_ASSUME_NONNULL_BEGIN /** * The services used in the logger. + * + * DEPRECATED; use NSString instead. */ typedef NSString *const GULLoggerService; @@ -29,24 +31,28 @@ typedef NSString *const GULLoggerService; extern "C" { #endif // __cplusplus -/** - * Initialize GULLogger. - */ +/// DEPRECATED; provide a relevant subsystem name rather than using default. +extern NSString *const kGULLogSubsystem; + +/// Initialize GULLogger. +extern void GULLoggerInitialize(void); + +/// Initialize GULLogger. +/// +/// The Apple System Log (ASL) in Google Utilities Logger has been replaced by OSLog. +/// +/// DEPRECATED; simply calls its replacement `GULLoggerInitialize`. extern void GULLoggerInitializeASL(void); -/** - * Override log level to Debug. - */ +/// Override log level to Debug. void GULLoggerForceDebug(void); -/** - * Turn on logging to STDERR. - */ +/// Turn on logging to STDERR. +/// +/// DEPRECATED; this function is a no-op. extern void GULLoggerEnableSTDERR(void); -/** - * Gets the current GULLoggerLevel. - */ +/// Gets the current `GULLoggerLevel`. extern GULLoggerLevel GULGetLoggerLevel(void); /** @@ -81,6 +87,36 @@ extern void GULLoggerRegisterVersion(NSString *version); * (optional) variable arguments list obtained from calling va_start, used when message is a format * string. */ +extern void GULOSLogBasic(GULLoggerLevel level, + NSString *subsystem, + NSString *category, + BOOL forceLog, + NSString *messageCode, + NSString *message, +// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable +// See: http://stackoverflow.com/q/29095469 +#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX + va_list args_ptr +#else + va_list _Nullable args_ptr +#endif +); + +/** + * Logs a message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than GULLoggerLevelNotice to avoid log spamming. + * (required) log level (one of the GULLoggerLevel enum values). + * (required) service name of type GULLoggerService. + * (required) message code starting with "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * (required) message string which can be a format string. + * (optional) variable arguments list obtained from calling va_start, used when message is a format + * string. + * + * DEPRECATED; replaced by `GULOSLogBasic`. + */ extern void GULLogBasic(GULLoggerLevel level, GULLoggerService service, BOOL forceLog, @@ -107,32 +143,68 @@ extern void GULLogBasic(GULLoggerLevel level, * (optional) the list of arguments to substitute into the format string. * Example usage: * GULLogError(kGULLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); + * + * DEPRECATED; replaced by `GULOSLogError`, `GULOSLogWarning`, etc. */ -extern void GULLogError(GULLoggerService service, - BOOL force, - NSString *messageCode, - NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); -extern void GULLogWarning(GULLoggerService service, +extern void GULLogError( + GULLoggerService service, BOOL force, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(4, 5) DEPRECATED_MSG_ATTRIBUTE("Replaced by `GULOSLogError`."); +extern void GULLogWarning( + GULLoggerService service, BOOL force, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(4, 5) DEPRECATED_MSG_ATTRIBUTE("Replaced by `GULOSLogWarning`."); +extern void GULLogNotice( + GULLoggerService service, BOOL force, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(4, 5) DEPRECATED_MSG_ATTRIBUTE("Replaced by `GULOSLogInfo`."); +extern void GULLogInfo( + GULLoggerService service, BOOL force, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(4, 5) DEPRECATED_MSG_ATTRIBUTE("Replaced by `GULOSLogInfo`."); +extern void GULLogDebug( + GULLoggerService service, BOOL force, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(4, 5) DEPRECATED_MSG_ATTRIBUTE("Replaced by `GULOSLogDebug`."); + +/** + * The following functions accept the following parameters in order: + * (required) service name of type GULLoggerService. + * (required) message code starting from "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * See go/firebase-log-proposal for details. + * (required) message string which can be a format string. + * (optional) the list of arguments to substitute into the format string. + * Example usage: + * GULLogError(kGULLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); + */ +extern void GULOSLogError(NSString *subsystem, + GULLoggerService category, BOOL force, NSString *messageCode, NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); -extern void GULLogNotice(GULLoggerService service, + ...) NS_FORMAT_FUNCTION(5, 6); +extern void GULOSLogWarning(NSString *subsystem, + GULLoggerService category, + BOOL force, + NSString *messageCode, + NSString *message, + ...) NS_FORMAT_FUNCTION(5, 6); +extern void GULOSLogNotice(NSString *subsystem, + GULLoggerService category, + BOOL force, + NSString *messageCode, + NSString *message, + ...) NS_FORMAT_FUNCTION(5, 6); +extern void GULOSLogInfo(NSString *subsystem, + GULLoggerService category, BOOL force, NSString *messageCode, NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); -extern void GULLogInfo(GULLoggerService service, - BOOL force, - NSString *messageCode, - NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); -extern void GULLogDebug(GULLoggerService service, - BOOL force, - NSString *messageCode, - NSString *message, - ...) NS_FORMAT_FUNCTION(4, 5); + ...) NS_FORMAT_FUNCTION(5, 6); +extern void GULOSLogDebug(NSString *subsystem, + GULLoggerService category, + BOOL force, + NSString *messageCode, + NSString *message, + ...) NS_FORMAT_FUNCTION(5, 6); #ifdef __cplusplus } // extern "C" @@ -140,6 +212,26 @@ extern void GULLogDebug(GULLoggerService service, @interface GULLoggerWrapper : NSObject +/// Objective-C wrapper for `GULOSLogBasic` to allow weak linking to `GULLogger`. +/// +/// - Parameters: +/// - level: The log level (one of the `GULLoggerLevel` enum values). +/// - subsystem: An identifier for the subsystem performing logging, e.g., `com.example.logger`. +/// - category: The category name within the `subsystem` to group related messages, e.g., +/// `[GoogleUtilities/Example]`. +/// - messageCode: The message code starting with "I-" which means iOS, followed by a capitalized +/// three-character service identifier and a six digit integer message ID that is unique within +/// the service. An example of the message code is @"I-COR000001". +/// - message: The message to log, which may be a format string. +/// - arguments: The variable arguments list obtained from calling va_start, used when message is +/// a format string; optional if `message` is not a format string. ++ (void)logWithLevel:(GULLoggerLevel)level + subsystem:(NSString *)subsystem + category:(NSString *)category + messageCode:(NSString *)messageCode + message:(NSString *)message + arguments:(va_list)args; + /** * Objective-C wrapper for GULLogBasic to allow weak linking to GULLogger * (required) log level (one of the GULLoggerLevel enum values). @@ -151,8 +243,9 @@ extern void GULLogDebug(GULLoggerService service, * (required) message string which can be a format string. * (optional) variable arguments list obtained from calling va_start, used when message is a format * string. + * + * DEPRECATED; replaced by `logWithLevel:subsystem:category:messageCode:message:arguments:`. */ - + (void)logWithLevel:(GULLoggerLevel)level withService:(GULLoggerService)service withCode:(NSString *)messageCode diff --git a/GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h b/GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h index f7b28e5..6a68eb1 100644 --- a/GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h +++ b/GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h @@ -18,23 +18,29 @@ NS_ASSUME_NONNULL_BEGIN -/** - * The log levels used by internal logging. - */ +/// The log levels used by internal logging. typedef NS_ENUM(NSInteger, GULLoggerLevel) { - /** Error level, matches ASL_LEVEL_ERR. */ - GULLoggerLevelError = 3, - /** Warning level, matches ASL_LEVEL_WARNING. */ - GULLoggerLevelWarning = 4, - /** Notice level, matches ASL_LEVEL_NOTICE. */ - GULLoggerLevelNotice = 5, - /** Info level, matches ASL_LEVEL_INFO. */ - GULLoggerLevelInfo = 6, - /** Debug level, matches ASL_LEVEL_DEBUG. */ - GULLoggerLevelDebug = 7, - /** Minimum log level. */ + /// Error level, corresponding to `OS_LOG_TYPE_ERROR`. + GULLoggerLevelError = 3, // For backwards compatibility, the enum value matches `ASL_LEVEL_ERR`. + + /// Warning level, corresponding to `OS_LOG_TYPE_DEFAULT`. + /// + /// > Note: Since OSLog doesn't have a WARNING type, this is equivalent to `GULLoggerLevelNotice`. + GULLoggerLevelWarning = 4, // For backwards compatibility, the value matches `ASL_LEVEL_WARNING`. + + /// Notice level, corresponding to `OS_LOG_TYPE_DEFAULT`. + GULLoggerLevelNotice = 5, // For backwards compatibility, the value matches `ASL_LEVEL_NOTICE`. + + /// Info level, corresponding to `OS_LOG_TYPE_INFO`. + GULLoggerLevelInfo = 6, // For backwards compatibility, the enum value matches `ASL_LEVEL_INFO`. + + /// Debug level, corresponding to `OS_LOG_TYPE_DEBUG`. + GULLoggerLevelDebug = 7, // For backwards compatibility, the value matches `ASL_LEVEL_DEBUG`. + + /// The minimum (most severe) supported logging level. GULLoggerLevelMin = GULLoggerLevelError, - /** Maximum log level. */ + + /// The maximum (least severe) supported logging level. GULLoggerLevelMax = GULLoggerLevelDebug } NS_SWIFT_NAME(GoogleLoggerLevel); diff --git a/GoogleUtilities/MethodSwizzler/GULSwizzler.m b/GoogleUtilities/MethodSwizzler/GULSwizzler.m index 7f0c82e..3b40b41 100644 --- a/GoogleUtilities/MethodSwizzler/GULSwizzler.m +++ b/GoogleUtilities/MethodSwizzler/GULSwizzler.m @@ -89,11 +89,12 @@ dispatch_queue_t GetGULSwizzlingQueue(void) { IMP testOriginal; [inv getReturnValue:&testOriginal]; if (originalImpOfClass != testOriginal) { - GULLogWarning(kGULLoggerSwizzler, NO, - [NSString stringWithFormat:@"I-SWZ%06ld", - (long)kGULSwizzlerMessageCodeMethodSwizzling000], - @"Swizzling class: %@ SEL:%@ after it has been previously been swizzled.", - NSStringFromClass(resolvedClass), NSStringFromSelector(selector)); + GULOSLogWarning( + kGULLogSubsystem, kGULLoggerSwizzler, NO, + [NSString + stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeMethodSwizzling000], + @"Swizzling class: %@ SEL:%@ after it has been previously been swizzled.", + NSStringFromClass(resolvedClass), NSStringFromSelector(selector)); } } } diff --git a/GoogleUtilities/Network/GULNetwork.m b/GoogleUtilities/Network/GULNetwork.m index 4f66260..23b3bb0 100644 --- a/GoogleUtilities/Network/GULNetwork.m +++ b/GoogleUtilities/Network/GULNetwork.m @@ -279,10 +279,11 @@ static NSString *const kGULNetworkLogTag = @"Google/Utilities/Network"; messageCode:message:context:)] || ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel: messageCode:message:)]) { - GULLogError(kGULLoggerNetwork, NO, - [NSString stringWithFormat:@"I-NET%06ld", (long)kGULNetworkMessageCodeNetwork002], - @"Cannot set the network logger delegate: delegate does not conform to the network " - "logger protocol."); + GULOSLogError( + kGULLogSubsystem, kGULLoggerNetwork, NO, + [NSString stringWithFormat:@"I-NET%06ld", (long)kGULNetworkMessageCodeNetwork002], + @"Cannot set the network logger delegate: delegate does not conform to the network " + "logger protocol."); return; } _loggerDelegate = loggerDelegate; @@ -329,9 +330,9 @@ static NSString *const kGULNetworkLogTag = @"Google/Utilities/Network"; logLevel == kGULNetworkLogLevelWarning || logLevel == kGULNetworkLogLevelInfo) { NSString *formattedMessage = GULStringWithLogMessage(message, logLevel, contexts); NSLog(@"%@", formattedMessage); - GULLogBasic((GULLoggerLevel)logLevel, kGULLoggerNetwork, NO, - [NSString stringWithFormat:@"I-NET%06ld", (long)messageCode], formattedMessage, - NULL); + GULOSLogBasic((GULLoggerLevel)logLevel, kGULLogSubsystem, kGULLoggerNetwork, NO, + [NSString stringWithFormat:@"I-NET%06ld", (long)messageCode], formattedMessage, + NULL); } } diff --git a/GoogleUtilities/Network/GULNetworkURLSession.m b/GoogleUtilities/Network/GULNetworkURLSession.m index 1dcfd43..c29de0c 100644 --- a/GoogleUtilities/Network/GULNetworkURLSession.m +++ b/GoogleUtilities/Network/GULNetworkURLSession.m @@ -93,10 +93,10 @@ if (fetcher != nil) { [fetcher addSystemCompletionHandler:systemCompletionHandler forSession:sessionID]; } else { - GULLogError(kGULLoggerNetwork, NO, - [NSString stringWithFormat:@"I-NET%06ld", (long)kGULNetworkMessageCodeNetwork003], - @"Failed to retrieve background session with ID %@ after app is relaunched.", - sessionID); + GULOSLogError(kGULLogSubsystem, kGULLoggerNetwork, NO, + [NSString stringWithFormat:@"I-NET%06ld", (long)kGULNetworkMessageCodeNetwork003], + @"Failed to retrieve background session with ID %@ after app is relaunched.", + sessionID); } } diff --git a/GoogleUtilities/Reachability/GULReachabilityChecker.m b/GoogleUtilities/Reachability/GULReachabilityChecker.m index 43e3d2f..e3745c6 100644 --- a/GoogleUtilities/Reachability/GULReachabilityChecker.m +++ b/GoogleUtilities/Reachability/GULReachabilityChecker.m @@ -64,10 +64,10 @@ static NSString *const kGULReachabilityDisconnectedStatus = @"Disconnected"; - (void)setReachabilityApi:(const struct GULReachabilityApi *)reachabilityApi { #if !TARGET_OS_WATCH if (reachability_) { - GULLogError(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode000], - @"Cannot change reachability API while reachability is running. " - @"Call stop first."); + GULOSLogError(kGULLogSubsystem, kGULLoggerReachability, NO, + [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode000], + @"Cannot change reachability API while reachability is running. " + @"Call stop first."); return; } reachabilityApi_ = reachabilityApi; @@ -89,9 +89,9 @@ static NSString *const kGULReachabilityDisconnectedStatus = @"Disconnected"; - (void)setReachabilityDelegate:(id)reachabilityDelegate { if (reachabilityDelegate && (![(NSObject *)reachabilityDelegate conformsToProtocol:@protocol(GULReachabilityDelegate)])) { - GULLogError(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-NET%06ld", (long)kGULReachabilityMessageCode005], - @"Reachability delegate doesn't conform to Reachability protocol."); + GULOSLogError(kGULLogSubsystem, kGULLoggerReachability, NO, + [NSString stringWithFormat:@"I-NET%06ld", (long)kGULReachabilityMessageCode005], + @"Reachability delegate doesn't conform to Reachability protocol."); return; } reachabilityDelegate_ = reachabilityDelegate; @@ -102,9 +102,9 @@ static NSString *const kGULReachabilityDisconnectedStatus = @"Disconnected"; self = [super init]; if (!host || !host.length) { - GULLogError(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode001], - @"Invalid host specified"); + GULOSLogError(kGULLogSubsystem, kGULLoggerReachability, NO, + [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode001], + @"Invalid host specified"); return nil; } if (self) { @@ -147,15 +147,15 @@ static NSString *const kGULReachabilityDisconnectedStatus = @"Disconnected"; reachabilityApi_->releaseFn(reachability_); reachability_ = nil; - GULLogError(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode002], - @"Failed to start reachability handle"); + GULOSLogError(kGULLogSubsystem, kGULLoggerReachability, NO, + [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode002], + @"Failed to start reachability handle"); return NO; } } - GULLogDebug(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode003], - @"Monitoring the network status"); + GULOSLogDebug(kGULLogSubsystem, kGULLoggerReachability, NO, + [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode003], + @"Monitoring the network status"); return YES; #endif } @@ -214,10 +214,10 @@ static NSString *const kGULReachabilityDisconnectedStatus = @"Disconnected"; : kGULReachabilityConnectedStatus; } - GULLogDebug(kGULLoggerReachability, NO, - [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode004], - @"Network status has changed. Code:%@, status:%@", @(status), - reachabilityStatusString); + GULOSLogDebug(kGULLogSubsystem, kGULLoggerReachability, NO, + [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode004], + @"Network status has changed. Code:%@, status:%@", @(status), + reachabilityStatusString); reachabilityStatus_ = status; [reachabilityDelegate_ reachability:self statusChanged:reachabilityStatus_]; } diff --git a/GoogleUtilities/Tests/Unit/Logger/GULLoggerTest.m b/GoogleUtilities/Tests/Unit/Logger/GULLoggerTest.m index 0a5bfe4..42c2cc2 100644 --- a/GoogleUtilities/Tests/Unit/Logger/GULLoggerTest.m +++ b/GoogleUtilities/Tests/Unit/Logger/GULLoggerTest.m @@ -16,22 +16,21 @@ // The tests depend upon library methods only built with #ifdef DEBUG #import +#import #import #import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h" #import -extern const char *kGULLoggerASLClientFacilityName; - extern void GULResetLogger(void); -extern aslclient getGULLoggerClient(void); - extern dispatch_queue_t getGULClientQueue(void); extern BOOL getGULLoggerDebugMode(void); +extern os_log_type_t GULLoggerLevelToOSLogType(GULLoggerLevel level); + static NSString *const kMessageCode = @"I-COR000001"; @interface GULLoggerTest : XCTestCase @@ -45,7 +44,7 @@ static NSString *const kMessageCode = @"I-COR000001"; @implementation GULLoggerTest + (void)setUp { - GULLoggerInitializeASL(); + GULLoggerInitialize(); } - (void)setUp { @@ -64,46 +63,34 @@ static NSString *const kMessageCode = @"I-COR000001"; - (void)testMessageCodeFormat { // Valid case. - XCTAssertNoThrow(GULLogError(@"my service", NO, @"I-APP000001", @"Message.")); + XCTAssertNoThrow( + GULOSLogError(@"com.my.service", @"My/Category", NO, @"I-APP000001", @"Message.")); // An extra dash or missing dash should fail. - XCTAssertThrows(GULLogError(@"my service", NO, @"I-APP-000001", @"Message.")); - XCTAssertThrows(GULLogError(@"my service", NO, @"IAPP000001", @"Message.")); + XCTAssertThrows( + GULOSLogError(@"com.my.service", @"My/Category", NO, @"I-APP-000001", @"Message.")); + XCTAssertThrows(GULOSLogError(@"com.my.service", @"My/Category", NO, @"IAPP000001", @"Message.")); // Wrong number of digits should fail. - XCTAssertThrows(GULLogError(@"my service", NO, @"I-APP00001", @"Message.")); - XCTAssertThrows(GULLogError(@"my service", NO, @"I-APP0000001", @"Message.")); + XCTAssertThrows(GULOSLogError(@"com.my.service", @"My/Category", NO, @"I-APP00001", @"Message.")); + XCTAssertThrows( + GULOSLogError(@"com.my.service", @"My/Category", NO, @"I-APP0000001", @"Message.")); // Lowercase should fail. - XCTAssertThrows(GULLogError(@"my service", NO, @"I-app000001", @"Message.")); + XCTAssertThrows( + GULOSLogError(@"com.my.service", @"My/Category", NO, @"I-app000001", @"Message.")); // nil or empty message code should fail. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" - XCTAssertThrows(GULLogError(@"my service", NO, nil, @"Message.")); + XCTAssertThrows(GULOSLogError(@"com.my.service", @"My/Category", NO, nil, @"Message.")); #pragma clang diagnostic pop - XCTAssertThrows(GULLogError(@"my service", NO, @"", @"Message.")); + XCTAssertThrows(GULOSLogError(@"com.my.service", @"My/Category", NO, @"", @"Message.")); // Android message code should fail. - XCTAssertThrows(GULLogError(@"my service", NO, @"A-APP000001", @"Message.")); -} - -- (void)testLoggerInterface { - XCTAssertNoThrow(GULLogError(@"my service", NO, kMessageCode, @"Message.")); - XCTAssertNoThrow(GULLogError(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); - - XCTAssertNoThrow(GULLogWarning(@"my service", NO, kMessageCode, @"Message.")); - XCTAssertNoThrow(GULLogWarning(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); - - XCTAssertNoThrow(GULLogNotice(@"my service", NO, kMessageCode, @"Message.")); - XCTAssertNoThrow(GULLogNotice(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); - - XCTAssertNoThrow(GULLogInfo(@"my service", NO, kMessageCode, @"Message.")); - XCTAssertNoThrow(GULLogInfo(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); - - XCTAssertNoThrow(GULLogDebug(@"my service", NO, kMessageCode, @"Message.")); - XCTAssertNoThrow(GULLogDebug(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); + XCTAssertThrows( + GULOSLogError(@"com.my.service", @"My/Category", NO, @"A-APP000001", @"Message.")); } // The GULLoggerLevel enum must match the ASL_LEVEL_* constants, but we manually redefine @@ -117,6 +104,16 @@ static NSString *const kMessageCode = @"I-COR000001"; XCTAssertEqual(GULLoggerLevelDebug, ASL_LEVEL_DEBUG); } +- (void)testGULLoggerLevelToOSLogType { + XCTAssertEqual(GULLoggerLevelToOSLogType(GULLoggerLevelError), OS_LOG_TYPE_ERROR); + // OSLog doesn't have a WARNING level so it is remapped to DEFAULT (Notice). + XCTAssertEqual(GULLoggerLevelToOSLogType(GULLoggerLevelWarning), + GULLoggerLevelToOSLogType(GULLoggerLevelNotice)); + XCTAssertEqual(GULLoggerLevelToOSLogType(GULLoggerLevelNotice), OS_LOG_TYPE_DEFAULT); + XCTAssertEqual(GULLoggerLevelToOSLogType(GULLoggerLevelInfo), OS_LOG_TYPE_INFO); + XCTAssertEqual(GULLoggerLevelToOSLogType(GULLoggerLevelDebug), OS_LOG_TYPE_DEBUG); +} + - (void)testGULGetLoggerLevel { GULLoggerLevel loggerLevel = GULGetLoggerLevel(); @@ -143,5 +140,64 @@ static NSString *const kMessageCode = @"I-COR000001"; XCTAssertEqual(loggerLevel, GULLoggerLevelNotice); } +#pragma mark - Deprecated Functions + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +- (void)testDeprecatedInitializeASL { + XCTAssertNoThrow(GULLoggerInitializeASL()); +} + +- (void)testDeprecatedEnableSTDERR { + XCTAssertNoThrow(GULLoggerEnableSTDERR()); +} + +- (void)testDeprecatedMessageCodeFormat { + // Valid case. + XCTAssertNoThrow(GULLogError(@"my service", NO, @"I-APP000001", @"Message.")); + + // An extra dash or missing dash should fail. + XCTAssertThrows(GULLogError(@"my service", NO, @"I-APP-000001", @"Message.")); + XCTAssertThrows(GULLogError(@"my service", NO, @"IAPP000001", @"Message.")); + + // Wrong number of digits should fail. + XCTAssertThrows(GULLogError(@"my service", NO, @"I-APP00001", @"Message.")); + XCTAssertThrows(GULLogError(@"my service", NO, @"I-APP0000001", @"Message.")); + + // Lowercase should fail. + XCTAssertThrows(GULLogError(@"my service", NO, @"I-app000001", @"Message.")); + + // nil or empty message code should fail. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + XCTAssertThrows(GULLogError(@"my service", NO, nil, @"Message.")); +#pragma clang diagnostic pop + + XCTAssertThrows(GULLogError(@"my service", NO, @"", @"Message.")); + + // Android message code should fail. + XCTAssertThrows(GULLogError(@"my service", NO, @"A-APP000001", @"Message.")); +} + +- (void)testDeprecatedLoggerInterface { + XCTAssertNoThrow(GULLogError(@"my service", NO, kMessageCode, @"Message.")); + XCTAssertNoThrow(GULLogError(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); + + XCTAssertNoThrow(GULLogWarning(@"my service", NO, kMessageCode, @"Message.")); + XCTAssertNoThrow(GULLogWarning(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); + + XCTAssertNoThrow(GULLogNotice(@"my service", NO, kMessageCode, @"Message.")); + XCTAssertNoThrow(GULLogNotice(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); + + XCTAssertNoThrow(GULLogInfo(@"my service", NO, kMessageCode, @"Message.")); + XCTAssertNoThrow(GULLogInfo(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); + + XCTAssertNoThrow(GULLogDebug(@"my service", NO, kMessageCode, @"Message.")); + XCTAssertNoThrow(GULLogDebug(@"my service", NO, kMessageCode, @"Configure %@.", @"blah")); +} + +#pragma clang diagnostic pop + @end #endif diff --git a/GoogleUtilities/UserDefaults/GULUserDefaults.m b/GoogleUtilities/UserDefaults/GULUserDefaults.m index 3d04983..b4ac798 100644 --- a/GoogleUtilities/UserDefaults/GULUserDefaults.m +++ b/GoogleUtilities/UserDefaults/GULUserDefaults.m @@ -66,9 +66,9 @@ typedef NS_ENUM(NSInteger, GULUDMessageCode) { - (nullable id)objectForKey:(NSString *)defaultName { NSString *key = [defaultName copy]; if (![key isKindOfClass:[NSString class]] || !key.length) { - GULLogWarning(@"", NO, - [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeyGet], - @"Cannot get object for invalid user default key."); + GULOSLogWarning(kGULLogSubsystem, @"", NO, + [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeyGet], + @"Cannot get object for invalid user default key."); return nil; } @@ -78,9 +78,9 @@ typedef NS_ENUM(NSInteger, GULUDMessageCode) { - (void)setObject:(nullable id)value forKey:(NSString *)defaultName { NSString *key = [defaultName copy]; if (![key isKindOfClass:[NSString class]] || !key.length) { - GULLogWarning(kGULLogUserDefaultsService, NO, - [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeySet], - @"Cannot set object for invalid user default key."); + GULOSLogWarning(kGULLogSubsystem, kGULLogUserDefaultsService, NO, + [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeySet], + @"Cannot set object for invalid user default key."); return; } if (!value) { @@ -92,11 +92,12 @@ typedef NS_ENUM(NSInteger, GULUDMessageCode) { [value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSDate class]] || [value isKindOfClass:[NSData class]]; if (!isAcceptableValue) { - GULLogWarning(kGULLogUserDefaultsService, NO, - [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidObjectSet], - @"Cannot set invalid object to user defaults. Must be a string, number, array, " - @"dictionary, date, or data. Value: %@", - value); + GULOSLogWarning( + kGULLogSubsystem, kGULLogUserDefaultsService, NO, + [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidObjectSet], + @"Cannot set invalid object to user defaults. Must be a string, number, array, " + @"dictionary, date, or data. Value: %@", + value); return; }