mirror of
https://github.com/espressif/openthread.git
synced 2026-07-31 08:07:47 +00:00
[logging] update OT logging (use functions) (#5674)
This commit updates and enhances OT logging by implementing some of more common operations as functions (instead of macros) and preparing the entire log line (appending log level and/or log region to the log string if the corresponding OT config options are enabled) before passing it to platform layer. The OT logging previously used macro definitions all the way to platform layer call to `otPlatLog` (which itself can be defined as a macro through an OT config). This model was adopted to address a restriction/requirement on certain platforms (e.g., platforms that required to enable/use log tokenization). However, using macros adds an overhead on all other platforms that do not have such a requirement. This commit adds `OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY` which when enabled (set to 1) keeps the implementation as before (i.e., macros are used in the logging module). By default this is disabled which enables the new implementation added from this commit. This commit also adds `OPENTHREAD_CONFIG_PLAT_LOG_MACRO_NAME` which replaces the previous `OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION_NAME`. This config is used to override the `otPlatLog` and define it as a macro. A build-time check is added in the `config-check.h` to help any project that is integrating OT and may be using the macro name override behavior to detect the change from this commit and update its config definitions. Finally, this commit updates `check-simulation-build-autotools` script to add a build with `OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY` enabled.
This commit is contained in:
@@ -99,6 +99,9 @@ build_all_features()
|
||||
reset_source
|
||||
make -f examples/Makefile-simulation FULL_LOGS=1
|
||||
|
||||
export CPPFLAGS="${options[*]} -DOPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY=1"
|
||||
make -f examples/Makefile-simulation FULL_LOGS=1
|
||||
|
||||
export CPPFLAGS="${options[*]} ${options_1_2[*]} -DOPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_NONE"
|
||||
reset_source
|
||||
make -f examples/Makefile-simulation THREAD_VERSION=1.2
|
||||
|
||||
+189
-46
@@ -46,14 +46,186 @@
|
||||
#error OPENTHREAD_CONFIG_ENABLE_DEBUG_UART_LOG requires OPENTHREAD_CONFIG_ENABLE_DEBUG_UART
|
||||
#endif
|
||||
|
||||
#define otLogDump(aFormat, ...) _otDynamicLog(aLogLevel, aLogRegion, aFormat OPENTHREAD_CONFIG_LOG_SUFFIX, __VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY
|
||||
|
||||
static void Log(otLogLevel aLogLevel,
|
||||
otLogRegion aLogRegion,
|
||||
const char *aRegionPrefix,
|
||||
const char *aFormat,
|
||||
va_list aArgs)
|
||||
{
|
||||
ot::String<OPENTHREAD_CONFIG_LOG_MAX_SIZE> logString;
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
|
||||
VerifyOrExit(otLoggingGetLevel() >= aLogLevel);
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL
|
||||
{
|
||||
const char *levelStr = "";
|
||||
|
||||
switch (aLogLevel)
|
||||
{
|
||||
case OT_LOG_LEVEL_CRIT:
|
||||
levelStr = _OT_LEVEL_CRIT_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_WARN:
|
||||
levelStr = _OT_LEVEL_WARN_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_NOTE:
|
||||
levelStr = _OT_LEVEL_NOTE_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_INFO:
|
||||
levelStr = _OT_LEVEL_INFO_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_DEBG:
|
||||
levelStr = _OT_LEVEL_DEBG_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_NONE:
|
||||
default:
|
||||
levelStr = _OT_LEVEL_NONE_PREFIX;
|
||||
break;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_PREPEND_REGION
|
||||
IgnoreError(logString.Append("[%s]", levelStr));
|
||||
#endif
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_LOG_PREPEND_LEVEL
|
||||
|
||||
IgnoreError(logString.Append("%s", aRegionPrefix));
|
||||
VerifyOrExit(logString.AppendVarArgs(aFormat, aArgs) != OT_ERROR_INVALID_ARGS);
|
||||
otPlatLog(aLogLevel, aLogRegion, "%s" OPENTHREAD_CONFIG_LOG_SUFFIX, logString.AsCString());
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_CRIT
|
||||
void otLogCrit(otLogRegion aRegion, const char *aRegionPrefix, const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, aFormat);
|
||||
Log(OT_LOG_LEVEL_CRIT, aRegion, aRegionPrefix, aFormat, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_WARN
|
||||
void otLogWarn(otLogRegion aRegion, const char *aRegionPrefix, const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, aFormat);
|
||||
Log(OT_LOG_LEVEL_WARN, aRegion, aRegionPrefix, aFormat, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE
|
||||
void otLogNote(otLogRegion aRegion, const char *aRegionPrefix, const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, aFormat);
|
||||
Log(OT_LOG_LEVEL_NOTE, aRegion, aRegionPrefix, aFormat, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO
|
||||
void otLogInfo(otLogRegion aRegion, const char *aRegionPrefix, const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, aFormat);
|
||||
Log(OT_LOG_LEVEL_INFO, aRegion, aRegionPrefix, aFormat, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_DEBG
|
||||
void otLogDebg(otLogRegion aRegion, const char *aRegionPrefix, const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, aFormat);
|
||||
Log(OT_LOG_LEVEL_DEBG, aRegion, aRegionPrefix, aFormat, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_MAC
|
||||
void otLogMac(otLogLevel aLogLevel, const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
VerifyOrExit(otLoggingGetLevel() >= aLogLevel);
|
||||
|
||||
va_start(args, aFormat);
|
||||
Log(aLogLevel, OT_LOG_REGION_MAC, _OT_REGION_MAC_PREFIX, aFormat, args);
|
||||
va_end(args);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
|
||||
void otLogCertMeshCoP(const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, aFormat);
|
||||
Log(OT_LOG_LEVEL_NONE, OT_LOG_REGION_MESH_COP, _OT_REGION_MESH_COP_PREFIX, aFormat, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_OTNS_ENABLE
|
||||
void otLogOtns(const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, aFormat);
|
||||
Log(OT_LOG_LEVEL_NONE, OT_LOG_REGION_CORE, _OT_REGION_CORE_PREFIX, aFormat, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #if !OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_PKT_DUMP
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY
|
||||
#define otLogDump(aLogLevel, aLogRegion, aFormat, ...) \
|
||||
_otDynamicLog(aLogLevel, aLogRegion, aFormat OPENTHREAD_CONFIG_LOG_SUFFIX, __VA_ARGS__)
|
||||
#else
|
||||
static void otLogDump(otLogLevel aLogLevel, otLogRegion aRegion, const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
VerifyOrExit(otLoggingGetLevel() >= aLogLevel);
|
||||
|
||||
va_start(args, aFormat);
|
||||
Log(aLogLevel, aRegion, "", aFormat, args);
|
||||
va_end(args);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
enum : uint8_t
|
||||
{
|
||||
kStringLineLength = 80,
|
||||
@@ -100,7 +272,7 @@ static void DumpLine(otLogLevel aLogLevel, otLogRegion aLogRegion, const uint8_t
|
||||
IgnoreError(string.Append("%c", c));
|
||||
}
|
||||
|
||||
otLogDump("%s", string.AsCString());
|
||||
otLogDump(aLogLevel, aLogRegion, "%s", string.AsCString());
|
||||
}
|
||||
|
||||
void otDump(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aId, const void *aBuf, const size_t aLength)
|
||||
@@ -125,7 +297,7 @@ void otDump(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aId, const
|
||||
IgnoreError(string.Append("="));
|
||||
}
|
||||
|
||||
otLogDump("%s", string.AsCString());
|
||||
otLogDump(aLogLevel, aLogRegion, "%s", string.AsCString());
|
||||
|
||||
for (size_t i = 0; i < aLength; i += kDumpBytesPerLine)
|
||||
{
|
||||
@@ -140,7 +312,7 @@ void otDump(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aId, const
|
||||
IgnoreError(string.Append("-"));
|
||||
}
|
||||
|
||||
otLogDump("%s", string.AsCString());
|
||||
otLogDump(aLogLevel, aLogRegion, "%s", string.AsCString());
|
||||
}
|
||||
#else // OPENTHREAD_CONFIG_LOG_PKT_DUMP
|
||||
void otDump(otLogLevel, otLogRegion, const char *, const void *, const size_t)
|
||||
@@ -190,55 +362,26 @@ static const char *const sThreadErrorStrings[OT_NUM_ERRORS] = {
|
||||
|
||||
const char *otThreadErrorToString(otError aError)
|
||||
{
|
||||
const char *retval;
|
||||
|
||||
if (aError < OT_ARRAY_LENGTH(sThreadErrorStrings))
|
||||
{
|
||||
retval = sThreadErrorStrings[aError];
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = "UnknownErrorType";
|
||||
}
|
||||
return retval;
|
||||
return aError < OT_ARRAY_LENGTH(sThreadErrorStrings) ? sThreadErrorStrings[aError] : "UnknownErrorType";
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY
|
||||
|
||||
const char *otLogLevelToPrefixString(otLogLevel aLogLevel)
|
||||
{
|
||||
const char *retval = "";
|
||||
static const char *const kLevelStrings[] = {
|
||||
_OT_LEVEL_NONE_PREFIX, _OT_LEVEL_CRIT_PREFIX, _OT_LEVEL_WARN_PREFIX,
|
||||
_OT_LEVEL_NOTE_PREFIX, _OT_LEVEL_INFO_PREFIX, _OT_LEVEL_DEBG_PREFIX,
|
||||
};
|
||||
|
||||
switch (aLogLevel)
|
||||
{
|
||||
case OT_LOG_LEVEL_NONE:
|
||||
retval = _OT_LEVEL_NONE_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_CRIT:
|
||||
retval = _OT_LEVEL_CRIT_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_WARN:
|
||||
retval = _OT_LEVEL_WARN_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_NOTE:
|
||||
retval = _OT_LEVEL_NOTE_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_INFO:
|
||||
retval = _OT_LEVEL_INFO_PREFIX;
|
||||
break;
|
||||
|
||||
case OT_LOG_LEVEL_DEBG:
|
||||
retval = _OT_LEVEL_DEBG_PREFIX;
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
return ((aLogLevel >= 0) && (aLogLevel < static_cast<int>(OT_ARRAY_LENGTH(kLevelStrings))))
|
||||
? kLevelStrings[aLogLevel]
|
||||
: "";
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NONE
|
||||
/* this provides a stub, incase something uses the function */
|
||||
/* this provides a stub, in case something uses the function */
|
||||
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aLogLevel);
|
||||
|
||||
+322
-294
File diff suppressed because it is too large
Load Diff
@@ -212,6 +212,19 @@ public:
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method appends `printf()` style formatted data to the `String` object.
|
||||
*
|
||||
* @param[in] aFormat A pointer to the format string.
|
||||
* @param[in] aArgs Arguments for the format specification (as `va_list`).
|
||||
*
|
||||
* @retval OT_ERROR_NONE Updated the string successfully.
|
||||
* @retval OT_ERROR_NO_BUFS String could not fit in the storage.
|
||||
* @retval OT_ERROR_INVALID_ARGS Arguments do not match the format string.
|
||||
*
|
||||
*/
|
||||
otError AppendVarArgs(const char *aFormat, va_list aArgs) { return Write(mBuffer, kSize, mLength, aFormat, aArgs); }
|
||||
|
||||
/**
|
||||
* This method appends an array of bytes in hex representation (using "%02x" style) to the `String` object.
|
||||
*
|
||||
|
||||
@@ -341,13 +341,38 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION
|
||||
* @def OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY
|
||||
*
|
||||
* Defines the name of function/macro used for logging inside OpenThread, by default it is set to `otPlatLog()`.
|
||||
* Set to 1 to require all the logging related definition to user macro only (up to the call to the platform log API).
|
||||
* Otherwise the logging implementation uses functions (which is preferred and recommended model).
|
||||
*
|
||||
* This is intended for special platform requirements where the logging needs to be defined a macro (e.g., for log
|
||||
* tokenization or similar features).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION
|
||||
#define OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION otPlatLog
|
||||
#ifndef OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY
|
||||
#define OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PLAT_LOG_MACRO_NAME
|
||||
*
|
||||
* Defines the name of macro used for logging inside OpenThread, by default it is set to `otPlatLog()`. This is used
|
||||
* and applicable only when `OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY` is set to 1.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_PLAT_LOG_MACRO_NAME
|
||||
#define OPENTHREAD_CONFIG_PLAT_LOG_MACRO_NAME otPlatLog
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_LOG_MAX_SIZE
|
||||
*
|
||||
* The maximum log string size (number of chars).
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_LOG_MAX_SIZE
|
||||
#define OPENTHREAD_CONFIG_LOG_MAX_SIZE 150
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_LOGGING_H_
|
||||
|
||||
@@ -541,4 +541,9 @@
|
||||
#error "OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL is removed, use OPENTHREAD_CONFIG_LOG_OUTPUT_APP instead"
|
||||
#endif
|
||||
|
||||
#ifdef OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION
|
||||
#error "OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION was replaced by OPENTHREAD_CONFIG_PLAT_LOG_MACRO_NAME " \
|
||||
"(and OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY)"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CORE_CONFIG_CHECK_H_
|
||||
|
||||
Reference in New Issue
Block a user