(file) Return to log.c CVS log (file) (dir) Up to [OMI] / omi / base

  1 mike  1.1 /*
  2           **==============================================================================
  3           **
  4           ** Open Management Infrastructure (OMI)
  5           **
  6           ** Copyright (c) Microsoft Corporation
  7           ** 
  8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  9           ** use this file except in compliance with the License. You may obtain a copy 
 10           ** of the License at 
 11           **
 12           **     http://www.apache.org/licenses/LICENSE-2.0 
 13           **
 14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
 16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
 17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
 18           **
 19           ** See the Apache 2 License for the specific language governing permissions 
 20           ** and limitations under the License.
 21           **
 22 mike  1.1 **==============================================================================
 23           */
 24           
 25           #include "log.h"
 26           
 27           #if defined(CONFIG_OS_WINDOWS)
 28           # include <windows.h>
 29           # include <time.h>
 30           #else
 31           # include <unistd.h>
 32           # include <sys/time.h>
 33           # include <sys/types.h>
 34           # include <time.h>
 35           #endif
 36           
 37           #include "strings.h"
 38           #include "io.h"
 39           
 40           /*
 41           **==============================================================================
 42           **
 43 mike  1.1 ** Local definitions:
 44           **
 45           **==============================================================================
 46           */
 47           
 48           static FILE* _os;
 49           
 50           static const char* _levelStrings[] =
 51           {
 52               "FATAL",
 53               "ERROR",
 54               "WARNING",
 55               "INFO",
 56               "DEBUG",
 57           };
 58           
 59           static Log_Level _level = LOG_WARNING;
 60           static Log_Level _currentLevel = LOG_WARNING;
 61           
 62           static int _GetCurrentTimeInUsec(MI_Uint64* usec)
 63           {
 64 mike  1.1 #if defined(CONFIG_OS_WINDOWS)
 65               FILETIME ft;
 66               ULARGE_INTEGER tmp;
 67           
 68               GetSystemTimeAsFileTime(&ft);
 69               tmp.u.LowPart = ft.dwLowDateTime;
 70               tmp.u.HighPart = ft.dwHighDateTime;
 71               tmp.QuadPart -= 0X19DB1DED53E8000;
 72               *usec = tmp.QuadPart / (UINT64)10;
 73           
 74               return 0;
 75           #else
 76               struct timeval tv;
 77               struct timezone tz;
 78               memset(&tv, 0, sizeof(tv));
 79               memset(&tz, 0, sizeof(tz));
 80           
 81               if (gettimeofday(&tv, &tz) != 0)
 82                   return -1;
 83           
 84               *usec = (MI_Uint64)tv.tv_sec * (MI_Uint64)1000000 + (MI_Uint64)tv.tv_usec;
 85 mike  1.1     return 0;
 86           #endif
 87           }
 88           
 89           #define TIMESTAMP_SIZE 128
 90           
 91           static int _GetTimeStamp(char buf[TIMESTAMP_SIZE])
 92           {
 93               MI_Uint64 usec;
 94           
 95               if (_GetCurrentTimeInUsec(&usec) != 0)
 96               {
 97                   buf[0] = '\0';
 98                   return -1;
 99               }
100           
101           #if defined(CONFIG_OS_WINDOWS)
102               {
103                   time_t t = usec / 1000000;
104                   struct tm tm;
105                   localtime_s(&tm, &t);
106 mike  1.1         sprintf_s(
107                       buf,
108                       TIMESTAMP_SIZE,
109                       "%02u/%02u/%02u %02u:%02u:%02u",
110                       tm.tm_year + 1900,
111                       tm.tm_mon + 1,
112                       tm.tm_mday,
113                       tm.tm_hour,
114                       tm.tm_min,
115                       tm.tm_sec);
116               }
117           #else
118               {
119                   time_t t = usec / 1000000;
120                   struct tm tm;
121                   localtime_r(&t, &tm);
122                   sprintf(
123                       buf,
124                       "%02u/%02u/%02u %02u:%02u:%02u",
125                       tm.tm_year + 1900,
126                       tm.tm_mon + 1,
127 mike  1.1             tm.tm_mday,
128                       tm.tm_hour,
129                       tm.tm_min,
130                       tm.tm_sec);
131               }
132           #endif
133           
134               return 0;
135           }
136           
137           #if (MI_CHAR_TYPE == 2)
138           static char* _StrdupWcharToASCII7(const MI_Char* str)
139           {
140               char* p;
141               
142               /* Allocate room for string */
143               p = (char*)malloc(Wcslen(str) + 1);
144           
145               if (!p)
146                   return NULL;
147           
148 mike  1.1     /* Copy string while failing on non-ASCII characters */
149               while (*str)
150               {
151                   if ((MI_Uint32)*str >= 128)
152                   {
153                       free(p);
154                       return NULL;
155                   }
156                   *p++ = (char)*str++;
157               }
158           
159               return p;
160           }
161           #endif
162           
163           static void _PutHeader(
164               FILE* os, 
165               const char* file, 
166               unsigned int line, 
167               Log_Level level)
168           {
169 mike  1.1     char buf[TIMESTAMP_SIZE];
170           
171               _GetTimeStamp(buf);
172               fprintf(os, "%s: ", buf);
173               fprintf(os, "%s: ", _levelStrings[(int)level]);
174               fprintf(os, "%s(%u): ", file, line);
175           }
176           
177           /*
178           **==============================================================================
179           **
180           ** Public definitions:
181           **
182           **==============================================================================
183           */
184           
185           MI_Result Log_Open(
186               const MI_Char* path)
187           {
188               if (!path || _os)
189                   return MI_RESULT_FAILED;
190 mike  1.1 
191           #if defined(CONFIG_OS_WINDOWS)
192           # if (MI_CHAR_TYPE == 1)
193               {
194                   if (fopen_s(&_os, path, "a") != 0)
195                       return MI_RESULT_FAILED;
196           
197                   return MI_RESULT_OK;
198               }
199           # else
200               {
201                   if (_wfopen_s(&_os, path, L"a") != 0)
202                       return MI_RESULT_FAILED;
203           
204                   return MI_RESULT_OK;
205               }
206           # endif
207           #else
208           # if (MI_CHAR_TYPE == 1)
209               {
210                   _os = fopen(path, "a");
211 mike  1.1         if (!_os)
212                       return MI_RESULT_FAILED;
213           
214                   return MI_RESULT_OK;
215               }
216           # else
217               {
218                   char* path7 = _StrdupWcharToASCII7(path);
219           
220                   if (!path7)
221                       return MI_RESULT_FAILED;
222                   
223                   _os = fopen(path7, _os, "a");
224           
225                   if (!_os)
226                   {
227                       free(path7);
228                       return MI_RESULT_FAILED;
229                   }
230           
231                   free(path7);
232 mike  1.1         return MI_RESULT_OK;
233               }
234           # endif
235           #endif
236           }
237           
238           MI_Result Log_OpenFD(
239               int fd)
240           {
241           #if defined(CONFIG_OS_WINDOWS)
242               MI_UNUSED(fd);
243               return MI_RESULT_FAILED;
244           #else
245               if (fd < 0 || _os)
246                   return MI_RESULT_FAILED;
247           
248               _os = fdopen(fd, "a");
249               if (!_os)
250                   return MI_RESULT_FAILED;
251           
252               return MI_RESULT_OK;
253 mike  1.1 
254           #endif
255           }
256           
257           MI_Result Log_OpenStdErr()
258           {
259               _os = stderr;
260               return MI_RESULT_OK;
261           }
262           
263           void Log_Close()
264           {
265               if (_os && _os != stderr)
266               {
267                   fclose(_os);
268                   _os = NULL;
269               }
270           }
271           
272           void Log_SetLevel(
273               Log_Level level)
274 mike  1.1 {
275               _level = level;
276           }
277           
278           Log_Level Log_GetLevel()
279           {
280               return _level;
281           }
282           
283           int Log_SetLevelFromString(const char* level)
284           {
285               size_t i;
286           
287               for (i = 0; i < sizeof(_levelStrings) / sizeof(_levelStrings[0]); i++)
288               {
289                   char buf[32];
290           
291                   Snprintf(buf, sizeof(buf), "%u", (int)i);
292           
293                   if (Strcasecmp(level, _levelStrings[i]) == 0 || 
294                       Strcasecmp(level, buf) == 0)
295 mike  1.1         {
296                       _level = (Log_Level)i;
297                       return 0;
298                   }
299               }
300           
301               return -1;
302           }
303           
304           const char* Log_GetLevelString(Log_Level level)
305           {
306               return _levelStrings[(int)level];
307           }
308           
309           int Log_Put(
310               Log_Level level,
311               const char* file,
312               MI_Uint32 line,
313               const MI_Char* format,
314               ...)
315           {
316 mike  1.1     va_list ap;
317               memset(&ap, 0, sizeof(ap));
318           
319               if (!_os || level > _level)
320                   return 0;
321           
322               _PutHeader(_os, file, line, level);
323               va_start(ap, format);
324           #if (MI_CHAR_TYPE == 1)
325               vfprintf(_os, format, ap);
326           #else
327               vfwprintf(_os, format, ap);
328           #endif
329               va_end(ap);
330               fputc('\n', _os);
331           
332               return 1;
333           }
334           
335           int Log_VPut(
336               Log_Level level,
337 mike  1.1     const char* file,
338               MI_Uint32 line,
339               const MI_Char* format,
340               va_list ap)
341           {
342               if (!_os || level > _level)
343                   return 0;
344           
345               _PutHeader(_os, file, line, level);
346           #if (MI_CHAR_TYPE == 1)
347               vfprintf(_os, format, ap);
348           #else
349               vfwprintf(_os, format, ap);
350           #endif
351               fputc('\n', _os);
352           
353               return 1;
354           }
355           
356           int __Log_Put1(
357               Log_Level level,
358 mike  1.1     const char* file,
359               MI_Uint32 line)
360           {
361               if (!_os || level > _level)
362                   return 0;
363           
364               _currentLevel = level;
365               _PutHeader(_os, file, line, level);
366           
367               return 1;
368           }
369           
370           void __Log_Put2(
371               const MI_Char* format,
372               ...)
373           {
374               va_list ap;
375               memset(&ap, 0, sizeof(ap));
376           
377               if (!_os || _currentLevel > _level)
378                   return;
379 mike  1.1 
380               va_start(ap, format);
381           #if (MI_CHAR_TYPE == 1)
382               vfprintf(_os, format, ap);
383           #else
384               vfwprintf(_os, format, ap);
385           #endif
386               fputc('\n', _os);
387               fflush(_os);
388           }
389           
390           void __Log_Put2_char(
391               const char* format,
392               ...)
393           {
394               va_list ap;
395               memset(&ap, 0, sizeof(ap));
396           
397               if (!_os || _currentLevel > _level)
398                   return;
399           
400 mike  1.1     va_start(ap, format);
401               vfprintf(_os, format, ap);
402               fputc('\n', _os);
403               fflush(_os);
404           }

ViewCVS 0.9.2