[logging] introduce instance-aware platform logging API (#12737)

This commit adds `otPlatLogOutput()`, a new platform logging API that
provides the `otInstance` pointer along with a pre-formatted log
string. This addresses the limitation of the existing `otPlatLog()` in
multi-instance builds, where the function cannot reliably determine
which OpenThread instance generated the log.

`OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE`, is introduced to
enable this behavior. When enabled, `Logger::Log()` resolves the
active instance (via a tracked global pointer `gActiveInstance`)
and passes it to `otPlatLogOutput()`.

To support tracking the active instance context,
`UpdateActiveInstance()` is added and called during standard
instance retrieval paths, such as `Locator::GetInstance()` and
`Message::GetInstance()`. The TCP endpoints and listeners are also
updated to track the active instance when their `GetInstance()` methods
are invoked.

The Nexus testing platform is updated to enable this configuration
and implement `otPlatLogOutput()` to print the instance ID alongside
the log line, simplifying log tracing in multi-node simulations.
This commit is contained in:
Abtin Keshavarzian
2026-03-24 15:30:08 -05:00
committed by GitHub
parent 52551d8ff0
commit b35cb137d5
11 changed files with 110 additions and 29 deletions
+1 -1
View File
@@ -83,7 +83,6 @@
#define OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE 1
#define OPENTHREAD_CONFIG_JOINER_ENABLE 1
#define OPENTHREAD_CONFIG_LOG_LEVEL OT_LOG_LEVEL_INFO
#define OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE 1
#define OPENTHREAD_CONFIG_LOG_LEVEL_INIT OT_LOG_LEVEL_CRIT
#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
@@ -91,6 +90,7 @@
#define OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL 1
#define OPENTHREAD_CONFIG_LOG_PREPEND_UPTIME 0
#define OPENTHREAD_CONFIG_LOG_SUFFIX ""
#define OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE 1
#define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1
#define OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1
#define OPENTHREAD_CONFIG_MAC_FILTER_ENABLE 1
+20 -23
View File
@@ -39,8 +39,7 @@
namespace ot {
namespace Nexus {
static void LogVarArgs(Node *aActiveNode, const char *aFormat, va_list aArgs)
OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(2, 0);
static void LogTime(void);
extern "C" {
@@ -57,16 +56,18 @@ void otTaskletsSignalPending(otInstance *aInstance)
//---------------------------------------------------------------------------------------------------------------------
// otPlatLog
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
void otPlatLogOutput(otInstance *aInstance, otLogLevel aLogLevel, const char *aLogLine)
{
OT_UNUSED_VARIABLE(aLogLevel);
OT_UNUSED_VARIABLE(aLogRegion);
va_list args;
VerifyOrExit(aInstance != nullptr);
va_start(args, aFormat);
LogVarArgs(Core::Get().GetActiveNode(), aFormat, args);
va_end(args);
LogTime();
printf("%03u %s\n", AsNode(aInstance).GetId(), aLogLine);
fflush(stdout);
exit:
return;
}
//---------------------------------------------------------------------------------------------------------------------
@@ -136,29 +137,25 @@ void otPlatWakeHost(void) {}
//---------------------------------------------------------------------------------------------------------------------
// Log related function
static void LogTime(void)
{
uint32_t now = Core::Get().GetNow().GetValue();
printf("%02u:%02u:%02u.%03u ", now / 3600000, (now / 60000) % 60, (now / 1000) % 60, now % 1000);
}
void Log(const char *aFormat, ...)
{
va_list args;
va_start(args, aFormat);
LogVarArgs(nullptr, aFormat, args);
va_end(args);
}
static void LogVarArgs(Node *aActiveNode, const char *aFormat, va_list aArgs)
{
uint32_t now = Core::Get().GetNow().GetValue();
printf("%02u:%02u:%02u.%03u ", now / 3600000, (now / 60000) % 60, (now / 1000) % 60, now % 1000);
if (aActiveNode != nullptr)
{
printf("%03u ", aActiveNode->GetInstance().GetId());
}
vprintf(aFormat, aArgs);
LogTime();
vprintf(aFormat, args);
printf("\n");
fflush(stdout);
va_end(args);
}
} // namespace Nexus