Browse Source

Logging enhancement: allow different callbacks serve different log levels

1. The default log level is set to VERBOSE for DEBUG builds and FATAL
for other builds
2. By default, there are the amount of slots is the same as the number
of log levels. And each registered callback can specify the minimal log
level it can handle.
3. The file logger's level is set to user configured level, while other
built-in loggers follows the default log level.

This does not affect the log processing logic: only the logs whose levels
are greater than user-configured are processed by UTIL_LogOutput. It
just affects how many callbacks can be called.
LouYihua 7 years ago
parent
commit
4b89c996fa
9 changed files with 29 additions and 11 deletions
  1. 1 1
      android/app/src/main/cpp/android_jni.cpp
  2. 7 1
      common.h
  3. 1 1
      main.c
  4. 1 1
      palcfg.c
  5. 1 1
      unix/unix.cpp
  6. 10 2
      util.c
  7. 6 2
      util.h
  8. 1 1
      win32/win32.cpp
  9. 1 1
      winrt/SDLPal.Common/WinRTUtil.cpp

+ 1 - 1
android/app/src/main/cpp/android_jni.cpp

@@ -301,7 +301,7 @@ UTIL_Platform_Init(
 			ANDROID_LOG_ERROR
 		};
 		__android_log_print(level_mapping[level], TAG, "%s", str);
-	});
+	}, PAL_DEFAULT_LOGLEVEL);
 
     FILE *fp = fopen((g_cachepath + "running").c_str(), "w");
     if (fp) fclose(fp);

+ 7 - 1
common.h

@@ -230,6 +230,12 @@ typedef enum tagLOGLEVEL
 	LOGLEVEL_MAX = LOGLEVEL_FATAL,
 } LOGLEVEL;
 
-#define PAL_LOG_MAX_OUTPUTS   4
+#define PAL_LOG_MAX_OUTPUTS   (LOGLEVEL_MAX + 1)
+
+#if defined(DEBUG) || defined(_DEBUG)
+# define PAL_DEFAULT_LOGLEVEL  LOGLEVEL_MIN
+#else
+# define PAL_DEFAULT_LOGLEVEL  LOGLEVEL_MAX
+#endif
 
 #endif

+ 1 - 1
main.c

@@ -498,7 +498,7 @@ main(
    // If user requests a file-based log, then add it after the system-specific one.
    //
    if (gConfig.pszLogFile)
-	   UTIL_LogAddOutputCallback(UTIL_LogToFile);
+	   UTIL_LogAddOutputCallback(UTIL_LogToFile, gConfig.iLogLevel);
 
    //
    // Initialize everything

+ 1 - 1
palcfg.c

@@ -45,7 +45,7 @@ static const ConfigItem gConfigItems[PALCFG_ALL_MAX] = {
 	{ PALCFG_USETOUCHOVERLAY,   PALCFG_BOOLEAN,  "UseTouchOverlay",   15, MAKE_VALUE(PAL_HAS_TOUCH,                 FALSE,                 TRUE) },
 
 	{ PALCFG_SURROUNDOPLOFFSET, PALCFG_INTEGER,  "SurroundOPLOffset", 17, MAKE_VALUE(384,                           INT32_MIN,             INT32_MAX) },
-	{ PALCFG_LOGLEVEL,          PALCFG_INTEGER,  "LogLevel",           8, MAKE_VALUE(LOGLEVEL_MAX,                  LOGLEVEL_MIN,          LOGLEVEL_MAX) },
+	{ PALCFG_LOGLEVEL,          PALCFG_INTEGER,  "LogLevel",           8, MAKE_VALUE(PAL_DEFAULT_LOGLEVEL,          LOGLEVEL_MIN,          LOGLEVEL_MAX) },
 
 	{ PALCFG_AUDIOBUFFERSIZE,   PALCFG_UNSIGNED, "AudioBufferSize",   15, MAKE_VALUE(PAL_AUDIO_DEFAULT_BUFFER_SIZE, 2,                     32768) },
 	{ PALCFG_CODEPAGE,          PALCFG_UNSIGNED, "CodePage",           8, MAKE_VALUE(CP_BIG5,                       CP_MIN,                CP_MAX - 1) },            // Default for BIG5

+ 1 - 1
unix/unix.cpp

@@ -263,7 +263,7 @@ UTIL_Platform_Init(
 			LOG_EMERG
 		};
 		syslog(priorities[level], "%s", str);
-	});
+	}, PAL_DEFAULT_LOGLEVEL);
 
 #if !defined(UNIT_TEST) && !defined(PAL_NO_LAUNCH_UI)
    if (gConfig.fLaunchSetting)

