diff --git a/fml/logging.cc b/fml/logging.cc index 3cf7c86964392..7a9f3b6a24e99 100644 --- a/fml/logging.cc +++ b/fml/logging.cc @@ -11,7 +11,8 @@ #if defined(OS_ANDROID) #include -#elif defined(OS_IOS) +#elif defined(OS_MACOSX) +#include #include #endif @@ -81,8 +82,37 @@ LogMessage::~LogMessage() { break; } __android_log_write(priority, "flutter", stream_.str().c_str()); -#elif defined(OS_IOS) - syslog(LOG_ALERT, "%s", stream_.str().c_str()); +#elif defined(OS_MACOSX) + const char* chars = stream_.str().c_str(); + // Unified logging (os_log) became available in iOS 9.0 and syslog stopped + // working in iOS 13.0. idevicesyslog made device syslog available on the + // connected host, but there is no known API to view device unified logging on + // the host. Flutter tool will continue to observe syslog on devices older + // than iOS 13.0 since it provides more logging context, particularly for + // application crashes. + if (__builtin_available(iOS 13.0, macOS 10.11, *)) { + os_log_t engine_log = os_log_create("io.flutter", "engine"); + switch (severity_) { + // TODO(flutter/flutter#45931): LogSeverity LOG_INFO and LOG_WARNING + // collide with syslog log level macros. + case 0 /* LOG_INFO */: + os_log_debug(engine_log, "%s", chars); + break; + case 1 /* LOG_WARNING */: + case LOG_ERROR: + os_log_error(engine_log, "%s", chars); + break; + case LOG_FATAL: + os_log_fault(engine_log, "%s", chars); + break; + default: + os_log(engine_log, "%s", chars); + break; + } + } else { + syslog(LOG_ALERT, "%s", chars); + } + #else std::cerr << stream_.str(); std::cerr.flush(); diff --git a/lib/ui/dart_runtime_hooks.cc b/lib/ui/dart_runtime_hooks.cc index 662d2d631108c..7e90e7b5f9305 100644 --- a/lib/ui/dart_runtime_hooks.cc +++ b/lib/ui/dart_runtime_hooks.cc @@ -30,7 +30,8 @@ #if defined(OS_ANDROID) #include -#elif defined(OS_IOS) +#elif defined(OS_MACOSX) +#include extern "C" { // Cannot import the syslog.h header directly because of macro collision. extern void syslog(int, const char*, ...); @@ -199,19 +200,29 @@ void Logger_PrintString(Dart_NativeArguments args) { // Write to the logcat on Android. __android_log_print(ANDROID_LOG_INFO, logger_prefix.c_str(), "%.*s", (int)length, chars); -#elif defined(OS_IOS) - // Write to syslog on iOS. - // +#elif defined(OS_MACOSX) // TODO(cbracken): replace with dedicated communication channel and bypass // iOS logging APIs altogether. - syslog(1 /* LOG_ALERT */, "%.*s", (int)length, chars); + // + // Unified logging (os_log) became available in iOS 9.0 and syslog stopped + // working in iOS 13.0. idevicesyslog made device syslog available on the + // connected host, but there is no known API to view device unified logging + // on the host. Flutter tool will continue to observe syslog on devices + // older than iOS 13.0 since it provides more logging context, particularly + // for application crashes. + if (__builtin_available(iOS 13.0, macOS 10.11, *)) { + os_log_t dart_log = os_log_create("io.flutter", "dart"); + os_log(dart_log, "%.*s", static_cast(length), chars); + } else { + syslog(1 /* LOG_ALERT */, "%.*s", @(length).intValue, chars); + } #else std::cout << log_string << std::endl; #endif } if (dart::bin::ShouldCaptureStdout()) { - // For now we report print output on the Stdout stream. + // Report print output on the Stdout stream. uint8_t newline[] = {'\n'}; Dart_ServiceSendDataEvent("Stdout", "WriteEvent", reinterpret_cast(chars), length);