From f9deda0d3e0e7453e58ea18c797d1ad38c3f63f4 Mon Sep 17 00:00:00 2001 From: Martin Klos Date: Thu, 14 Jan 2021 13:27:13 +0100 Subject: open62541: Add custom log handler This change adds a custom log handler to the open62541 plugin. Open62541 log output is redirected to Qt logging categories and can be filtered by using the standard mechanisms. Change-Id: Iffbc236326d4ce84cdca56091de2974c4121b217 Reviewed-by: Frank Meerkoetter --- src/opcua/doc/src/qtopcua.qdoc | 34 +++++++++++++ src/plugins/opcua/open62541/qopen62541backend.cpp | 62 ++++++++++++++++++++++- src/plugins/opcua/open62541/qopen62541backend.h | 5 ++ 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/opcua/doc/src/qtopcua.qdoc b/src/opcua/doc/src/qtopcua.qdoc index c344b6c..48161c9 100644 --- a/src/opcua/doc/src/qtopcua.qdoc +++ b/src/opcua/doc/src/qtopcua.qdoc @@ -377,6 +377,40 @@ \li Messages generated by the UACpp plugin \endtable + \section2 Open62541 specific Logging Categories + The open62541 sdk logging categories depend on the log level for open62541, which is configured at compile time. + The default is 300, which enables: info, warning, error and critical. + To obtain less or more verbose output, the open62541 sdk needs to be rebuilt with a different configuration. + + The following table shows the logging categories used by open62541: + + \table + \header + \li Open62541 Logging Category + \li Description + \row + \li qt.opcua.plugins.open62541.sdk.network + \li Messages generated by the open62541 network + \row + \li qt.opcua.plugins.open62541.sdk.securechannel + \li Messages generated by the open62541 channel + \row + \li qt.opcua.plugins.open62541.sdk.session + \li Messages generated by the open62541 session + \row + \li qt.opcua.plugins.open62541.sdk.server + \li Messages generated by open62541 server components + \row + \li qt.opcua.plugins.open62541.sdk.client + \li Messages generated by the open62541 client + \row + \li qt.opcua.plugins.open62541.sdk.userland + \li Messages generated by the open62541 userland + \row + \li qt.opcua.plugins.open62541.sdk.securitypolicy + \li Messages generated by the open62541 security policies + \endtable + \section1 Licenses The Qt OPC UA module is available under commercial licenses from \l{The Qt Company}. diff --git a/src/plugins/opcua/open62541/qopen62541backend.cpp b/src/plugins/opcua/open62541/qopen62541backend.cpp index 91f790d..c90a8a9 100644 --- a/src/plugins/opcua/open62541/qopen62541backend.cpp +++ b/src/plugins/opcua/open62541/qopen62541backend.cpp @@ -396,10 +396,63 @@ void Open62541AsyncBackend::resolveBrowsePath(quint64 handle, UA_NodeId startNod emit resolveBrowsePathFinished(handle, ret, path, static_cast(res.results[0].statusCode)); } +void Open62541AsyncBackend::open62541LogHandler (void *logContext, UA_LogLevel level, UA_LogCategory category, + const char *msg, va_list args) { + + Q_UNUSED(logContext) + + Q_STATIC_ASSERT(UA_LOGCATEGORY_NETWORK == 0); + Q_STATIC_ASSERT(UA_LOGCATEGORY_SECURECHANNEL == 1); + Q_STATIC_ASSERT(UA_LOGCATEGORY_SESSION == 2); + Q_STATIC_ASSERT(UA_LOGCATEGORY_SERVER == 3); + Q_STATIC_ASSERT(UA_LOGCATEGORY_CLIENT == 4); + Q_STATIC_ASSERT(UA_LOGCATEGORY_USERLAND == 5); + Q_STATIC_ASSERT(UA_LOGCATEGORY_SECURITYPOLICY == 6); + + Q_ASSERT(category <= UA_LOGCATEGORY_SECURITYPOLICY); + + const auto logMessage = QString::vasprintf(msg, args); + + static const QLoggingCategory loggingCategories[] { + QLoggingCategory("qt.opcua.plugins.open62541.sdk.network"), + QLoggingCategory("qt.opcua.plugins.open62541.sdk.securechannel"), + QLoggingCategory("qt.opcua.plugins.open62541.sdk.session"), + QLoggingCategory("qt.opcua.plugins.open62541.sdk.server"), + QLoggingCategory("qt.opcua.plugins.open62541.sdk.client"), + QLoggingCategory("qt.opcua.plugins.open62541.sdk.userland"), + QLoggingCategory("qt.opcua.plugins.open62541.sdk.securitypolicy") + }; + + switch (level) { + case UA_LOGLEVEL_TRACE: + case UA_LOGLEVEL_DEBUG: + qCDebug(loggingCategories[category]) << logMessage; + break; + case UA_LOGLEVEL_INFO: + qCInfo(loggingCategories[category]) << logMessage; + break; + case UA_LOGLEVEL_WARNING: + qCWarning(loggingCategories[category]) << logMessage; + break; + case UA_LOGLEVEL_ERROR: + case UA_LOGLEVEL_FATAL: + qCCritical(loggingCategories[category]) << logMessage; + break; + default: + qCCritical(loggingCategories[category]) << "Unknown UA_LOGLEVEL" << logMessage; + break; + } +} + void Open62541AsyncBackend::findServers(const QUrl &url, const QStringList &localeIds, const QStringList &serverUris) { UA_Client *tmpClient = UA_Client_new(); + auto conf = UA_Client_getConfig(tmpClient); + + conf->logger = m_open62541Logger; + UA_ClientConfig_setDefault(UA_Client_getConfig(tmpClient)); + UaDeleter clientDeleter(tmpClient, UA_Client_delete); UA_String *uaServerUris = nullptr; @@ -817,6 +870,8 @@ void Open62541AsyncBackend::connectToEndpoint(const QOpcUaEndpointDescription &e m_uaclient = UA_Client_new(); auto conf = UA_Client_getConfig(m_uaclient); + conf->logger = m_open62541Logger; + const auto identity = m_clientImpl->m_client->applicationIdentity(); const auto authInfo = m_clientImpl->m_client->authenticationInformation(); #ifdef UA_ENABLE_ENCRYPTION @@ -986,7 +1041,12 @@ void Open62541AsyncBackend::disconnectFromEndpoint() void Open62541AsyncBackend::requestEndpoints(const QUrl &url) { UA_Client *tmpClient = UA_Client_new(); - UA_ClientConfig_setDefault(UA_Client_getConfig(tmpClient)); + auto conf = UA_Client_getConfig(tmpClient); + + conf->logger = m_open62541Logger; + + UA_ClientConfig_setDefault(conf); + size_t numEndpoints = 0; UA_EndpointDescription *endpoints = nullptr; UA_StatusCode res = UA_Client_getEndpoints(tmpClient, url.toString(QUrl::RemoveUserInfo).toUtf8().constData(), &numEndpoints, &endpoints); diff --git a/src/plugins/opcua/open62541/qopen62541backend.h b/src/plugins/opcua/open62541/qopen62541backend.h index 92a2e20..89a9e0f 100644 --- a/src/plugins/opcua/open62541/qopen62541backend.h +++ b/src/plugins/opcua/open62541/qopen62541backend.h @@ -101,6 +101,9 @@ private: static void inactivityCallback(UA_Client *client); + static void open62541LogHandler(void *logContext, UA_LogLevel level, UA_LogCategory category, + const char *msg, va_list args); + QOpen62541Subscription *getSubscriptionForItem(quint64 handle, QOpcUa::NodeAttribute attr); QOpcUaApplicationDescription convertApplicationDescription(UA_ApplicationDescription &desc); @@ -118,6 +121,8 @@ private: QHash> m_attributeMapping; // Handle -> Attribute -> Subscription double m_minPublishingInterval; + + const UA_Logger m_open62541Logger {open62541LogHandler, nullptr, nullptr}; }; QT_END_NAMESPACE -- cgit v1.2.3