LOG_LEVEL=WARNING : The logs including WARNING, ERROR, FATAL level is printed.
LOG_LEVEL=ERROR : The logs including ERROR, FATAL level is printed.
LOG_LEVEL=FATAL : FATAL level is printed.
+ Log entries that have the OC_LOG_PRIVATE_DATA bit set, in addition to DEBUG, INFO, WARNING,
+ ERROR, or FATAL, contain confidential information and therefore are not printed by default.
+ The application has to call OCSetLogLevel() to enable printing of private information in the
+ log.
Note:
1) for convenience, a script (auto_build.sh) is provided to run possible build
if ('BROKER' in with_mq):
env.AppendUnique(CPPDEFINES=['MQ_BROKER', 'WITH_MQ'])
+env.AppendUnique(CPPDEFINES = {'OC_LOG_LEVEL' : env.get('LOG_LEVEL')})
+
if env.get('LOGGING'):
env.AppendUnique(CPPDEFINES=['TB_LOG'])
Import('env')
import os
-log_level = env.get('LOG_LEVEL')
build_dir = env.get('BUILD_DIR')
else:
logger_src = ['./src/logger.c', './src/trace.c']
-if log_level == 'INFO':
- env.AppendUnique(CPPDEFINES = ['SET_LOG_INFO'])
- print "SET_LOG_INFO"
-if log_level == 'ERROR':
- env.AppendUnique(CPPDEFINES = ['SET_LOG_ERROR'])
- print "SET_LOG_ERROR"
-if log_level == 'WARNING':
- env.AppendUnique(CPPDEFINES = ['SET_LOG_WARNING'])
- print "SET_LOG_WARNING"
-if log_level == 'FATAL':
- env.AppendUnique(CPPDEFINES = ['SET_LOG_FATAL'])
- print "SET_LOG_FATAL"
-
loggerlib = local_env.StaticLibrary('logger', logger_src)
local_env.InstallTarget(loggerlib, 'logger')
-
// Max buffer size used in variable argument log function
#define MAX_LOG_V_BUFFER_SIZE (256)
+// Setting this flag for a log level means that the corresponding log message
+// contains private data. This kind of message is logged only when a call to
+// OCSetLogLevel() enabled private data logging.
+#define OC_LOG_PRIVATE_DATA (1 << 31)
+
// Log levels
#ifdef __TIZEN__
typedef enum {
FATAL = DLOG_ERROR,
DEBUG_LITE = DLOG_INFO,
INFO_LITE = DLOG_INFO,
- INFO_PRIVATE = 255,
} LogLevel;
#else
FATAL,
DEBUG_LITE, // The DEBUG log for Lite device
INFO_LITE, // The INFO log for Lite device
- INFO_PRIVATE // The log contained private data
} LogLevel;
#endif // __TIZEN__
-#ifdef SET_LOG_INFO
-#define IF_OC_PRINT_LOG_LEVEL(level) if (INFO <= (level))
-#elif defined(SET_LOG_ERROR)
-#define IF_OC_PRINT_LOG_LEVEL(level) if (ERROR <= (level) && INFO_PRIVATE != (level))
-#elif defined(SET_LOG_WARNING)
-#define IF_OC_PRINT_LOG_LEVEL(level) if (WARNING <= (level) && INFO_PRIVATE != (level))
-#elif defined(SET_LOG_FATAL)
-#define IF_OC_PRINT_LOG_LEVEL(level) if (FATAL <= (level) && INFO_PRIVATE != (level))
+#define DEBUG_PRIVATE ((OC_LOG_PRIVATE_DATA) | (DEBUG))
+#define INFO_PRIVATE ((OC_LOG_PRIVATE_DATA) | (INFO))
+#define WARNING_PRIVATE ((OC_LOG_PRIVATE_DATA) | (WARNING))
+#define ERROR_PRIVATE ((OC_LOG_PRIVATE_DATA) | (ERROR))
+#define FATAL_PRIVATE ((OC_LOG_PRIVATE_DATA) | (FATAL))
+
+#ifndef OC_LOG_LEVEL
+#define OC_MINIMUM_LOG_LEVEL (DEBUG)
#else
-#define IF_OC_PRINT_LOG_LEVEL(level) if (INFO_PRIVATE != (level))
+#define OC_MINIMUM_LOG_LEVEL (OC_LOG_LEVEL)
#endif
+// Perform signed comparison here, to avoid compiler warnings caused by
+// unsigned comparison with DEBUG (i.e., with value 0 on some platforms).
+#define IF_OC_PRINT_LOG_LEVEL(level) \
+ if (((int)OC_MINIMUM_LOG_LEVEL) <= ((int)(level & (~OC_LOG_PRIVATE_DATA))))
+
/**
* Set log level and privacy log to print.
*
* @param[in] buffer pointer to buffer of bytes
* @param[in] bufferSize max number of byte in buffer
*/
-void OCLogBuffer(LogLevel level, const char* tag, const uint8_t* buffer, size_t bufferSize);
+void OCLogBuffer(int level, const char* tag, const uint8_t* buffer, size_t bufferSize);
-#define OCLog(level,tag,mes) LOG_(LOG_ID_MAIN, (level), (tag), mes)
-#define OCLogv(level,tag,fmt,args...) LOG_(LOG_ID_MAIN, (level),tag,fmt,##args)
+#define OCLog(level,tag,mes) LOG_(LOG_ID_MAIN, ((level) & (~OC_LOG_PRIVATE_DATA)), (tag), mes)
+#define OCLogv(level,tag,fmt,args...) LOG_(LOG_ID_MAIN, ((level) & (~OC_LOG_PRIVATE_DATA)),tag,fmt,##args)
#elif !defined(ARDUINO)
/**
* Configure logger to use a context that defines a custom logger function
* @param tag - Module name
* @param format - variadic log string
*/
- void OCLogv(LogLevel level, const char * tag, const char * format, ...)
+ void OCLogv(int level, const char * tag, const char * format, ...)
#if defined(__GNUC__)
__attribute__ ((format(printf, 3, 4)))
#endif
* @param tag - Module name
* @param logStr - log string
*/
- void OCLog(LogLevel level, const char * tag, const char * logStr);
+ void OCLog(int level, const char * tag, const char * logStr);
/**
* Output the contents of the specified buffer (in hex) with the specified priority level.
* @param buffer - pointer to buffer of bytes
* @param bufferSize - max number of byte in buffer
*/
- void OCLogBuffer(LogLevel level, const char* tag, const uint8_t* buffer, size_t bufferSize);
+ void OCLogBuffer(int level, const char* tag, const uint8_t* buffer, size_t bufferSize);
#else // For arduino platforms
/**
* Initialize the serial logger for Arduino
* @param lineNum- line Number
* @param logStr - log string
*/
- void OCLog(LogLevel level, PROGMEM const char *tag, const int lineNum,
+ void OCLog(int level, PROGMEM const char *tag, const int lineNum,
PROGMEM const char *logStr);
/**
* @param buffer - pointer to buffer of bytes
* @param bufferSize - max number of byte in buffer
*/
- void OCLogBuffer(LogLevel level, const char* tag, const uint8_t* buffer, size_t bufferSize);
+ void OCLogBuffer(int level, const char* tag, const uint8_t* buffer, size_t bufferSize);
/**
* Output a variable argument list log string with the specified priority level.
* @param lineNum- line Number
* @param format - variadic log string
*/
- void OCLogv(LogLevel level, PROGMEM const char *tag, const int lineNum,
+ void OCLogv(int level, PROGMEM const char *tag, const int lineNum,
PROGMEM const char *format, ...)
#if defined(__GNUC__)
__attribute__ ((format(printf, 4, 5)))
#include "logger_types.h"
// log level
-LogLevel g_level = DEBUG;
-// privacy log
-bool g_hidePrivateLogEntries = false;
+static int g_level = DEBUG;
+// private log messages are not logged unless they have been explicitly enabled by calling OCSetLogLevel().
+static bool g_hidePrivateLogEntries = true;
#ifndef __TIZEN__
static oc_log_ctx_t *logCtx = 0;
PROGMEM const char * const LEVEL[] = {level0, level1, level2, level3, level4};
- static void OCLogString(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr);
+ static void OCLogString(int level, PROGMEM const char * tag, PROGMEM const char * logStr);
#ifdef ARDUINO_ARCH_AVR
//Mega2560 and other 8-bit AVR microcontrollers
#define GET_PROGMEM_BUFFER(buffer, addr) { OICStrcpy(buffer, sizeof(buffer), (char*)pgm_read_word(addr));}
{"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
#endif
+/**
+ * Checks if a message should be logged, based on its priority level, and removes
+ * the OC_LOG_PRIVATE_DATA bit if the message should be logged.
+ *
+ * @param level[in] - One of DEBUG, INFO, WARNING, ERROR, or FATAL plus possibly the OC_LOG_PRIVATE_DATA bit
+ *
+ * @return true if the message should be logged, false otherwise
+ */
+static bool AdjustAndVerifyLogLevel(int* level)
+{
+ int localLevel = *level;
+
+ if (OC_LOG_PRIVATE_DATA & localLevel)
+ {
+ if (g_hidePrivateLogEntries)
+ {
+ return false;
+ }
+
+ localLevel &= ~OC_LOG_PRIVATE_DATA;
+ }
+
+ if (g_level > localLevel)
+ {
+ return false;
+ }
+
+ *level = localLevel;
+ return true;
+}
+
#ifndef ARDUINO
/**
* Output the contents of the specified buffer (in hex) with the specified priority level.
*
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param level - One of DEBUG, INFO, WARNING, ERROR, or FATAL plus possibly the OC_LOG_PRIVATE_DATA bit
* @param tag - Module name
* @param buffer - pointer to buffer of bytes
* @param bufferSize - max number of byte in buffer
*/
-void OCLogBuffer(LogLevel level, const char* tag, const uint8_t* buffer, size_t bufferSize)
+void OCLogBuffer(int level, const char* tag, const uint8_t* buffer, size_t bufferSize)
{
if (!buffer || !tag || (bufferSize == 0))
{
return;
}
+ if (!AdjustAndVerifyLogLevel(&level))
+ {
+ return;
+ }
+
// No idea why the static initialization won't work here, it seems the compiler is convinced
// that this is a variable-sized object.
char lineBuffer[LINE_BUFFER_SIZE];
* Output a variable argument list log string with the specified priority level.
* Only defined for Linux and Android
*
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param level - One of DEBUG, INFO, WARNING, ERROR, or FATAL plus possibly the OC_LOG_PRIVATE_DATA bit
* @param tag - Module name
* @param format - variadic log string
*/
-void OCLogv(LogLevel level, const char * tag, const char * format, ...)
+void OCLogv(int level, const char * tag, const char * format, ...)
{
if (!format || !tag) {
return;
}
- if (g_level > level && ERROR != level && WARNING != level && FATAL != level)
- {
- return;
- }
-
- if (true == g_hidePrivateLogEntries && INFO_PRIVATE == level)
+ if (!AdjustAndVerifyLogLevel(&level))
{
return;
}
* Output a log string with the specified priority level.
* Only defined for Linux and Android
*
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param level - One of DEBUG, INFO, WARNING, ERROR, or FATAL plus possibly the OC_LOG_PRIVATE_DATA bit
* @param tag - Module name
* @param logStr - log string
*/
-void OCLog(LogLevel level, const char * tag, const char * logStr)
+void OCLog(int level, const char * tag, const char * logStr)
{
if (!logStr || !tag)
{
return;
}
- if (g_level > level && ERROR != level && WARNING != level && FATAL != level)
- {
- return;
- }
-
- if (true == g_hidePrivateLogEntries && INFO_PRIVATE == level)
+ if (!AdjustAndVerifyLogLevel(&level))
{
return;
}
case INFO_LITE:
level = INFO;
break;
- case INFO_PRIVATE:
- level = INFO;
- break;
default:
break;
}
* Only defined for Arduino. Only uses PROGMEM strings
* for the tag parameter
*
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param level - One of DEBUG, INFO, WARNING, ERROR, or FATAL plus possibly the OC_LOG_PRIVATE_DATA bit
* @param tag - Module name
* @param logStr - log string
*/
-void OCLogString(LogLevel level, PROGMEM const char * tag, const char * logStr)
+void OCLogString(int level, PROGMEM const char * tag, const char * logStr)
{
if (!logStr || !tag)
{
return;
}
- char buffer[LINE_BUFFER_SIZE];
+ if (!AdjustAndVerifyLogLevel(&level))
+ {
+ return;
+ }
+ char buffer[LINE_BUFFER_SIZE];
GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
Serial.print(buffer);
* Output the contents of the specified buffer (in hex) with the specified
* priority level.
*
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param level - One of DEBUG, INFO, WARNING, ERROR, or FATAL plus possibly the OC_LOG_PRIVATE_DATA bit
* @param tag - Module name
* @param buffer - pointer to buffer of bytes
* @param bufferSize - max number of byte in buffer
*/
- void OCLogBuffer(LogLevel level, PROGMEM const char * tag,
- const uint8_t * buffer, size_t bufferSize)
- {
- if (!buffer || !tag || (bufferSize == 0))
- {
- return;
- }
+void OCLogBuffer(int level, PROGMEM const char * tag,
+ const uint8_t * buffer, size_t bufferSize)
+{
+ if (!buffer || !tag || (bufferSize == 0))
+ {
+ return;
+ }
- char lineBuffer[LINE_BUFFER_SIZE] = {0};
- uint8_t lineIndex = 0;
- for (uint8_t i = 0; i < bufferSize; i++)
- {
+ if (!AdjustAndVerifyLogLevel(&level))
+ {
+ return;
+ }
+
+ char lineBuffer[LINE_BUFFER_SIZE] = {0};
+ uint8_t lineIndex = 0;
+ for (uint8_t i = 0; i < bufferSize; i++)
+ {
// Format the buffer data into a line
snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]);
lineIndex++;
- // Output 16 values per line
- if (((i+1)%16) == 0)
- {
- OCLogString(level, tag, lineBuffer);
- memset(lineBuffer, 0, sizeof lineBuffer);
- lineIndex = 0;
- }
- }
- // Output last values in the line, if any
- if (bufferSize % 16)
- {
- OCLogString(level, tag, lineBuffer);
- }
- }
+
+ // Output 16 values per line
+ if (((i+1)%16) == 0)
+ {
+ OCLogString(level, tag, lineBuffer);
+ memset(lineBuffer, 0, sizeof lineBuffer);
+ lineIndex = 0;
+ }
+ }
+ // Output last values in the line, if any
+ if (bufferSize % 16)
+ {
+ OCLogString(level, tag, lineBuffer);
+ }
+}
/**
* Output a log string with the specified priority level.
* Only defined for Arduino. Uses PROGMEM strings
*
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param level - One of DEBUG, INFO, WARNING, ERROR, or FATAL plus possibly the OC_LOG_PRIVATE_DATA bit
* @param tag - Module name
* @param logStr - log string
*/
-void OCLog(LogLevel level, PROGMEM const char *tag, const int lineNum,
+void OCLog(int level, PROGMEM const char *tag, const int lineNum,
PROGMEM const char *logStr)
{
if (!logStr || !tag)
{
return;
}
+
+ if (!AdjustAndVerifyLogLevel(&level))
+ {
+ return;
+ }
+
char buffer[LINE_BUFFER_SIZE] = {0};
GET_PROGMEM_BUFFER(buffer, &(LEVEL[level]));
Serial.print(buffer);
* Output a variable argument list log string with the specified priority level.
* Only defined for Arduino as depicted below.
*
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param level - One of DEBUG, INFO, WARNING, ERROR, or FATAL plus possibly the OC_LOG_PRIVATE_DATA bit
* @param tag - Module name
* @param format - variadic log string
*/
-void OCLogv(LogLevel level, PROGMEM const char *tag, const int lineNum,
+void OCLogv(int level, PROGMEM const char *tag, const int lineNum,
PROGMEM const char *format, ...)
{
+ if (!AdjustAndVerifyLogLevel(&level))
+ {
+ return;
+ }
+
char buffer[LINE_BUFFER_SIZE];
va_list ap;
va_start(ap, format);
* Output a variable argument list log string with the specified priority level.
* Only defined for Arduino as depicted below.
*
- * @param level - DEBUG, INFO, WARNING, ERROR, FATAL
+ * @param level - One of DEBUG, INFO, WARNING, ERROR, or FATAL plus possibly the OC_LOG_PRIVATE_DATA bit
* @param tag - Module name
* @param format - variadic log string
*/
-void OCLogv(LogLevel level, const char *tag, const __FlashStringHelper *format, ...)
+void OCLogv(int level, const char *tag, const __FlashStringHelper *format, ...)
{
+ if (!AdjustAndVerifyLogLevel(&level))
+ {
+ return;
+ }
+
char buffer[LINE_BUFFER_SIZE];
va_list ap;
va_start(ap, format);
set LOGGING=0
)
+if "%LOG_LEVEL%" == "" (
+ set LOG_LEVEL=DEBUG
+)
+
if "%RELEASE%" == "" (
set RELEASE=0
)
IF /I "%1"=="-logging" (
SET LOGGING=1
)
+ IF /I "%1"=="-logLevel" (
+ SET LOG_LEVEL=%2
+ SHIFT
+ )
IF /I "%1"=="-debugger" (
set DEBUG="%ProgramFiles(x86)%\Windows Kits\10\Debuggers\x64\cdb.exe" -2 -c "g"
)
set PATH=!PATH!;!BUILD_DIR!;C:\msys64\mingw64\bin
)
-set BUILD_OPTIONS= TARGET_OS=%TARGET_OS% TARGET_ARCH=%TARGET_ARCH% UWP_APP=%UWP_APP% RELEASE=%RELEASE% WITH_RA=0 TARGET_TRANSPORT=IP SECURED=%SECURED% WITH_TCP=%WITH_TCP% BUILD_SAMPLE=ON LOGGING=%LOGGING% RD_MODE=%RD_MODE% ROUTING=%ROUTING% WITH_UPSTREAM_LIBCOAP=%WITH_UPSTREAM_LIBCOAP% MULTIPLE_OWNER=%MULTIPLE_OWNER% AUTOMATIC_UPDATE=%AUTOMATIC_UPDATE%
+set BUILD_OPTIONS= TARGET_OS=%TARGET_OS% TARGET_ARCH=%TARGET_ARCH% UWP_APP=%UWP_APP% RELEASE=%RELEASE% WITH_RA=0 TARGET_TRANSPORT=IP SECURED=%SECURED% WITH_TCP=%WITH_TCP% BUILD_SAMPLE=ON LOGGING=%LOGGING% LOG_LEVEL=%LOG_LEVEL% RD_MODE=%RD_MODE% ROUTING=%ROUTING% WITH_UPSTREAM_LIBCOAP=%WITH_UPSTREAM_LIBCOAP% MULTIPLE_OWNER=%MULTIPLE_OWNER% AUTOMATIC_UPDATE=%AUTOMATIC_UPDATE%
REM Use MSVC_VERSION=12.0 for VS2013, or MSVC_VERSION=14.0 for VS2015.
REM If MSVC_VERSION has not been defined here, SCons chooses automatically a VS version.
echo RELEASE=%RELEASE%
echo TEST=%TEST%
echo LOGGING=%LOGGING%
+ echo LOG_LEVEL=%LOG_LEVEL%
echo ROUTING=%ROUTING%
echo WITH_TCP=%WITH_TCP%
echo WITH_UPSTREAM_LIBCOAP=%WITH_UPSTREAM_LIBCOAP%
echo.
echo -logging - Enable logging while building the binaries
echo.
+echo -logLevel LEVEL - Enable logging while building the binaries, and ignore log entries less severe than LEVEL.
+echo Valid levels are: DEBUG, INFO, WARNING, ERROR, and FATAL. Default level is DEBUG.
+echo.
echo -debugger - Debug the requested application
echo.
echo -release - Build release binaries
echo Build amd64 release binaries with logging enabled:
echo %0 build -arch amd64 -release -logging
echo.
+echo Build debug binaries with logging enabled, and ignore log entries less severe than WARNING:
+echo %0 build -logging -logLevel WARNING
+echo.
echo Build using only one thread:
echo %0 build -threads 1
echo.
#undef LOG_TAG
#endif // LOG_TAG
#define LOG_TAG "NotificationService"
-#define NS_CONVERT_LEVEL(level) ( \
- ((level) == 0) ? DLOG_DEBUG : \
- ((level) == 1) ? DLOG_INFO : \
- ((level) == 2) ? DLOG_WARN : \
- ((level) == 3) ? DLOG_ERROR : \
- ((level) == 4) ? DLOG_ERROR : \
- ((level) == 5) ? DLOG_INFO : \
- ((level) == 6) ? DLOG_INFO : \
- ((level) == 7) ? DLOG_INFO : DLOG_INFO)
-#define NS_LOG_V(level, format, ...) (dlog_print(NS_CONVERT_LEVEL(level), LOG_TAG, (format), __VA_ARGS__))
-#define NS_LOG(level, msg) (dlog_print(NS_CONVERT_LEVEL(level), LOG_TAG, (msg)))
+
+inline log_priority NSConvertLogLevel(int level)
+{
+ // Always log private data on Tizen.
+ level &= ~OC_LOG_PRIVATE_DATA;
+
+ if (level == DEBUG)
+ {
+ return DLOG_DEBUG;
+ }
+
+ if ((level == INFO) || (level == DEBUG_LITE) || (level == INFO_LITE))
+ {
+ return DLOG_INFO;
+ }
+
+ if (level == WARNING)
+ {
+ return DLOG_WARN;
+ }
+
+ if ((level == ERROR) || (level == FATAL))
+ {
+ return DLOG_ERROR;
+ }
+
+ return DLOG_INFO;
+}
+
+#define NS_LOG_V(level, format, ...) (dlog_print(NSConvertLogLevel(level), LOG_TAG, (format), __VA_ARGS__))
+#define NS_LOG(level, msg) (dlog_print(NSConvertLogLevel(level), LOG_TAG, (msg)))
#else // __TIZEN__
#define NS_LOG_V(level, format, ...) OIC_LOG_V((level), __NS_FILE__, (format), __VA_ARGS__)
#define NS_LOG(level, msg) OIC_LOG((level), __NS_FILE__, (msg))
#endif // __TIZEN__
#else // TB_LOG
#if (__PRINTLOG == 1)
-#define NS_CONVERT_LEVEL(level) ( \
+#define NSConvertLogLevel(level) ( \
((level) == 0) ? "DEBUG" : \
((level) == 1) ? "INFO" : \
((level) == 2) ? "WARNING" : \
((level) == 7) ? "INFO_PRIVATE" : "INFO_PRIVATE")
#define NS_LOG_V(level, format, ...) \
{ \
- printf("%s: %s ", NS_CONVERT_LEVEL(level), __NS_FILE__); \
+ printf("%s: %s ", NSConvertLogLevel(level), __NS_FILE__); \
printf((format), __VA_ARGS__); \
printf("\n"); \
}
#define NS_LOG(level, msg) \
{ \
- printf("%s: %s ", NS_CONVERT_LEVEL(level), __NS_FILE__); \
+ printf("%s: %s ", NSConvertLogLevel(level), __NS_FILE__); \
printf((msg)); \
printf("\n"); \
}
#else // (__PRINTLOG == 1)
-#define NS_CONVERT_LEVEL(level)
+#define NSConvertLogLevel(level)
#define NS_LOG(level, msg)
#define NS_LOG_V(level, format, ...) NS_LOG((level), ((format), __VA_ARGS__))
#endif // (__PRINTLOG == 1)