Migrate from ASL to OSLog (#192)

This commit is contained in:
Andrew Heard authored and GitHub committed 2024-07-10 21:10:56 -04:00
1 parent 41bf68bcda
commit 3cd2e3dc57
11 files changed
+495 -283

No files matched your search

@@ -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<GULApplicationDelegate>)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<GULApplicationDelegate> 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;
}
}
@@ -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)
+99 -54
View File
@@ -14,18 +14,13 @@
#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
#include <asl.h>
#import <OSLog/OSLog.h>
#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<NSString *, NSMutableDictionary<GULLoggerService, os_log_t> *>
*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<GULLoggerService, os_log_t> *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] <Error> [{service}][I-XYZ000001] Configure blah failed.
* Calling GULLogDebug({service}, @"I-XYZ000001", @"Configure succeed.") shows:
* yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Debug> [{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
@@ -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
@@ -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);
+6 -5
View File
@@ -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));
}
}
}
+8 -7
View File
@@ -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);
}
}
@@ -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);
}
}
@@ -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<GULReachabilityDelegate>)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_];
}
@@ -16,22 +16,21 @@
// The tests depend upon library methods only built with #ifdef DEBUG
#import <OCMock/OCMock.h>
#import <OSLog/OSLog.h>
#import <XCTest/XCTest.h>
#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
#import <asl.h>
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
+12 -11
View File
@@ -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(@"<GoogleUtilities>", NO,
[NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeyGet],
@"Cannot get object for invalid user default key.");
GULOSLogWarning(kGULLogSubsystem, @"<GoogleUtilities>", 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;
}