source: libcf/trunk/src/cf_log.c@ 23

Last change on this file since 23 was 23, checked in by cheese, 11 years ago

#1 change local functions in source code to static functions and some comments

File size: 8.0 KB
Line 
1/**
2 * cf_log.c
3 */
4#ifdef _WIN32
5# define _USE_32BIT_TIME_T
6#endif
7
8#include "cf_log.h"
9#include "cf_file.h"
10#include "cf_thread.h"
11#include "cf_local.h"
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <stdarg.h>
17#include <time.h>
18
19#ifdef _WIN32
20# define snprintf _snprintf
21# include <Windows.h>
22#else // #ifdef _WIN32
23# include <sys/time.h>
24#endif // #ifdef _WIN32
25
26#define CHECK_INVALID_CTX(__ctx) \
27 if (__ctx == NULL) \
28 return CF_ERROR_LOG_INVALID_CTX
29
30#define LOCK_LOG_CTX(__ctx) \
31 CF_Mutex_Lock (&__ctx->mutex)
32
33#define UNLOCK_LOG_CTX(__ctx) \
34 CF_Mutex_Unlock (&__ctx->mutex)
35
36#define CF_LOG_BUFFER_DEFAULT_SIZE 128 * 1024
37
38typedef struct __cf_util_datetime__
39{
40 int year;
41 int month;
42 int day;
43 int week; /* SUN:0 ~ SAT:6 */
44
45 int hour;
46 int min;
47 int sec;
48 int usec;
49} S_CF_Log_DateTime, CF_Log_DateTime;
50
51typedef struct __cf_log_ctx__ {
52 char path[NAME_LENGTH + 1];
53 int fd;
54 char * buffer;
55 size_t size; /* entire size of buffer */
56 size_t length; /* data length in current */
57 CF_Mutex mutex;
58} S_CF_LOG_CTX, CF_LOG_CTX;
59
60typedef struct __cf_log_environment__ {
61 CF_Log_Ctx * ctxPool;
62 int ctxSize;
63} S_CF_LOG_ENVIRONMENT, CF_LOG_ENVIRONMENT;
64
65CF_LOG_ENVIRONMENT gLogEnvironment;
66
67#if defined(_WIN32) || defined(_WIN64)
68/* #if defined(_WIN32) || defined(_WIN64) {{{ */
69struct timezone
70{
71 int tz_minuteswest; /* minutes W of Greenwich */
72 int tz_dsttime; /* type of dst correction */
73};
74
75// Definition of a gettimeofday function
76int gettimeofday(struct timeval *tv, struct timezone *tz)
77{
78 // Define a structure to receive the current Windows filetime
79 FILETIME ft;
80
81 // Initialize the present time to 0 and the timezone to UTC
82 unsigned __int64 ui64 =0;
83 static int tzflag = 0;
84
85 if (NULL != tv)
86 {
87 GetSystemTimeAsFileTime(&ft);
88
89 ui64 = (((unsigned __int64) ft.dwHighDateTime << 32)
90 + (unsigned __int64) ft.dwLowDateTime);
91
92 if (ui64)
93 {
94 ui64 /= 10;
95 ui64 -= ((369 * 365 + 89) * (unsigned __int64) 86400) * 1000000;
96 }
97
98 // Finally change microseconds to seconds and place in the seconds value.
99 // The modulus picks up the microseconds.
100 tv->tv_sec = (long)(ui64 / 1000000UL);
101 tv->tv_usec = (long)(ui64 % 1000000UL);
102 }
103
104 if (NULL != tz)
105 {
106 if (!tzflag)
107 {
108 _tzset();
109 tzflag++;
110 }
111
112 // Adjust for the timezone west of Greenwich
113 tz->tz_minuteswest = _timezone / 60;
114 tz->tz_dsttime = _daylight;
115 }
116
117 return 0;
118}
119#endif // #if defined(_WIN32) || defined(_WIN64)
120/* }}} #if defined(_WIN32) || defined(_WIN64) */
121
122static int
123CF_Log_Local_GetTime (CF_Log_DateTime * dt)
124{
125 struct timeval timeVal;
126 struct tm * timeSt;
127
128 gettimeofday (&timeVal, NULL);
129 timeSt = localtime ((const time_t *)&timeVal.tv_sec);
130
131 dt->year = timeSt->tm_year + 1900;
132 dt->month = timeSt->tm_mon + 1;
133 dt->day = timeSt->tm_mday;
134 dt->week = timeSt->tm_wday;
135
136 dt->hour = timeSt->tm_hour;
137 dt->min = timeSt->tm_min;
138 dt->sec = timeSt->tm_sec;
139
140 dt->usec = (int) timeVal.tv_usec;
141
142 return CF_OK;
143}
144
145static int
146CF_Log_Local_GetTimeString (char * buffer)
147{
148 CF_Log_DateTime dt;
149 CF_Log_Local_GetTime (&dt);
150
151
152
153 snprintf (buffer, strlen ("0000-00-00 00:00:00.000"),
154 "%02d-%02d-%02d %02d:%02d:%02d.%03d",
155 dt.year, dt.month, dt.day,
156 dt.hour, dt.min, dt.sec, dt.usec);
157
158 return CF_OK;
159}
160
161static int
162CF_Log_Local_Push (CF_LOG_CTX * ctx,
163 const char * buffer)
164{
165 strncat (ctx->buffer + ctx->length,
166 buffer,
167 ctx->size - ctx->length);
168 ctx->length = strlen (ctx->buffer);
169
170 return CF_OK;
171}
172
173static int
174CF_Log_Local_Flush (CF_LOG_CTX * ctx)
175{
176 if (CF_File_Write (ctx->fd, ctx->buffer, ctx->length) < 0)
177 return CF_ERROR_LOG_FLUSH;
178
179 memset (ctx->buffer, 0x00, ctx->size);
180 ctx->length = 0;
181
182 return CF_OK;
183}
184
185int
186CF_Log_Initialize (const int logPool)
187{
188 memset (&gLogEnvironment, 0x00, sizeof (CF_LOG_ENVIRONMENT));
189
190 if (logPool > 0)
191 {
192 gLogEnvironment.ctxPool =
193 (CF_Log_Ctx *) calloc ((size_t) logPool, sizeof (CF_Log_Ctx));
194 gLogEnvironment.ctxSize = logPool;
195 }
196
197 return CF_OK;
198}
199
200int
201CF_Log_Finalize (void)
202{
203 int mapid = 0;
204
205 for (mapid = 0 ; mapid < gLogEnvironment.ctxSize ; mapid++)
206 {
207 CF_Log_UnmapCtxID (mapid);
208 }
209
210 if (gLogEnvironment.ctxPool != NULL)
211 free (gLogEnvironment.ctxPool);
212
213 memset (&gLogEnvironment, 0x00, sizeof (CF_LOG_ENVIRONMENT));
214
215 return CF_OK;
216}
217
218CF_Log_Ctx
219CF_Log_CreateCtx (const char * path,
220 const int memsize)
221{
222 int result = 0;
223 int size = (memsize == CF_LOG_BUFFER_DEFAULT)
224 ? CF_LOG_BUFFER_DEFAULT_SIZE
225 : memsize;
226 CF_LOG_CTX * context = NULL;
227
228 if (path == NULL)
229 return NULL;
230
231 TRY
232 {
233 context = (CF_LOG_CTX *) calloc (sizeof (CF_LOG_CTX), 1);
234 if (context == NULL)
235 {
236 result = -1;
237 TRY_BREAK;
238 }
239
240 context->fd = CF_File_Create (path);
241 if (context->fd < 0)
242 {
243 result = -2;
244 TRY_BREAK;
245 }
246 sprintf (context->path, "%s", path);
247
248 if (size > 0)
249 {
250 context->buffer = (char *) calloc ((size_t) size + 1, 1);
251 if (context->buffer == NULL)
252 {
253 result = -3;
254 TRY_BREAK;
255 }
256 context->size = (size_t) size;
257 }
258 }
259 CATCH_IF (result < 0)
260 {
261 CF_Log_DestroyCtx ((CF_Log_Ctx) context);
262 return NULL;
263 }
264
265 return (CF_Log_Ctx) context;
266}
267
268int
269CF_Log_DestroyCtx (CF_Log_Ctx ctx)
270{
271 CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
272
273 CHECK_INVALID_CTX (ctx);
274
275 memset (context->path, 0x00, sizeof (context->path));
276
277 if (context->buffer != NULL)
278 {
279 CF_Log_Flush (ctx);
280 free (context->buffer);
281 context->buffer = NULL;
282 context->size = 0;
283 }
284
285 CF_File_Close (context->fd);
286
287 if (context->mutex != NULL)
288 {
289 if (CF_Mutex_Destory (&context->mutex) < 0)
290 /* do something ? */;
291
292 context->mutex = NULL;
293 }
294
295 return CF_OK;
296}
297
298int
299CF_Log_SetMultiThread (CF_Log_Ctx ctx)
300{
301 CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
302
303 CHECK_INVALID_CTX (ctx);
304
305 if (CF_Mutex_Create (&context->mutex) < 0)
306 return CF_ERROR_LOG_SET_MULTITHREAD;
307
308 return CF_OK;
309}
310
311int
312CF_Log_UnsetMultiThread (CF_Log_Ctx ctx)
313{
314 CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
315
316 CHECK_INVALID_CTX (ctx);
317
318 if (CF_Mutex_Destory (&context->mutex) < 0)
319 return CF_ERROR_LOG_UNSET_MULTITHREAD;
320
321 return CF_OK;
322}
323
324int
325CF_Log_Write (CF_Log_Ctx ctx,
326 const char * prefix,
327 const char * fmt, ...)
328{
329 CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
330 va_list valist;
331 char buffer[4096] = {0x00,};
332 size_t length = 0;
333
334 CHECK_INVALID_CTX (ctx);
335
336 LOCK_LOG_CTX (context);
337 va_start (valist, fmt);
338
339 strncat (buffer, "[", 1);
340 CF_Log_Local_GetTimeString (buffer + strlen (buffer));
341 sprintf (buffer + strlen (buffer), "][%s] ", prefix);
342 vsprintf (buffer + strlen (buffer), fmt, valist);
343
344 if (context->size == CF_LOG_BUFFER_NO)
345 {
346 context->buffer = buffer;
347 context->length = strlen (buffer);
348
349 CF_Log_Local_Flush (context);
350
351 context->buffer = NULL;
352 /* context->length = 0; // already did this in flush */
353 }
354 else /* (context->size > 0) */
355 {
356 length = context->size - context->length;
357 CF_Log_Local_Push (context, buffer);
358
359 if (context->length == context->size)
360 {
361 CF_Log_Local_Flush (context);
362 CF_Log_Local_Push (context, buffer + length);
363 }
364 }
365
366 va_end (valist);
367 UNLOCK_LOG_CTX (context);
368
369 return CF_OK;
370}
371
372int
373CF_Log_Flush (CF_Log_Ctx ctx)
374{
375 CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
376
377 CHECK_INVALID_CTX (ctx);
378
379 LOCK_LOG_CTX (context);
380 CF_Log_Local_Flush (context);
381 UNLOCK_LOG_CTX (context);
382
383 return CF_OK;
384}
385
386int
387CF_Log_MapCtxID (const int mapid,
388 const CF_Log_Ctx ctx)
389{
390 if (gLogEnvironment.ctxPool == NULL || gLogEnvironment.ctxSize <= 0)
391 return CF_ERROR_LOG_NOT_INITIALIZE;
392
393 if (gLogEnvironment.ctxPool[mapid] != NULL)
394 return CF_ERROR_LOG_ALREADY_MAPPED_ID;
395
396 gLogEnvironment.ctxPool[mapid] = ctx;
397
398 return CF_OK;
399}
400
401int
402CF_Log_UnmapCtxID (const int mapid)
403{
404 if (gLogEnvironment.ctxPool == NULL || gLogEnvironment.ctxSize <= 0)
405 return CF_ERROR_LOG_NOT_INITIALIZE;
406
407 if (gLogEnvironment.ctxPool[mapid] == NULL)
408 return CF_ERROR_LOG_NOT_MAPPED_ID;
409
410 CF_Log_DestroyCtx (gLogEnvironment.ctxPool[mapid]);
411
412 free (gLogEnvironment.ctxPool[mapid]);
413 gLogEnvironment.ctxPool[mapid] = NULL;
414
415 return CF_OK;
416}
417
418CF_Log_Ctx
419CF_Log_GetMappedCtx (const int mapid)
420{
421 if (gLogEnvironment.ctxPool == NULL || gLogEnvironment.ctxSize <= 0)
422 return NULL;
423
424 return gLogEnvironment.ctxPool[mapid];
425}
Note: See TracBrowser for help on using the repository browser.