File: [OMI] / omi / base / log.c
(download)
Revision: 1.1,
Wed May 30 21:47:49 2012 UTC (12 years ago) by mike
Branch: MAIN
Initial revision
|
/*
**==============================================================================
**
** Open Management Infrastructure (OMI)
**
** Copyright (c) Microsoft Corporation
**
** 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
**
** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABLITY OR NON-INFRINGEMENT.
**
** See the Apache 2 License for the specific language governing permissions
** and limitations under the License.
**
**==============================================================================
*/
#include "log.h"
#if defined(CONFIG_OS_WINDOWS)
# include <windows.h>
# include <time.h>
#else
# include <unistd.h>
# include <sys/time.h>
# include <sys/types.h>
# include <time.h>
#endif
#include "strings.h"
#include "io.h"
/*
**==============================================================================
**
** Local definitions:
**
**==============================================================================
*/
static FILE* _os;
static const char* _levelStrings[] =
{
"FATAL",
"ERROR",
"WARNING",
"INFO",
"DEBUG",
};
static Log_Level _level = LOG_WARNING;
static Log_Level _currentLevel = LOG_WARNING;
static int _GetCurrentTimeInUsec(MI_Uint64* usec)
{
#if defined(CONFIG_OS_WINDOWS)
FILETIME ft;
ULARGE_INTEGER tmp;
GetSystemTimeAsFileTime(&ft);
tmp.u.LowPart = ft.dwLowDateTime;
tmp.u.HighPart = ft.dwHighDateTime;
tmp.QuadPart -= 0X19DB1DED53E8000;
*usec = tmp.QuadPart / (UINT64)10;
return 0;
#else
struct timeval tv;
struct timezone tz;
memset(&tv, 0, sizeof(tv));
memset(&tz, 0, sizeof(tz));
if (gettimeofday(&tv, &tz) != 0)
return -1;
*usec = (MI_Uint64)tv.tv_sec * (MI_Uint64)1000000 + (MI_Uint64)tv.tv_usec;
return 0;
#endif
}
#define TIMESTAMP_SIZE 128
static int _GetTimeStamp(char buf[TIMESTAMP_SIZE])
{
MI_Uint64 usec;
if (_GetCurrentTimeInUsec(&usec) != 0)
{
buf[0] = '\0';
return -1;
}
#if defined(CONFIG_OS_WINDOWS)
{
time_t t = usec / 1000000;
struct tm tm;
localtime_s(&tm, &t);
sprintf_s(
buf,
TIMESTAMP_SIZE,
"%02u/%02u/%02u %02u:%02u:%02u",
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec);
}
#else
{
time_t t = usec / 1000000;
struct tm tm;
localtime_r(&t, &tm);
sprintf(
buf,
"%02u/%02u/%02u %02u:%02u:%02u",
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec);
}
#endif
return 0;
}
#if (MI_CHAR_TYPE == 2)
static char* _StrdupWcharToASCII7(const MI_Char* str)
{
char* p;
/* Allocate room for string */
p = (char*)malloc(Wcslen(str) + 1);
if (!p)
return NULL;
/* Copy string while failing on non-ASCII characters */
while (*str)
{
if ((MI_Uint32)*str >= 128)
{
free(p);
return NULL;
}
*p++ = (char)*str++;
}
return p;
}
#endif
static void _PutHeader(
FILE* os,
const char* file,
unsigned int line,
Log_Level level)
{
char buf[TIMESTAMP_SIZE];
_GetTimeStamp(buf);
fprintf(os, "%s: ", buf);
fprintf(os, "%s: ", _levelStrings[(int)level]);
fprintf(os, "%s(%u): ", file, line);
}
/*
**==============================================================================
**
** Public definitions:
**
**==============================================================================
*/
MI_Result Log_Open(
const MI_Char* path)
{
if (!path || _os)
return MI_RESULT_FAILED;
#if defined(CONFIG_OS_WINDOWS)
# if (MI_CHAR_TYPE == 1)
{
if (fopen_s(&_os, path, "a") != 0)
return MI_RESULT_FAILED;
return MI_RESULT_OK;
}
# else
{
if (_wfopen_s(&_os, path, L"a") != 0)
return MI_RESULT_FAILED;
return MI_RESULT_OK;
}
# endif
#else
# if (MI_CHAR_TYPE == 1)
{
_os = fopen(path, "a");
if (!_os)
return MI_RESULT_FAILED;
return MI_RESULT_OK;
}
# else
{
char* path7 = _StrdupWcharToASCII7(path);
if (!path7)
return MI_RESULT_FAILED;
_os = fopen(path7, _os, "a");
if (!_os)
{
free(path7);
return MI_RESULT_FAILED;
}
free(path7);
return MI_RESULT_OK;
}
# endif
#endif
}
MI_Result Log_OpenFD(
int fd)
{
#if defined(CONFIG_OS_WINDOWS)
MI_UNUSED(fd);
return MI_RESULT_FAILED;
#else
if (fd < 0 || _os)
return MI_RESULT_FAILED;
_os = fdopen(fd, "a");
if (!_os)
return MI_RESULT_FAILED;
return MI_RESULT_OK;
#endif
}
MI_Result Log_OpenStdErr()
{
_os = stderr;
return MI_RESULT_OK;
}
void Log_Close()
{
if (_os && _os != stderr)
{
fclose(_os);
_os = NULL;
}
}
void Log_SetLevel(
Log_Level level)
{
_level = level;
}
Log_Level Log_GetLevel()
{
return _level;
}
int Log_SetLevelFromString(const char* level)
{
size_t i;
for (i = 0; i < sizeof(_levelStrings) / sizeof(_levelStrings[0]); i++)
{
char buf[32];
Snprintf(buf, sizeof(buf), "%u", (int)i);
if (Strcasecmp(level, _levelStrings[i]) == 0 ||
Strcasecmp(level, buf) == 0)
{
_level = (Log_Level)i;
return 0;
}
}
return -1;
}
const char* Log_GetLevelString(Log_Level level)
{
return _levelStrings[(int)level];
}
int Log_Put(
Log_Level level,
const char* file,
MI_Uint32 line,
const MI_Char* format,
...)
{
va_list ap;
memset(&ap, 0, sizeof(ap));
if (!_os || level > _level)
return 0;
_PutHeader(_os, file, line, level);
va_start(ap, format);
#if (MI_CHAR_TYPE == 1)
vfprintf(_os, format, ap);
#else
vfwprintf(_os, format, ap);
#endif
va_end(ap);
fputc('\n', _os);
return 1;
}
int Log_VPut(
Log_Level level,
const char* file,
MI_Uint32 line,
const MI_Char* format,
va_list ap)
{
if (!_os || level > _level)
return 0;
_PutHeader(_os, file, line, level);
#if (MI_CHAR_TYPE == 1)
vfprintf(_os, format, ap);
#else
vfwprintf(_os, format, ap);
#endif
fputc('\n', _os);
return 1;
}
int __Log_Put1(
Log_Level level,
const char* file,
MI_Uint32 line)
{
if (!_os || level > _level)
return 0;
_currentLevel = level;
_PutHeader(_os, file, line, level);
return 1;
}
void __Log_Put2(
const MI_Char* format,
...)
{
va_list ap;
memset(&ap, 0, sizeof(ap));
if (!_os || _currentLevel > _level)
return;
va_start(ap, format);
#if (MI_CHAR_TYPE == 1)
vfprintf(_os, format, ap);
#else
vfwprintf(_os, format, ap);
#endif
fputc('\n', _os);
fflush(_os);
}
void __Log_Put2_char(
const char* format,
...)
{
va_list ap;
memset(&ap, 0, sizeof(ap));
if (!_os || _currentLevel > _level)
return;
va_start(ap, format);
vfprintf(_os, format, ap);
fputc('\n', _os);
fflush(_os);
}