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

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

#1 remove getting disk block size using stat and fix windows project and compile error

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