diff options
Diffstat (limited to 'src/corelib/kernel/qcore_mac.cpp')
-rw-r--r-- | src/corelib/kernel/qcore_mac.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/corelib/kernel/qcore_mac.cpp b/src/corelib/kernel/qcore_mac.cpp index bfb3b2ff07..b5df0db232 100644 --- a/src/corelib/kernel/qcore_mac.cpp +++ b/src/corelib/kernel/qcore_mac.cpp @@ -39,6 +39,9 @@ #include <private/qcore_mac_p.h> #include <new> + +#include "qhash.h" +#include "qpair.h" #include "qvarlengtharray.h" QT_BEGIN_NAMESPACE @@ -57,4 +60,96 @@ QCFString::operator CFStringRef() const return value; } +// -------------------------------------------------------------------------- + +#if defined(QT_USE_APPLE_UNIFIED_LOGGING) + +bool AppleUnifiedLogger::messageHandler(QtMsgType msgType, const QMessageLogContext &context, + const QString &message, const QString &optionalSubsystem) +{ + QString subsystem = optionalSubsystem; + if (subsystem.isNull()) { + static QString bundleIdentifier = []() { + if (CFBundleRef bundle = CFBundleGetMainBundle()) { + if (CFStringRef identifier = CFBundleGetIdentifier(bundle)) + return QString::fromCFString(identifier); + } + return QString(); + }(); + subsystem = bundleIdentifier; + } + + const bool isDefault = !context.category || !strcmp(context.category, "default"); + os_log_t log = isDefault ? OS_LOG_DEFAULT : + cachedLog(subsystem, QString::fromLatin1(context.category)); + os_log_type_t logType = logTypeForMessageType(msgType); + + if (!os_log_type_enabled(log, logType)) + return false; + + // Logging best practices says we should not include symbolication + // information or source file line numbers in messages, as the system + // will automatically captures this information. In our case, what + // the system captures is the call to os_log_with_type below, which + // isn't really useful, but we still don't want to include the context's + // info, as that would clutter the logging output. See rdar://35958308. + + // The format must be a string constant, so we can't pass on the + // message. This means we won't be able to take advantage of the + // unified logging's custom format specifiers such as %{BOOL}d. + // We use the 'public' format specifier to prevent the logging + // system from redacting our log message. + os_log_with_type(log, logType, "%{public}s", qPrintable(message)); + + // When running under Xcode or LLDB, one or more of these variables will + // be set, which triggers libsystem_trace.dyld to log messages to stderr + // as well, via_os_log_impl_mirror_to_stderr. Un-setting these variables + // is not an option, as that would silence normal NSLog or os_log calls, + // so instead we skip our own stderr output. See rdar://36919139. + static bool mirroredToStderr = qEnvironmentVariableIsSet("OS_ACTIVITY_DT_MODE") + || qEnvironmentVariableIsSet("ACTIVITY_LOG_STDERR") + || qEnvironmentVariableIsSet("CFLOG_FORCE_STDERR"); + return mirroredToStderr; +} + +os_log_type_t AppleUnifiedLogger::logTypeForMessageType(QtMsgType msgType) +{ + switch (msgType) { + case QtDebugMsg: return OS_LOG_TYPE_DEBUG; + case QtInfoMsg: return OS_LOG_TYPE_INFO; + case QtWarningMsg: return OS_LOG_TYPE_DEFAULT; + case QtCriticalMsg: return OS_LOG_TYPE_ERROR; + case QtFatalMsg: return OS_LOG_TYPE_FAULT; + } + + return OS_LOG_TYPE_DEFAULT; +} + +os_log_t AppleUnifiedLogger::cachedLog(const QString &subsystem, const QString &category) +{ + static QBasicMutex mutex; + QMutexLocker locker(&mutex); + + static QHash<QPair<QString, QString>, os_log_t> logs; + const auto cacheKey = qMakePair(subsystem, category); + os_log_t log = logs.value(cacheKey); + + if (!log) { + log = os_log_create(subsystem.toLatin1().constData(), + category.toLatin1().constData()); + logs.insert(cacheKey, log); + + // Technically we should release the os_log_t resource when done + // with it, but since we don't know when a category is disabled + // we keep all cached os_log_t instances until shutdown, where + // the OS will clean them up for us. + } + + return log; +} + +#endif // QT_USE_APPLE_UNIFIED_LOGGING + +// -------------------------------------------------------------------------- + QT_END_NAMESPACE |