+ 10 - 2
util.c

@@ -587,6 +587,7 @@ UTIL_Platform_Quit(
 #define PAL_LOG_BUFFER_EXTRA_SIZE 32
 
 static LOGCALLBACK _log_callbacks[PAL_LOG_MAX_OUTPUTS];
+static LOGLEVEL _log_callback_levels[PAL_LOG_MAX_OUTPUTS];
 static char _log_buffer[PAL_LOG_BUFFER_SIZE + PAL_LOG_BUFFER_EXTRA_SIZE];
 
 static const char * const _loglevel_str[] = {
@@ -600,7 +601,8 @@ static const char * const _loglevel_str[] = {
 
 int
 UTIL_LogAddOutputCallback(
-	LOGCALLBACK    callback
+	LOGCALLBACK    callback,
+	LOGLEVEL       loglevel
 )
 {
 	if (!callback) return -1;
@@ -614,6 +616,7 @@ UTIL_LogAddOutputCallback(
 		}
 		if (_log_callbacks[i] == callback)
 		{
+			_log_callback_levels[i] = loglevel;
 			return i;
 		}
 	}
@@ -631,9 +634,11 @@ UTIL_LogRemoveOutputCallback(
 	while (id < PAL_LOG_MAX_OUTPUTS - 1)
 	{
 		_log_callbacks[id] = _log_callbacks[id + 1];
+		_log_callback_levels[id] = _log_callback_levels[id + 1];
 		id++;
 	}
 	_log_callbacks[id] = NULL;
+	_log_callback_levels[id] = LOGLEVEL_MIN;
 }
 
 void
@@ -663,7 +668,10 @@ UTIL_LogOutput(
 
 	for(id = 0; id < PAL_LOG_MAX_OUTPUTS && _log_callbacks[id]; id++)
 	{
-		_log_callbacks[id](level, _log_buffer, _log_buffer + PAL_LOG_BUFFER_EXTRA_SIZE - 1);
+		if (level >= _log_callback_levels[id])
+		{
+			_log_callbacks[id](level, _log_buffer, _log_buffer + PAL_LOG_BUFFER_EXTRA_SIZE - 1);
+		}
 	}
 }
 

+ 6 - 2
util.h

@@ -167,15 +167,19 @@ typedef void(*LOGCALLBACK)(LOGLEVEL level, const char *full_log, const char *use
 
     [IN]  callback     - The callback function to be added. Once added,
 	                     it will be called by UTIL_LogOutput.
+    [IN]  loglevel     - The minimal log level that the callback should
+	                     be called. Any log whose level below this will
+						 be ignored by the callback.
 
   Return value:
 
-    The id of this callback, -1 if all slots are used.
+    The slot id (>= 0), -1 if all slots are used or callback is NULL.
 
 --*/
 int
 UTIL_LogAddOutputCallback(
-	LOGCALLBACK    callback
+	LOGCALLBACK    callback,
+	LOGLEVEL       loglevel
 );
 
 /*++

+ 1 - 1
win32/win32.cpp

@@ -288,7 +288,7 @@ extern "C" int UTIL_Platform_Init(int argc, char* argv[])
 	// Defaults log to debug output
 	UTIL_LogAddOutputCallback([](LOGLEVEL, const char* str, const char*)->void {
 		OutputDebugStringA(str);
-	});
+	}, PAL_DEFAULT_LOGLEVEL);
 
 	g_hInstance = GetModuleHandle(nullptr);
 #if !defined(__MINGW32__) || _WIN32_WINNT > _WIN32_WINNT_WS03 // compile time switch; use `make CCFLAGS=-D_WIN32_WINNT=_WIN32_WINNT_VISTA` for vista+ only automatic language detection

+ 1 - 1
winrt/SDLPal.Common/WinRTUtil.cpp

@@ -165,7 +165,7 @@ INT UTIL_Platform_Init(int argc, char* argv[])
 	// Defaults log to debug output
 	UTIL_LogAddOutputCallback([](LOGLEVEL, const char* str, const char*)->void {
 		OutputDebugStringA(str);
-	});
+	}, PAL_DEFAULT_LOGLEVEL);
 
 	CreateRunningFile();