summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qcore_mac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qcore_mac.cpp')
-rw-r--r--src/corelib/kernel/qcore_mac.cpp95
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