From f501ed682ae68136d966aee2b0d3cc0f1e8b90cd Mon Sep 17 00:00:00 2001 From: Leo Natan Date: Tue, 28 Jan 2020 15:18:22 -0800 Subject: [PATCH] Use Apple unified logging API (os_log) (#27892) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: As discussed in https://github.com/facebook/react-native/issues/27863, the following changes were made to modernize the internal default logging function: - `RCTDefaultLogThreshold` is now set to `RCTLogLevelTrace` in both release and debug builds—the Apple logging system will discard uncollected log entires, while allowing for collection when needed - `RCTLogLevel` is translated to the appropriate log type - The log subsystem is "com.facebook.react.log" - `RCTLogSource` translates to the appropriate category ("native"/"javascript") - Log the provided message using `os_log_with_type` Closes https://github.com/facebook/react-native/issues/27863 ## Changelog [iOS] [Changed] - Use Apple unified logging API (os_log) Pull Request resolved: https://github.com/facebook/react-native/pull/27892 Test Plan: ## From Original PR Ran a test app in the iOS simulator, and verified that logs are correctly displayed in Console.app as well as using the following command: ```sh /usr/bin/xcrun simctl spawn booted log stream --level debug --style compact --predicate 'process=="ReactNativeTesterApp" && subsystem=="com.facebook.react.log"' ``` ## Peter's Test Plan 1. Apply P125583473 2. Verify log output in Xcode P125583504 3. Apply this diff 4. Verify log output in Xcode P125583597 These appear unchanged, after digging into why, I realized that FB doesn't even use the default log function, we inject a custom one [here](https://fburl.com/diffusion/887a1axs). So this PR shouldn't affect us at all. :) Differential Revision: D19605414 Pulled By: PeteTheHeat fbshipit-source-id: 1d70fb702c337a759905d4a65a951a31353ce775 --- React/Base/RCTLog.mm | 49 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/React/Base/RCTLog.mm b/React/Base/RCTLog.mm index 0fbff876cd8397..adfcadc0c359e1 100644 --- a/React/Base/RCTLog.mm +++ b/React/Base/RCTLog.mm @@ -10,6 +10,7 @@ #include #import +#import #import "RCTRedBoxSetEnabled.h" #import "RCTAssert.h" @@ -28,11 +29,8 @@ "fatal", }; -#if RCT_DEBUG +/* os log will discard debug and info messages if they are not needed */ static const RCTLogLevel RCTDefaultLogThreshold = (RCTLogLevel)(RCTLogLevelInfo - 1); -#else -static const RCTLogLevel RCTDefaultLogThreshold = RCTLogLevelError; -#endif static RCTLogFunction RCTCurrentLogFunction; static RCTLogLevel RCTCurrentLogThreshold = RCTDefaultLogThreshold; @@ -46,17 +44,48 @@ void RCTSetLogThreshold(RCTLogLevel threshold) { RCTCurrentLogThreshold = threshold; } +static os_log_type_t RCTLogTypeForLogLevel(RCTLogLevel logLevel) +{ + if (logLevel < RCTLogLevelInfo) { + return OS_LOG_TYPE_DEBUG; + } else if (logLevel <= RCTLogLevelWarning) { + return OS_LOG_TYPE_INFO; + } else { + return OS_LOG_TYPE_ERROR; + } +} + +static os_log_t RCTLogForLogSource(RCTLogSource source) +{ + switch (source) { + case RCTLogSourceNative: { + static os_log_t nativeLog; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + nativeLog = os_log_create("com.facebook.react.log", "native"); + }); + return nativeLog; + } + case RCTLogSourceJavaScript: { + static os_log_t javaScriptLog; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + javaScriptLog = os_log_create("com.facebook.react.log", "javascript"); + }); + return javaScriptLog; + } + } +} + RCTLogFunction RCTDefaultLogFunction = ^( RCTLogLevel level, - __unused RCTLogSource source, - NSString *fileName, - NSNumber *lineNumber, + RCTLogSource source, + __unused NSString *fileName, + __unused NSNumber *lineNumber, NSString *message ) { - NSString *log = RCTFormatLog([NSDate date], level, fileName, lineNumber, message); - fprintf(stderr, "%s\n", log.UTF8String); - fflush(stderr); + os_log_with_type(RCTLogForLogSource(source), RCTLogTypeForLogLevel(level), "%{public}s", message.UTF8String); }; void RCTSetLogFunction(RCTLogFunction logFunction)