Changeset 12 in libcf for trunk/src/cf_log.c


Ignore:
Timestamp:
01/31/13 14:40:55 (11 years ago)
Author:
cheese
Message:

#1 implement logging module

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/cf_log.c

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