2013-09-15 23:46:02 +04:00
|
|
|
/**
|
|
|
|
* WinPR: Windows Portable Runtime
|
|
|
|
* WinPR Logger
|
|
|
|
*
|
|
|
|
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2013-09-16 00:48:09 +04:00
|
|
|
#include <winpr/crt.h>
|
2013-09-15 23:46:02 +04:00
|
|
|
#include <winpr/print.h>
|
2014-08-18 21:24:16 +04:00
|
|
|
#include <winpr/debug.h>
|
2013-10-09 06:35:14 +04:00
|
|
|
#include <winpr/environment.h>
|
2013-09-15 23:46:02 +04:00
|
|
|
|
2014-08-18 20:57:08 +04:00
|
|
|
#if defined(ANDROID)
|
|
|
|
#include <android/log.h>
|
|
|
|
#endif
|
|
|
|
|
2013-09-15 23:46:02 +04:00
|
|
|
#include <winpr/wlog.h>
|
|
|
|
|
2013-10-02 00:08:26 +04:00
|
|
|
#include "wlog/wlog.h"
|
|
|
|
|
2014-08-18 20:57:08 +04:00
|
|
|
#include "../../log.h"
|
|
|
|
|
2013-09-16 20:05:08 +04:00
|
|
|
/**
|
|
|
|
* References for general logging concepts:
|
|
|
|
*
|
|
|
|
* Short introduction to log4j:
|
|
|
|
* http://logging.apache.org/log4j/1.2/manual.html
|
|
|
|
*
|
|
|
|
* logging - Logging facility for Python:
|
|
|
|
* http://docs.python.org/2/library/logging.html
|
|
|
|
*/
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
const char *WLOG_LEVELS[7] =
|
2013-09-15 23:46:02 +04:00
|
|
|
{
|
2013-09-17 00:30:49 +04:00
|
|
|
"TRACE",
|
|
|
|
"DEBUG",
|
|
|
|
"INFO",
|
|
|
|
"WARN",
|
|
|
|
"ERROR",
|
|
|
|
"FATAL",
|
|
|
|
"OFF"
|
2013-09-16 00:48:09 +04:00
|
|
|
};
|
|
|
|
|
2014-05-29 23:23:15 +04:00
|
|
|
static DWORD g_FilterCount = 0;
|
2014-08-18 19:11:40 +04:00
|
|
|
static wLogFilter *g_Filters = NULL;
|
2014-05-29 23:23:15 +04:00
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
static void log_recursion(const char *file, const char *fkt, int line)
|
2013-09-16 00:48:09 +04:00
|
|
|
{
|
2014-08-18 21:24:16 +04:00
|
|
|
size_t used, i;
|
|
|
|
void *bt = winpr_backtrace(20);
|
|
|
|
char **msg = winpr_backtrace_symbols(bt, &used);
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
#if defined(ANDROID)
|
2014-08-18 20:57:08 +04:00
|
|
|
const char *tag = WINPR_TAG("utils.wlog");
|
2014-08-18 19:11:40 +04:00
|
|
|
__android_log_print(ANDROID_LOG_FATAL, tag, "Recursion detected!!!");
|
|
|
|
__android_log_print(ANDROID_LOG_FATAL, tag, "Check %s [%s:%d]", fkt, file, line);
|
2014-08-18 21:24:16 +04:00
|
|
|
for (i=0; i<used; i++)
|
|
|
|
__android_log_print(ANDROID_LOG_FATAL, tag, "%d: %s", msg[i]);
|
2014-08-18 19:11:40 +04:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "[%s]: Recursion detected!\n", fkt);
|
|
|
|
fprintf(stderr, "[%s]: Check %s:%d\n", fkt, file, line);
|
2014-08-18 21:24:16 +04:00
|
|
|
for (i=0; i<used; i++)
|
|
|
|
fprintf(stderr, "%s: %zd: %s\n", fkt, i, msg[i]);
|
2014-08-18 19:11:40 +04:00
|
|
|
#endif
|
2014-08-18 21:24:16 +04:00
|
|
|
|
|
|
|
if (msg)
|
|
|
|
free(msg);
|
|
|
|
winpr_backtrace_free(bt);
|
2014-08-18 19:11:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int WLog_Write(wLog *log, wLogMessage *message)
|
|
|
|
{
|
|
|
|
int status = -1;
|
|
|
|
wLogAppender *appender;
|
2013-10-02 02:19:50 +04:00
|
|
|
appender = WLog_GetLogAppender(log);
|
|
|
|
|
|
|
|
if (!appender)
|
2013-09-16 20:05:08 +04:00
|
|
|
return -1;
|
2013-09-15 23:46:02 +04:00
|
|
|
|
2013-10-09 06:35:14 +04:00
|
|
|
if (!appender->State)
|
|
|
|
WLog_OpenAppender(log);
|
|
|
|
|
2013-10-02 02:19:50 +04:00
|
|
|
if (!appender->WriteMessage)
|
2013-09-16 20:05:08 +04:00
|
|
|
return -1;
|
2013-09-15 23:46:02 +04:00
|
|
|
|
2013-10-02 21:38:21 +04:00
|
|
|
EnterCriticalSection(&appender->lock);
|
|
|
|
|
2014-08-18 16:19:48 +04:00
|
|
|
if (appender->recursive)
|
2014-08-18 19:11:40 +04:00
|
|
|
log_recursion(message->FileName, message->FunctionName, message->LineNumber);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
appender->recursive = TRUE;
|
|
|
|
status = appender->WriteMessage(log, appender, message);
|
|
|
|
appender->recursive = FALSE;
|
|
|
|
}
|
2013-10-02 21:38:21 +04:00
|
|
|
|
|
|
|
LeaveCriticalSection(&appender->lock);
|
|
|
|
return status;
|
2013-09-15 23:46:02 +04:00
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
int WLog_WriteData(wLog *log, wLogMessage *message)
|
2013-10-09 07:18:59 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
int status = -1;
|
|
|
|
wLogAppender *appender;
|
2013-10-09 07:18:59 +04:00
|
|
|
appender = WLog_GetLogAppender(log);
|
|
|
|
|
|
|
|
if (!appender)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!appender->State)
|
|
|
|
WLog_OpenAppender(log);
|
|
|
|
|
|
|
|
if (!appender->WriteDataMessage)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
EnterCriticalSection(&appender->lock);
|
|
|
|
|
2014-08-18 16:19:48 +04:00
|
|
|
if (appender->recursive)
|
2014-08-18 19:11:40 +04:00
|
|
|
log_recursion(message->FileName, message->FunctionName, message->LineNumber);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
appender->recursive = TRUE;
|
|
|
|
status = appender->WriteDataMessage(log, appender, message);
|
|
|
|
appender->recursive = FALSE;
|
|
|
|
}
|
2013-10-09 07:18:59 +04:00
|
|
|
|
|
|
|
LeaveCriticalSection(&appender->lock);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
int WLog_WriteImage(wLog *log, wLogMessage *message)
|
2013-09-15 23:46:02 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
int status = -1;
|
|
|
|
wLogAppender *appender;
|
2013-10-02 23:41:46 +04:00
|
|
|
appender = WLog_GetLogAppender(log);
|
|
|
|
|
|
|
|
if (!appender)
|
|
|
|
return -1;
|
|
|
|
|
2013-10-09 06:35:14 +04:00
|
|
|
if (!appender->State)
|
|
|
|
WLog_OpenAppender(log);
|
|
|
|
|
2013-10-02 23:41:46 +04:00
|
|
|
if (!appender->WriteImageMessage)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
EnterCriticalSection(&appender->lock);
|
|
|
|
|
2014-08-18 16:19:48 +04:00
|
|
|
if (appender->recursive)
|
2014-08-18 19:11:40 +04:00
|
|
|
log_recursion(message->FileName, message->FunctionName, message->LineNumber);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
appender->recursive = TRUE;
|
|
|
|
status = appender->WriteImageMessage(log, appender, message);
|
|
|
|
appender->recursive = FALSE;
|
|
|
|
}
|
2013-10-02 23:41:46 +04:00
|
|
|
|
|
|
|
LeaveCriticalSection(&appender->lock);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
int WLog_WritePacket(wLog *log, wLogMessage *message)
|
2013-10-02 23:41:46 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
int status = -1;
|
|
|
|
wLogAppender *appender;
|
2013-10-02 23:41:46 +04:00
|
|
|
appender = WLog_GetLogAppender(log);
|
|
|
|
|
|
|
|
if (!appender)
|
|
|
|
return -1;
|
|
|
|
|
2013-10-09 06:35:14 +04:00
|
|
|
if (!appender->State)
|
|
|
|
WLog_OpenAppender(log);
|
|
|
|
|
2013-10-09 07:18:59 +04:00
|
|
|
if (!appender->WritePacketMessage)
|
2013-10-02 23:41:46 +04:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
EnterCriticalSection(&appender->lock);
|
|
|
|
|
2014-08-18 16:19:48 +04:00
|
|
|
if (appender->recursive)
|
2014-08-18 19:11:40 +04:00
|
|
|
log_recursion(message->FileName, message->FunctionName, message->LineNumber);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
appender->recursive = TRUE;
|
|
|
|
status = appender->WritePacketMessage(log, appender, message);
|
|
|
|
appender->recursive = FALSE;
|
|
|
|
}
|
2013-10-02 23:41:46 +04:00
|
|
|
|
|
|
|
LeaveCriticalSection(&appender->lock);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
int WLog_PrintMessageVA(wLog *log, wLogMessage *message, va_list args)
|
2013-10-02 23:41:46 +04:00
|
|
|
{
|
|
|
|
int status = -1;
|
|
|
|
|
2013-10-02 21:38:21 +04:00
|
|
|
if (message->Type == WLOG_MESSAGE_TEXT)
|
|
|
|
{
|
|
|
|
if (!strchr(message->FormatString, '%'))
|
|
|
|
{
|
|
|
|
message->TextString = (LPSTR) message->FormatString;
|
2013-10-02 23:41:46 +04:00
|
|
|
status = WLog_Write(log, message);
|
2013-10-02 21:38:21 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char formattedLogMessage[WLOG_MAX_STRING_SIZE];
|
|
|
|
wvsnprintfx(formattedLogMessage, WLOG_MAX_STRING_SIZE - 1, message->FormatString, args);
|
|
|
|
message->TextString = formattedLogMessage;
|
2013-10-02 23:41:46 +04:00
|
|
|
status = WLog_Write(log, message);
|
2013-10-02 21:38:21 +04:00
|
|
|
}
|
|
|
|
}
|
2013-10-09 07:43:57 +04:00
|
|
|
else if (message->Type == WLOG_MESSAGE_DATA)
|
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
message->Data = va_arg(args, void *);
|
2013-10-09 07:43:57 +04:00
|
|
|
message->Length = va_arg(args, int);
|
|
|
|
status = WLog_WriteData(log, message);
|
|
|
|
}
|
2013-10-02 21:38:21 +04:00
|
|
|
else if (message->Type == WLOG_MESSAGE_IMAGE)
|
2013-09-15 23:46:02 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
message->ImageData = va_arg(args, void *);
|
2013-10-02 23:41:46 +04:00
|
|
|
message->ImageWidth = va_arg(args, int);
|
|
|
|
message->ImageHeight = va_arg(args, int);
|
|
|
|
message->ImageBpp = va_arg(args, int);
|
|
|
|
status = WLog_WriteImage(log, message);
|
2013-09-15 23:46:02 +04:00
|
|
|
}
|
2013-10-09 07:43:57 +04:00
|
|
|
else if (message->Type == WLOG_MESSAGE_PACKET)
|
2013-09-15 23:46:02 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
message->PacketData = va_arg(args, void *);
|
2013-10-09 07:43:57 +04:00
|
|
|
message->PacketLength = va_arg(args, int);
|
|
|
|
message->PacketFlags = va_arg(args, int);
|
|
|
|
status = WLog_WritePacket(log, message);
|
2013-09-15 23:46:02 +04:00
|
|
|
}
|
2013-10-02 23:41:46 +04:00
|
|
|
|
|
|
|
return status;
|
2013-09-15 23:46:02 +04:00
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
void WLog_PrintMessage(wLog *log, wLogMessage *message, ...)
|
2013-09-15 23:46:02 +04:00
|
|
|
{
|
2013-10-02 23:41:46 +04:00
|
|
|
int status;
|
2013-09-15 23:46:02 +04:00
|
|
|
va_list args;
|
2013-09-17 00:30:49 +04:00
|
|
|
va_start(args, message);
|
2013-10-02 23:41:46 +04:00
|
|
|
status = WLog_PrintMessageVA(log, message, args);
|
2013-09-15 23:46:02 +04:00
|
|
|
va_end(args);
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
DWORD WLog_GetLogLevel(wLog *log)
|
2013-09-15 23:46:02 +04:00
|
|
|
{
|
2014-05-29 23:23:15 +04:00
|
|
|
if (log->Level == WLOG_LEVEL_INHERIT)
|
|
|
|
{
|
2014-01-15 17:52:48 +04:00
|
|
|
return WLog_GetLogLevel(log->Parent);
|
2014-05-29 23:23:15 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-01-15 17:52:48 +04:00
|
|
|
return log->Level;
|
|
|
|
}
|
2013-09-15 23:46:02 +04:00
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
void WLog_SetLogLevel(wLog *log, DWORD logLevel)
|
2013-09-15 23:46:02 +04:00
|
|
|
{
|
2014-01-15 17:52:48 +04:00
|
|
|
if ((logLevel > WLOG_OFF) && (logLevel != WLOG_LEVEL_INHERIT))
|
|
|
|
{
|
|
|
|
logLevel = WLOG_OFF;
|
|
|
|
}
|
2014-05-29 23:23:15 +04:00
|
|
|
|
2013-09-16 00:48:09 +04:00
|
|
|
log->Level = logLevel;
|
2013-09-15 23:46:02 +04:00
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
int WLog_ParseLogLevel(const char *level)
|
2014-05-29 23:23:15 +04:00
|
|
|
{
|
|
|
|
int iLevel = -1;
|
|
|
|
|
|
|
|
if (!level)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (_stricmp(level, "TRACE") == 0)
|
|
|
|
iLevel = WLOG_TRACE;
|
|
|
|
else if (_stricmp(level, "DEBUG") == 0)
|
|
|
|
iLevel = WLOG_DEBUG;
|
|
|
|
else if (_stricmp(level, "INFO") == 0)
|
|
|
|
iLevel = WLOG_INFO;
|
|
|
|
else if (_stricmp(level, "WARN") == 0)
|
|
|
|
iLevel = WLOG_WARN;
|
|
|
|
else if (_stricmp(level, "ERROR") == 0)
|
|
|
|
iLevel = WLOG_ERROR;
|
|
|
|
else if (_stricmp(level, "FATAL") == 0)
|
|
|
|
iLevel = WLOG_FATAL;
|
|
|
|
else if (_stricmp(level, "OFF") == 0)
|
|
|
|
iLevel = WLOG_OFF;
|
|
|
|
|
|
|
|
return iLevel;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
int WLog_ParseFilter(wLogFilter *filter, LPCSTR name)
|
2014-05-29 23:23:15 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
char *p;
|
|
|
|
char *q;
|
2014-05-29 23:23:15 +04:00
|
|
|
int count;
|
|
|
|
LPSTR names;
|
|
|
|
int iLevel;
|
|
|
|
count = 1;
|
2014-08-18 19:11:40 +04:00
|
|
|
p = (char *) name;
|
2014-05-29 23:23:15 +04:00
|
|
|
|
|
|
|
while ((p = strchr(p, '.')) != NULL)
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
names = _strdup(name);
|
|
|
|
filter->NameCount = count;
|
2014-08-18 19:11:40 +04:00
|
|
|
filter->Names = (LPSTR *) malloc(sizeof(LPSTR) * (count + 1));
|
2014-05-29 23:23:15 +04:00
|
|
|
filter->Names[count] = NULL;
|
|
|
|
count = 0;
|
2014-08-18 19:11:40 +04:00
|
|
|
p = (char *) names;
|
2014-05-29 23:23:15 +04:00
|
|
|
filter->Names[count++] = p;
|
|
|
|
q = strrchr(p, ':');
|
|
|
|
|
|
|
|
if (!q)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*q = '\0';
|
|
|
|
q++;
|
|
|
|
iLevel = WLog_ParseLogLevel(q);
|
|
|
|
|
|
|
|
if (iLevel < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
filter->Level = (DWORD) iLevel;
|
|
|
|
|
|
|
|
while ((p = strchr(p, '.')) != NULL)
|
|
|
|
{
|
|
|
|
filter->Names[count++] = p + 1;
|
|
|
|
*p = '\0';
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int WLog_ParseFilters()
|
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
char *p;
|
|
|
|
char *env;
|
2014-06-06 06:10:08 +04:00
|
|
|
DWORD count;
|
2014-05-29 23:23:15 +04:00
|
|
|
DWORD nSize;
|
|
|
|
int status;
|
2014-08-18 19:11:40 +04:00
|
|
|
char **strs;
|
2014-05-29 23:23:15 +04:00
|
|
|
nSize = GetEnvironmentVariableA("WLOG_FILTER", NULL, 0);
|
|
|
|
|
|
|
|
if (nSize < 1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
env = (LPSTR) malloc(nSize);
|
|
|
|
|
|
|
|
if (!env)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
nSize = GetEnvironmentVariableA("WLOG_FILTER", env, nSize);
|
|
|
|
count = 1;
|
|
|
|
p = env;
|
|
|
|
|
|
|
|
while ((p = strchr(p, ',')) != NULL)
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_FilterCount = count;
|
|
|
|
p = env;
|
|
|
|
count = 0;
|
2014-08-18 19:11:40 +04:00
|
|
|
strs = (char **) calloc(g_FilterCount, sizeof(char *));
|
2014-05-29 23:23:15 +04:00
|
|
|
strs[count++] = p;
|
|
|
|
|
|
|
|
while ((p = strchr(p, ',')) != NULL)
|
|
|
|
{
|
|
|
|
strs[count++] = p + 1;
|
|
|
|
*p = '\0';
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_Filters = calloc(g_FilterCount, sizeof(wLogFilter));
|
|
|
|
|
|
|
|
if (!g_Filters)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
for (count = 0; count < g_FilterCount; count++)
|
|
|
|
{
|
|
|
|
status = WLog_ParseFilter(&g_Filters[count], strs[count]);
|
|
|
|
|
|
|
|
if (status < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(strs);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
int WLog_GetFilterLogLevel(wLog *log)
|
2014-05-29 23:23:15 +04:00
|
|
|
{
|
|
|
|
DWORD i, j;
|
|
|
|
int iLevel = -1;
|
|
|
|
BOOL match = FALSE;
|
|
|
|
|
|
|
|
for (i = 0; i < g_FilterCount; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < g_Filters[i].NameCount; j++)
|
|
|
|
{
|
|
|
|
if (j >= log->NameCount)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (_stricmp(g_Filters[i].Names[j], "*") == 0)
|
|
|
|
{
|
|
|
|
match = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_stricmp(g_Filters[i].Names[j], log->Names[j]) != 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (j == (log->NameCount - 1))
|
|
|
|
{
|
|
|
|
match = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (match)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (match)
|
|
|
|
{
|
|
|
|
iLevel = (int) g_Filters[i].Level;
|
|
|
|
}
|
|
|
|
|
|
|
|
return iLevel;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
int WLog_ParseName(wLog *log, LPCSTR name)
|
2013-10-02 00:08:26 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
char *p;
|
2013-10-02 00:08:26 +04:00
|
|
|
int count;
|
|
|
|
LPSTR names;
|
|
|
|
count = 1;
|
2014-08-18 19:11:40 +04:00
|
|
|
p = (char *) name;
|
2013-10-02 00:08:26 +04:00
|
|
|
|
|
|
|
while ((p = strchr(p, '.')) != NULL)
|
|
|
|
{
|
|
|
|
count++;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
names = _strdup(name);
|
|
|
|
log->NameCount = count;
|
2014-08-18 19:11:40 +04:00
|
|
|
log->Names = (LPSTR *) malloc(sizeof(LPSTR) * (count + 1));
|
2013-10-02 00:08:26 +04:00
|
|
|
log->Names[count] = NULL;
|
|
|
|
count = 0;
|
2014-08-18 19:11:40 +04:00
|
|
|
p = (char *) names;
|
2013-10-02 00:08:26 +04:00
|
|
|
log->Names[count++] = p;
|
|
|
|
|
|
|
|
while ((p = strchr(p, '.')) != NULL)
|
|
|
|
{
|
|
|
|
log->Names[count++] = p + 1;
|
|
|
|
*p = '\0';
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
wLog *WLog_New(LPCSTR name, wLog *rootLogger)
|
2013-09-15 23:46:02 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
wLog *log;
|
|
|
|
char *env;
|
2013-10-09 06:35:14 +04:00
|
|
|
DWORD nSize;
|
2014-05-29 23:23:15 +04:00
|
|
|
int iLevel;
|
2014-08-18 19:11:40 +04:00
|
|
|
log = (wLog *) calloc(1, sizeof(wLog));
|
2013-09-16 00:48:09 +04:00
|
|
|
|
|
|
|
if (log)
|
|
|
|
{
|
|
|
|
log->Name = _strdup(name);
|
2014-05-29 23:23:15 +04:00
|
|
|
|
|
|
|
if (!log->Name)
|
|
|
|
return NULL;
|
|
|
|
|
2013-10-02 00:08:26 +04:00
|
|
|
WLog_ParseName(log, name);
|
2014-01-15 17:52:48 +04:00
|
|
|
log->Parent = rootLogger;
|
2013-10-02 02:19:50 +04:00
|
|
|
log->ChildrenCount = 0;
|
|
|
|
log->ChildrenSize = 16;
|
2014-08-18 19:11:40 +04:00
|
|
|
log->Children = (wLog **) calloc(log->ChildrenSize, sizeof(wLog *));
|
2014-05-29 23:23:15 +04:00
|
|
|
|
|
|
|
if (!log->Children)
|
|
|
|
return NULL;
|
2013-10-02 02:19:50 +04:00
|
|
|
|
|
|
|
log->Appender = NULL;
|
2013-10-09 06:35:14 +04:00
|
|
|
|
2014-05-29 23:23:15 +04:00
|
|
|
if (rootLogger)
|
|
|
|
{
|
2014-01-15 17:52:48 +04:00
|
|
|
log->Level = WLOG_LEVEL_INHERIT;
|
2014-05-29 23:23:15 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-10-25 16:41:01 +04:00
|
|
|
log->Level = WLOG_WARN;
|
2014-01-15 17:52:48 +04:00
|
|
|
nSize = GetEnvironmentVariableA("WLOG_LEVEL", NULL, 0);
|
2013-10-09 06:35:14 +04:00
|
|
|
|
2014-01-15 17:52:48 +04:00
|
|
|
if (nSize)
|
2013-10-09 06:35:14 +04:00
|
|
|
{
|
2014-01-15 17:52:48 +04:00
|
|
|
env = (LPSTR) malloc(nSize);
|
|
|
|
nSize = GetEnvironmentVariableA("WLOG_LEVEL", env, nSize);
|
2014-05-29 23:23:15 +04:00
|
|
|
iLevel = WLog_ParseLogLevel(env);
|
|
|
|
|
|
|
|
if (iLevel >= 0)
|
|
|
|
log->Level = (DWORD) iLevel;
|
|
|
|
|
|
|
|
free(env);
|
2013-10-09 06:35:14 +04:00
|
|
|
}
|
|
|
|
}
|
2014-05-29 23:23:15 +04:00
|
|
|
|
|
|
|
iLevel = WLog_GetFilterLogLevel(log);
|
|
|
|
|
|
|
|
if (iLevel >= 0)
|
|
|
|
log->Level = (DWORD) iLevel;
|
2013-09-16 00:48:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return log;
|
2013-09-15 23:46:02 +04:00
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
void WLog_Free(wLog *log)
|
2013-09-15 23:46:02 +04:00
|
|
|
{
|
2013-09-16 00:48:09 +04:00
|
|
|
if (log)
|
|
|
|
{
|
2013-09-16 20:05:08 +04:00
|
|
|
if (log->Appender)
|
|
|
|
{
|
|
|
|
WLog_Appender_Free(log, log->Appender);
|
|
|
|
log->Appender = NULL;
|
|
|
|
}
|
|
|
|
|
2013-09-16 00:48:09 +04:00
|
|
|
free(log->Name);
|
2013-10-02 00:08:26 +04:00
|
|
|
free(log->Names[0]);
|
|
|
|
free(log->Names);
|
2013-10-04 14:41:33 +04:00
|
|
|
free(log->Children);
|
2013-09-16 00:48:09 +04:00
|
|
|
free(log);
|
|
|
|
}
|
2013-09-15 23:46:02 +04:00
|
|
|
}
|
2013-10-02 02:19:50 +04:00
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
static wLog *g_RootLog = NULL;
|
2013-10-02 02:19:50 +04:00
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
wLog *WLog_GetRoot()
|
2013-10-02 02:19:50 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
char *env;
|
2013-10-09 06:35:14 +04:00
|
|
|
DWORD nSize;
|
|
|
|
DWORD logAppenderType;
|
|
|
|
|
2013-10-02 02:19:50 +04:00
|
|
|
if (!g_RootLog)
|
|
|
|
{
|
2014-05-29 23:23:15 +04:00
|
|
|
g_RootLog = WLog_New("", NULL);
|
2013-10-02 02:19:50 +04:00
|
|
|
g_RootLog->IsRoot = TRUE;
|
2014-05-29 23:23:15 +04:00
|
|
|
WLog_ParseFilters();
|
2013-10-09 06:35:14 +04:00
|
|
|
logAppenderType = WLOG_APPENDER_CONSOLE;
|
|
|
|
nSize = GetEnvironmentVariableA("WLOG_APPENDER", NULL, 0);
|
|
|
|
|
|
|
|
if (nSize)
|
|
|
|
{
|
|
|
|
env = (LPSTR) malloc(nSize);
|
|
|
|
nSize = GetEnvironmentVariableA("WLOG_APPENDER", env, nSize);
|
|
|
|
|
|
|
|
if (env)
|
|
|
|
{
|
|
|
|
if (_stricmp(env, "CONSOLE") == 0)
|
|
|
|
logAppenderType = WLOG_APPENDER_CONSOLE;
|
|
|
|
else if (_stricmp(env, "FILE") == 0)
|
|
|
|
logAppenderType = WLOG_APPENDER_FILE;
|
|
|
|
else if (_stricmp(env, "BINARY") == 0)
|
|
|
|
logAppenderType = WLOG_APPENDER_BINARY;
|
|
|
|
|
|
|
|
free(env);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WLog_SetLogAppenderType(g_RootLog, logAppenderType);
|
2013-10-02 02:19:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return g_RootLog;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
int WLog_AddChild(wLog *parent, wLog *child)
|
2013-10-02 02:19:50 +04:00
|
|
|
{
|
|
|
|
if (parent->ChildrenCount >= parent->ChildrenSize)
|
|
|
|
{
|
|
|
|
parent->ChildrenSize *= 2;
|
2014-08-18 19:11:40 +04:00
|
|
|
parent->Children = (wLog **) realloc(parent->Children, sizeof(wLog *) * parent->ChildrenSize);
|
2013-10-02 02:19:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
parent->Children[parent->ChildrenCount++] = child;
|
|
|
|
child->Parent = parent;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
wLog *WLog_FindChild(LPCSTR name)
|
2013-10-02 02:19:50 +04:00
|
|
|
{
|
2014-02-11 07:12:13 +04:00
|
|
|
DWORD index;
|
2014-08-18 19:11:40 +04:00
|
|
|
wLog *root;
|
|
|
|
wLog *child = NULL;
|
2013-10-02 02:19:50 +04:00
|
|
|
BOOL found = FALSE;
|
|
|
|
root = WLog_GetRoot();
|
|
|
|
|
|
|
|
for (index = 0; index < root->ChildrenCount; index++)
|
|
|
|
{
|
|
|
|
child = root->Children[index];
|
|
|
|
|
|
|
|
if (strcmp(child->Name, name) == 0)
|
|
|
|
{
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (found) ? child : NULL;
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
wLog *WLog_Get(LPCSTR name)
|
2013-10-02 02:19:50 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
wLog *log;
|
|
|
|
wLog *root;
|
2013-10-02 02:19:50 +04:00
|
|
|
root = WLog_GetRoot();
|
|
|
|
log = WLog_FindChild(name);
|
|
|
|
|
|
|
|
if (!log)
|
|
|
|
{
|
2013-10-25 16:41:01 +04:00
|
|
|
log = WLog_New(name,root);
|
2013-10-02 02:19:50 +04:00
|
|
|
WLog_AddChild(root, log);
|
|
|
|
}
|
|
|
|
|
|
|
|
return log;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WLog_Init()
|
|
|
|
{
|
2013-10-02 04:45:20 +04:00
|
|
|
WLog_GetRoot();
|
2013-10-02 02:19:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void WLog_Uninit()
|
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
wLog *root = WLog_GetRoot();
|
2014-04-11 13:07:50 +04:00
|
|
|
DWORD index;
|
2014-08-18 19:11:40 +04:00
|
|
|
wLog *child = NULL;
|
2014-04-11 13:07:50 +04:00
|
|
|
|
|
|
|
for (index = 0; index < root->ChildrenCount; index++)
|
|
|
|
{
|
|
|
|
child = root->Children[index];
|
|
|
|
WLog_Free(child);
|
|
|
|
}
|
|
|
|
|
2013-10-02 02:19:50 +04:00
|
|
|
WLog_Free(root);
|
|
|
|
g_RootLog = NULL;
|
|
|
|
}
|