|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* WinPR: Windows Portable Runtime
|
|
Packit |
1fb8d4 |
* WinPR Logger
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
Packit |
1fb8d4 |
* you may not use this file except in compliance with the License.
|
|
Packit |
1fb8d4 |
* You may obtain a copy of the License at
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
1fb8d4 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
1fb8d4 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
1fb8d4 |
* See the License for the specific language governing permissions and
|
|
Packit |
1fb8d4 |
* limitations under the License.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
1fb8d4 |
#include "config.h"
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <stdio.h>
|
|
Packit |
1fb8d4 |
#include <string.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <winpr/crt.h>
|
|
Packit |
1fb8d4 |
#include <winpr/print.h>
|
|
Packit |
1fb8d4 |
#include <winpr/debug.h>
|
|
Packit |
1fb8d4 |
#include <winpr/environment.h>
|
|
Packit |
1fb8d4 |
#include <winpr/wlog.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#if defined(ANDROID)
|
|
Packit |
1fb8d4 |
#include <android/log.h>
|
|
Packit |
1fb8d4 |
#include "../log.h"
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include "wlog.h"
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
struct _wLogFilter
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD Level;
|
|
Packit |
1fb8d4 |
LPSTR* Names;
|
|
Packit |
1fb8d4 |
DWORD NameCount;
|
|
Packit |
1fb8d4 |
};
|
|
Packit |
1fb8d4 |
typedef struct _wLogFilter wLogFilter;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
#define WLOG_FILTER_NOT_FILTERED -1
|
|
Packit Service |
5a9772 |
#define WLOG_FILTER_NOT_INITIALIZED -2
|
|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* References for general logging concepts:
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Short introduction to log4j:
|
|
Packit |
1fb8d4 |
* http://logging.apache.org/log4j/1.2/manual.html
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* logging - Logging facility for Python:
|
|
Packit |
1fb8d4 |
* http://docs.python.org/2/library/logging.html
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
LPCSTR WLOG_LEVELS[7] = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "OFF" };
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static INIT_ONCE _WLogInitialized = INIT_ONCE_STATIC_INIT;
|
|
Packit |
1fb8d4 |
static DWORD g_FilterCount = 0;
|
|
Packit |
1fb8d4 |
static wLogFilter* g_Filters = NULL;
|
|
Packit |
1fb8d4 |
static wLog* g_RootLog = NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static wLog* WLog_New(LPCSTR name, wLog* rootLogger);
|
|
Packit |
1fb8d4 |
static void WLog_Free(wLog* log);
|
|
Packit |
1fb8d4 |
static LONG WLog_GetFilterLogLevel(wLog* log);
|
|
Packit |
1fb8d4 |
static int WLog_ParseLogLevel(LPCSTR level);
|
|
Packit |
1fb8d4 |
static BOOL WLog_ParseFilter(wLogFilter* filter, LPCSTR name);
|
|
Packit |
1fb8d4 |
static BOOL WLog_ParseFilters(void);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#if !defined(_WIN32)
|
|
Packit |
1fb8d4 |
static void WLog_Uninit_(void) __attribute__((destructor));
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static void WLog_Uninit_(void)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD index;
|
|
Packit |
1fb8d4 |
wLog* child = NULL;
|
|
Packit |
1fb8d4 |
wLog* root = g_RootLog;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!root)
|
|
Packit |
1fb8d4 |
return;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (index = 0; index < root->ChildrenCount; index++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
child = root->Children[index];
|
|
Packit |
1fb8d4 |
WLog_Free(child);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
WLog_Free(root);
|
|
Packit |
1fb8d4 |
g_RootLog = NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL CALLBACK WLog_InitializeRoot(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
char* env;
|
|
Packit |
1fb8d4 |
DWORD nSize;
|
|
Packit |
1fb8d4 |
DWORD logAppenderType;
|
|
Packit |
1fb8d4 |
LPCSTR appender = "WLOG_APPENDER";
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!(g_RootLog = WLog_New("", NULL)))
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
g_RootLog->IsRoot = TRUE;
|
|
Packit |
1fb8d4 |
WLog_ParseFilters();
|
|
Packit |
1fb8d4 |
logAppenderType = WLOG_APPENDER_CONSOLE;
|
|
Packit |
1fb8d4 |
nSize = GetEnvironmentVariableA(appender, NULL, 0);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (nSize)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
env = (LPSTR)malloc(nSize);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!env)
|
|
Packit |
1fb8d4 |
goto fail;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (GetEnvironmentVariableA(appender, env, nSize) != nSize - 1)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
fprintf(stderr, "%s environment variable modified in my back", appender);
|
|
Packit |
1fb8d4 |
free(env);
|
|
Packit |
1fb8d4 |
goto fail;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (_stricmp(env, "CONSOLE") == 0)
|
|
Packit |
1fb8d4 |
logAppenderType = WLOG_APPENDER_CONSOLE;
|
|
Packit |
1fb8d4 |
else if (_stricmp(env, "FILE") == 0)
|
|
Packit |
1fb8d4 |
logAppenderType = WLOG_APPENDER_FILE;
|
|
Packit |
1fb8d4 |
else if (_stricmp(env, "BINARY") == 0)
|
|
Packit |
1fb8d4 |
logAppenderType = WLOG_APPENDER_BINARY;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifdef HAVE_SYSLOG_H
|
|
Packit |
1fb8d4 |
else if (_stricmp(env, "SYSLOG") == 0)
|
|
Packit |
1fb8d4 |
logAppenderType = WLOG_APPENDER_SYSLOG;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#endif /* HAVE_SYSLOG_H */
|
|
Packit |
1fb8d4 |
#ifdef HAVE_JOURNALD_H
|
|
Packit |
1fb8d4 |
else if (_stricmp(env, "JOURNALD") == 0)
|
|
Packit |
1fb8d4 |
logAppenderType = WLOG_APPENDER_JOURNALD;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
else if (_stricmp(env, "UDP") == 0)
|
|
Packit |
1fb8d4 |
logAppenderType = WLOG_APPENDER_UDP;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
free(env);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!WLog_SetLogAppenderType(g_RootLog, logAppenderType))
|
|
Packit |
1fb8d4 |
goto fail;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#if defined(_WIN32)
|
|
Packit |
1fb8d4 |
atexit(WLog_Uninit_);
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
fail:
|
|
Packit |
1fb8d4 |
free(g_RootLog);
|
|
Packit |
1fb8d4 |
g_RootLog = NULL;
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL log_recursion(LPCSTR file, LPCSTR fkt, int line)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL status = FALSE;
|
|
Packit |
1fb8d4 |
char** msg = NULL;
|
|
Packit |
1fb8d4 |
size_t used, i;
|
|
Packit |
1fb8d4 |
void* bt = winpr_backtrace(20);
|
|
Packit |
1fb8d4 |
#if defined(ANDROID)
|
|
Packit |
1fb8d4 |
LPCSTR tag = WINPR_TAG("utils.wlog");
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!bt)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
msg = winpr_backtrace_symbols(bt, &used);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!msg)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#if defined(ANDROID)
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (__android_log_print(ANDROID_LOG_FATAL, tag, "Recursion detected!!!") < 0)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if (__android_log_print(ANDROID_LOG_FATAL, tag, "Check %s [%s:%d]", fkt, file, line) < 0)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; i < used; i++)
|
|
Packit |
1fb8d4 |
if (__android_log_print(ANDROID_LOG_FATAL, tag, "%zd: %s", i, msg[i]) < 0)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#else
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (fprintf(stderr, "[%s]: Recursion detected!\n", fkt) < 0)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (fprintf(stderr, "[%s]: Check %s:%d\n", fkt, file, line) < 0)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; i < used; i++)
|
|
Packit Service |
5a9772 |
if (fprintf(stderr, "%s: %" PRIuz ": %s\n", fkt, i, msg[i]) < 0)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
status = TRUE;
|
|
Packit |
1fb8d4 |
out:
|
|
Packit |
1fb8d4 |
free(msg);
|
|
Packit |
1fb8d4 |
winpr_backtrace_free(bt);
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL WLog_Write(wLog* log, wLogMessage* message)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL status;
|
|
Packit |
1fb8d4 |
wLogAppender* appender;
|
|
Packit |
1fb8d4 |
appender = WLog_GetLogAppender(log);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender->active)
|
|
Packit |
1fb8d4 |
if (!WLog_OpenAppender(log))
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender->WriteMessage)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
EnterCriticalSection(&appender->lock);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (appender->recursive)
|
|
Packit Service |
5a9772 |
status = log_recursion(message->FileName, message->FunctionName, message->LineNumber);
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
appender->recursive = TRUE;
|
|
Packit |
1fb8d4 |
status = appender->WriteMessage(log, appender, message);
|
|
Packit |
1fb8d4 |
appender->recursive = FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
LeaveCriticalSection(&appender->lock);
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL WLog_WriteData(wLog* log, wLogMessage* message)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL status;
|
|
Packit |
1fb8d4 |
wLogAppender* appender;
|
|
Packit |
1fb8d4 |
appender = WLog_GetLogAppender(log);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender->active)
|
|
Packit |
1fb8d4 |
if (!WLog_OpenAppender(log))
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender->WriteDataMessage)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
EnterCriticalSection(&appender->lock);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (appender->recursive)
|
|
Packit Service |
5a9772 |
status = log_recursion(message->FileName, message->FunctionName, message->LineNumber);
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
appender->recursive = TRUE;
|
|
Packit |
1fb8d4 |
status = appender->WriteDataMessage(log, appender, message);
|
|
Packit |
1fb8d4 |
appender->recursive = FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
LeaveCriticalSection(&appender->lock);
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL WLog_WriteImage(wLog* log, wLogMessage* message)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL status;
|
|
Packit |
1fb8d4 |
wLogAppender* appender;
|
|
Packit |
1fb8d4 |
appender = WLog_GetLogAppender(log);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender->active)
|
|
Packit |
1fb8d4 |
if (!WLog_OpenAppender(log))
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender->WriteImageMessage)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
EnterCriticalSection(&appender->lock);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (appender->recursive)
|
|
Packit Service |
5a9772 |
status = log_recursion(message->FileName, message->FunctionName, message->LineNumber);
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
appender->recursive = TRUE;
|
|
Packit |
1fb8d4 |
status = appender->WriteImageMessage(log, appender, message);
|
|
Packit |
1fb8d4 |
appender->recursive = FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
LeaveCriticalSection(&appender->lock);
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL WLog_WritePacket(wLog* log, wLogMessage* message)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL status;
|
|
Packit |
1fb8d4 |
wLogAppender* appender;
|
|
Packit |
1fb8d4 |
appender = WLog_GetLogAppender(log);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender->active)
|
|
Packit |
1fb8d4 |
if (!WLog_OpenAppender(log))
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!appender->WritePacketMessage)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
EnterCriticalSection(&appender->lock);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (appender->recursive)
|
|
Packit Service |
5a9772 |
status = log_recursion(message->FileName, message->FunctionName, message->LineNumber);
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
appender->recursive = TRUE;
|
|
Packit |
1fb8d4 |
status = appender->WritePacketMessage(log, appender, message);
|
|
Packit |
1fb8d4 |
appender->recursive = FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
LeaveCriticalSection(&appender->lock);
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
BOOL WLog_PrintMessageVA(wLog* log, DWORD type, DWORD level, DWORD line, const char* file,
|
|
Packit Service |
5a9772 |
const char* function, va_list args)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL status = FALSE;
|
|
Packit |
1fb8d4 |
wLogMessage message = { 0 };
|
|
Packit Service |
5a9772 |
message.Type = type;
|
|
Packit |
1fb8d4 |
message.Level = level;
|
|
Packit |
1fb8d4 |
message.LineNumber = line;
|
|
Packit |
1fb8d4 |
message.FileName = file;
|
|
Packit |
1fb8d4 |
message.FunctionName = function;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
switch (type)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
case WLOG_MESSAGE_TEXT:
|
|
Packit |
1fb8d4 |
message.FormatString = va_arg(args, const char*);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!strchr(message.FormatString, '%'))
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
message.TextString = (LPSTR)message.FormatString;
|
|
Packit |
1fb8d4 |
status = WLog_Write(log, &message);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
char formattedLogMessage[WLOG_MAX_STRING_SIZE];
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if (wvsnprintfx(formattedLogMessage, WLOG_MAX_STRING_SIZE - 1, message.FormatString,
|
|
Packit Service |
5a9772 |
args) < 0)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
message.TextString = formattedLogMessage;
|
|
Packit |
1fb8d4 |
status = WLog_Write(log, &message);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case WLOG_MESSAGE_DATA:
|
|
Packit |
1fb8d4 |
message.Data = va_arg(args, void*);
|
|
Packit |
1fb8d4 |
message.Length = va_arg(args, int);
|
|
Packit |
1fb8d4 |
status = WLog_WriteData(log, &message);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case WLOG_MESSAGE_IMAGE:
|
|
Packit |
1fb8d4 |
message.ImageData = va_arg(args, void*);
|
|
Packit |
1fb8d4 |
message.ImageWidth = va_arg(args, int);
|
|
Packit |
1fb8d4 |
message.ImageHeight = va_arg(args, int);
|
|
Packit |
1fb8d4 |
message.ImageBpp = va_arg(args, int);
|
|
Packit |
1fb8d4 |
status = WLog_WriteImage(log, &message);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case WLOG_MESSAGE_PACKET:
|
|
Packit |
1fb8d4 |
message.PacketData = va_arg(args, void*);
|
|
Packit |
1fb8d4 |
message.PacketLength = va_arg(args, int);
|
|
Packit |
1fb8d4 |
message.PacketFlags = va_arg(args, int);
|
|
Packit |
1fb8d4 |
status = WLog_WritePacket(log, &message);
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
default:
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
BOOL WLog_PrintMessage(wLog* log, DWORD type, DWORD level, DWORD line, const char* file,
|
|
Packit Service |
5a9772 |
const char* function, ...)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL status;
|
|
Packit |
1fb8d4 |
va_list args;
|
|
Packit |
1fb8d4 |
va_start(args, function);
|
|
Packit |
1fb8d4 |
status = WLog_PrintMessageVA(log, type, level, line, file, function, args);
|
|
Packit |
1fb8d4 |
va_end(args);
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
DWORD WLog_GetLogLevel(wLog* log)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
if (!log)
|
|
Packit Service |
5a9772 |
return WLOG_OFF;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (log->FilterLevel <= WLOG_FILTER_NOT_INITIALIZED)
|
|
Packit |
1fb8d4 |
log->FilterLevel = WLog_GetFilterLogLevel(log);
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if (log->FilterLevel > WLOG_FILTER_NOT_FILTERED)
|
|
Packit Service |
5a9772 |
return (DWORD)log->FilterLevel;
|
|
Packit |
1fb8d4 |
else if (log->Level == WLOG_LEVEL_INHERIT)
|
|
Packit |
1fb8d4 |
log->Level = WLog_GetLogLevel(log->Parent);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return log->Level;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
BOOL WLog_IsLevelActive(wLog* _log, DWORD _log_level)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
DWORD level;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (!_log)
|
|
Packit Service |
5a9772 |
return FALSE;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
level = WLog_GetLogLevel(_log);
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (level == WLOG_OFF)
|
|
Packit Service |
5a9772 |
return FALSE;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
return _log_level >= level;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit |
1fb8d4 |
BOOL WLog_SetStringLogLevel(wLog* log, LPCSTR level)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int lvl;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!log || !level)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
lvl = WLog_ParseLogLevel(level);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (lvl < 0)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
return WLog_SetLogLevel(log, (DWORD)lvl);
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
static BOOL WLog_reset_log_filters(wLog* log)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
DWORD x;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (!log)
|
|
Packit Service |
5a9772 |
return FALSE;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
log->FilterLevel = WLOG_FILTER_NOT_INITIALIZED;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
for (x = 0; x < log->ChildrenCount; x++)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
wLog* child = log->Children[x];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (!WLog_reset_log_filters(child))
|
|
Packit Service |
5a9772 |
return FALSE;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL WLog_AddStringLogFilters(LPCSTR filter)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD pos;
|
|
Packit |
1fb8d4 |
DWORD size;
|
|
Packit |
1fb8d4 |
DWORD count;
|
|
Packit |
1fb8d4 |
LPSTR p;
|
|
Packit |
1fb8d4 |
LPSTR filterStr;
|
|
Packit |
1fb8d4 |
LPSTR cp;
|
|
Packit |
1fb8d4 |
wLogFilter* tmp;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!filter)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
count = 1;
|
|
Packit |
1fb8d4 |
p = (LPSTR)filter;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
while ((p = strchr(p, ',')) != NULL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
count++;
|
|
Packit |
1fb8d4 |
p++;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
pos = g_FilterCount;
|
|
Packit |
1fb8d4 |
size = g_FilterCount + count;
|
|
Packit Service |
5a9772 |
tmp = (wLogFilter*)realloc(g_Filters, size * sizeof(wLogFilter));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!tmp)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
g_Filters = tmp;
|
|
Packit |
1fb8d4 |
cp = (LPSTR)_strdup(filter);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!cp)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
p = cp;
|
|
Packit |
1fb8d4 |
filterStr = cp;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
do
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
p = strchr(p, ',');
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (p)
|
|
Packit |
1fb8d4 |
*p = '\0';
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (pos < size)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!WLog_ParseFilter(&g_Filters[pos++], filterStr))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
free(cp);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (p)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
filterStr = p + 1;
|
|
Packit |
1fb8d4 |
p++;
|
|
Packit |
1fb8d4 |
}
|
|
Packit Service |
5a9772 |
} while (p != NULL);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
g_FilterCount = size;
|
|
Packit |
1fb8d4 |
free(cp);
|
|
Packit Service |
5a9772 |
return WLog_reset_log_filters(WLog_GetRoot());
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
static BOOL WLog_UpdateInheritLevel(wLog* log, DWORD logLevel)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
if (!log)
|
|
Packit Service |
5a9772 |
return FALSE;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (log->inherit)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
DWORD x;
|
|
Packit Service |
5a9772 |
log->Level = logLevel;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
for (x = 0; x < log->ChildrenCount; x++)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
wLog* child = log->Children[x];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (!WLog_UpdateInheritLevel(child, logLevel))
|
|
Packit Service |
5a9772 |
return FALSE;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL WLog_SetLogLevel(wLog* log, DWORD logLevel)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
DWORD x;
|
|
Packit Service |
5a9772 |
|
|
Packit |
1fb8d4 |
if (!log)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ((logLevel > WLOG_OFF) && (logLevel != WLOG_LEVEL_INHERIT))
|
|
Packit |
1fb8d4 |
logLevel = WLOG_OFF;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
log->Level = logLevel;
|
|
Packit Service |
5a9772 |
log->inherit = (logLevel == WLOG_LEVEL_INHERIT) ? TRUE : FALSE;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
for (x = 0; x < log->ChildrenCount; x++)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
wLog* child = log->Children[x];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (!WLog_UpdateInheritLevel(child, logLevel))
|
|
Packit Service |
5a9772 |
return FALSE;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
return WLog_reset_log_filters(log);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
int WLog_ParseLogLevel(LPCSTR level)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int iLevel = -1;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!level)
|
|
Packit |
1fb8d4 |
return -1;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (_stricmp(level, "TRACE") == 0)
|
|
Packit |
1fb8d4 |
iLevel = WLOG_TRACE;
|
|
Packit |
1fb8d4 |
else if (_stricmp(level, "DEBUG") == 0)
|
|
Packit |
1fb8d4 |
iLevel = WLOG_DEBUG;
|
|
Packit |
1fb8d4 |
else if (_stricmp(level, "INFO") == 0)
|
|
Packit |
1fb8d4 |
iLevel = WLOG_INFO;
|
|
Packit |
1fb8d4 |
else if (_stricmp(level, "WARN") == 0)
|
|
Packit |
1fb8d4 |
iLevel = WLOG_WARN;
|
|
Packit |
1fb8d4 |
else if (_stricmp(level, "ERROR") == 0)
|
|
Packit |
1fb8d4 |
iLevel = WLOG_ERROR;
|
|
Packit |
1fb8d4 |
else if (_stricmp(level, "FATAL") == 0)
|
|
Packit |
1fb8d4 |
iLevel = WLOG_FATAL;
|
|
Packit |
1fb8d4 |
else if (_stricmp(level, "OFF") == 0)
|
|
Packit |
1fb8d4 |
iLevel = WLOG_OFF;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return iLevel;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL WLog_ParseFilter(wLogFilter* filter, LPCSTR name)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
char* p;
|
|
Packit |
1fb8d4 |
char* q;
|
|
Packit |
1fb8d4 |
int count;
|
|
Packit |
1fb8d4 |
LPSTR names;
|
|
Packit |
1fb8d4 |
int iLevel;
|
|
Packit |
1fb8d4 |
count = 1;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!name)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
p = (char*)name;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (p)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
while ((p = strchr(p, '.')) != NULL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
count++;
|
|
Packit |
1fb8d4 |
p++;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
names = _strdup(name);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!names)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
filter->NameCount = count;
|
|
Packit Service |
5a9772 |
filter->Names = (LPSTR*)calloc((count + 1UL), sizeof(LPSTR));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!filter->Names)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
free(names);
|
|
Packit |
1fb8d4 |
filter->NameCount = 0;
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
filter->Names[count] = NULL;
|
|
Packit |
1fb8d4 |
count = 0;
|
|
Packit Service |
5a9772 |
p = (char*)names;
|
|
Packit |
1fb8d4 |
filter->Names[count++] = p;
|
|
Packit |
1fb8d4 |
q = strrchr(p, ':');
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!q)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
free(names);
|
|
Packit |
1fb8d4 |
free(filter->Names);
|
|
Packit |
1fb8d4 |
filter->Names = NULL;
|
|
Packit |
1fb8d4 |
filter->NameCount = 0;
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
*q = '\0';
|
|
Packit |
1fb8d4 |
q++;
|
|
Packit |
1fb8d4 |
iLevel = WLog_ParseLogLevel(q);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (iLevel < 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
free(names);
|
|
Packit |
1fb8d4 |
free(filter->Names);
|
|
Packit |
1fb8d4 |
filter->Names = NULL;
|
|
Packit |
1fb8d4 |
filter->NameCount = 0;
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
filter->Level = (DWORD)iLevel;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
while ((p = strchr(p, '.')) != NULL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
if (count < (int)filter->NameCount)
|
|
Packit |
1fb8d4 |
filter->Names[count++] = p + 1;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
*p = '\0';
|
|
Packit |
1fb8d4 |
p++;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL WLog_ParseFilters(void)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
LPCSTR filter = "WLOG_FILTER";
|
|
Packit |
1fb8d4 |
BOOL res = FALSE;
|
|
Packit |
1fb8d4 |
char* env;
|
|
Packit |
1fb8d4 |
DWORD nSize;
|
|
Packit Service |
5a9772 |
free(g_Filters);
|
|
Packit |
1fb8d4 |
g_Filters = NULL;
|
|
Packit |
1fb8d4 |
g_FilterCount = 0;
|
|
Packit |
1fb8d4 |
nSize = GetEnvironmentVariableA(filter, NULL, 0);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (nSize < 1)
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
env = (LPSTR)malloc(nSize);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!env)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (GetEnvironmentVariableA(filter, env, nSize) == nSize - 1)
|
|
Packit |
1fb8d4 |
res = WLog_AddStringLogFilters(env);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
free(env);
|
|
Packit |
1fb8d4 |
return res;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
LONG WLog_GetFilterLogLevel(wLog* log)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD i, j;
|
|
Packit |
1fb8d4 |
BOOL match = FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (log->FilterLevel >= 0)
|
|
Packit |
1fb8d4 |
return log->FilterLevel;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (i = 0; i < g_FilterCount; i++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
for (j = 0; j < g_Filters[i].NameCount; j++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (j >= log->NameCount)
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (_stricmp(g_Filters[i].Names[j], "*") == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
match = TRUE;
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (_stricmp(g_Filters[i].Names[j], log->Names[j]) != 0)
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (j == (log->NameCount - 1))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
match = TRUE;
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (match)
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (match)
|
|
Packit |
1fb8d4 |
log->FilterLevel = g_Filters[i].Level;
|
|
Packit |
1fb8d4 |
else
|
|
Packit Service |
5a9772 |
log->FilterLevel = WLOG_FILTER_NOT_FILTERED;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return log->FilterLevel;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL WLog_ParseName(wLog* log, LPCSTR name)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
char* p;
|
|
Packit |
1fb8d4 |
int count;
|
|
Packit |
1fb8d4 |
LPSTR names;
|
|
Packit |
1fb8d4 |
count = 1;
|
|
Packit Service |
5a9772 |
p = (char*)name;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
while ((p = strchr(p, '.')) != NULL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
count++;
|
|
Packit |
1fb8d4 |
p++;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
names = _strdup(name);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!names)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
log->NameCount = count;
|
|
Packit Service |
5a9772 |
log->Names = (LPSTR*)calloc((count + 1UL), sizeof(LPSTR));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!log->Names)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
free(names);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
log->Names[count] = NULL;
|
|
Packit |
1fb8d4 |
count = 0;
|
|
Packit Service |
5a9772 |
p = (char*)names;
|
|
Packit |
1fb8d4 |
log->Names[count++] = p;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
while ((p = strchr(p, '.')) != NULL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
if (count < (int)log->NameCount)
|
|
Packit |
1fb8d4 |
log->Names[count++] = p + 1;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
*p = '\0';
|
|
Packit |
1fb8d4 |
p++;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
wLog* WLog_New(LPCSTR name, wLog* rootLogger)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
wLog* log = NULL;
|
|
Packit |
1fb8d4 |
char* env = NULL;
|
|
Packit |
1fb8d4 |
DWORD nSize;
|
|
Packit |
1fb8d4 |
int iLevel;
|
|
Packit Service |
5a9772 |
log = (wLog*)calloc(1, sizeof(wLog));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!log)
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
log->Name = _strdup(name);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!log->Name)
|
|
Packit |
1fb8d4 |
goto out_fail;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!WLog_ParseName(log, name))
|
|
Packit |
1fb8d4 |
goto out_fail;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
log->Parent = rootLogger;
|
|
Packit |
1fb8d4 |
log->ChildrenCount = 0;
|
|
Packit |
1fb8d4 |
log->ChildrenSize = 16;
|
|
Packit Service |
5a9772 |
log->FilterLevel = WLOG_FILTER_NOT_INITIALIZED;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if (!(log->Children = (wLog**)calloc(log->ChildrenSize, sizeof(wLog*))))
|
|
Packit |
1fb8d4 |
goto out_fail;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
log->Appender = NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (rootLogger)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
log->Level = WLOG_LEVEL_INHERIT;
|
|
Packit Service |
5a9772 |
log->inherit = TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
LPCSTR level = "WLOG_LEVEL";
|
|
Packit |
1fb8d4 |
log->Level = WLOG_INFO;
|
|
Packit |
1fb8d4 |
nSize = GetEnvironmentVariableA(level, NULL, 0);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (nSize)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
env = (LPSTR)malloc(nSize);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!env)
|
|
Packit |
1fb8d4 |
goto out_fail;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (GetEnvironmentVariableA(level, env, nSize) != nSize - 1)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
fprintf(stderr, "%s environment variable changed in my back !\n", level);
|
|
Packit |
1fb8d4 |
free(env);
|
|
Packit |
1fb8d4 |
goto out_fail;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
iLevel = WLog_ParseLogLevel(env);
|
|
Packit |
1fb8d4 |
free(env);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (iLevel >= 0)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
if (!WLog_SetLogLevel(log, (DWORD)iLevel))
|
|
Packit Service |
5a9772 |
goto out_fail;
|
|
Packit Service |
5a9772 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
iLevel = WLog_GetFilterLogLevel(log);
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if (iLevel >= 0)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
if (!WLog_SetLogLevel(log, (DWORD)iLevel))
|
|
Packit Service |
5a9772 |
goto out_fail;
|
|
Packit Service |
5a9772 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return log;
|
|
Packit |
1fb8d4 |
out_fail:
|
|
Packit |
1fb8d4 |
free(log->Children);
|
|
Packit |
1fb8d4 |
free(log->Name);
|
|
Packit |
1fb8d4 |
free(log);
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
void WLog_Free(wLog* log)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (log)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (log->Appender)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_Appender_Free(log, log->Appender);
|
|
Packit |
1fb8d4 |
log->Appender = NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
free(log->Name);
|
|
Packit |
1fb8d4 |
free(log->Names[0]);
|
|
Packit |
1fb8d4 |
free(log->Names);
|
|
Packit |
1fb8d4 |
free(log->Children);
|
|
Packit |
1fb8d4 |
free(log);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
wLog* WLog_GetRoot(void)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!InitOnceExecuteOnce(&_WLogInitialized, WLog_InitializeRoot, NULL, NULL))
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return g_RootLog;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static BOOL WLog_AddChild(wLog* parent, wLog* child)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (parent->ChildrenCount >= parent->ChildrenSize)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
wLog** tmp;
|
|
Packit |
1fb8d4 |
parent->ChildrenSize *= 2;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!parent->ChildrenSize)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (parent->Children)
|
|
Packit |
1fb8d4 |
free(parent->Children);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
parent->Children = NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
tmp = (wLog**)realloc(parent->Children, sizeof(wLog*) * parent->ChildrenSize);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!tmp)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (parent->Children)
|
|
Packit |
1fb8d4 |
free(parent->Children);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
parent->Children = NULL;
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
parent->Children = tmp;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!parent->Children)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
parent->Children[parent->ChildrenCount++] = child;
|
|
Packit |
1fb8d4 |
child->Parent = parent;
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static wLog* WLog_FindChild(LPCSTR name)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD index;
|
|
Packit |
1fb8d4 |
wLog* root;
|
|
Packit |
1fb8d4 |
wLog* child = NULL;
|
|
Packit |
1fb8d4 |
BOOL found = FALSE;
|
|
Packit |
1fb8d4 |
root = WLog_GetRoot();
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!root)
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (index = 0; index < root->ChildrenCount; index++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
child = root->Children[index];
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (strcmp(child->Name, name) == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
found = TRUE;
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return (found) ? child : NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
wLog* WLog_Get(LPCSTR name)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
wLog* log;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!(log = WLog_FindChild(name)))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
wLog* root = WLog_GetRoot();
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!root)
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!(log = WLog_New(name, root)))
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!WLog_AddChild(root, log))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_Free(log);
|
|
Packit |
1fb8d4 |
return NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return log;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL WLog_Init(void)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return WLog_GetRoot() != NULL;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL WLog_Uninit(void)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|