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


Ignore:
Timestamp:
10/31/13 10:17:24 (11 years ago)
Author:
cheese
Message:

#1 fix interface and add util module

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/cf_log.c

    r149 r151  
    1919#include "cf_local.h"
    2020#include "cf_error.h"
     21#include "cf_util.h"
    2122
    2223#include <stdio.h>
     
    2930# include <Windows.h>
    3031#else
    31 # include <sys/time.h>
    3232#endif
     33
     34#define LOG_BUFFER_DEFAULT_SIZE         128 * 1024
    3335
    3436#define ASSERT_CTX(__ctx)   \
     
    3638        return CF_ERROR_LOG_INVALID_CTX
    3739
    38 #define ASSERT_INIT()                   \
    39     if (gLogPool.ctxPool == NULL    ||  \
    40         gLogPool.poolSize <= 0      )   \
    41         return CF_ERROR_LOG_NOT_INITIALIZE
    42 
    43 #define ASSERT_MAPID(__mapid)           \
    44     if (gLogPool.poolSize <= __mapid)   \
    45         return CF_ERROR_LOG_INVALID_MAPID
    46 
    47 #define ASSERT_MAPPED_CTX(__mapid)          \
    48     if (gLogPool.ctxPool[__mapid] != NULL)  \
    49         return CF_ERROR_LOG_ALREADY_MAPPED_ID
    50 
    51 #define ASSERT_NOT_MAPPED_CTX(__mapid)      \
    52     if (gLogPool.ctxPool[__mapid] == NULL)  \
    53         return CF_ERROR_LOG_NOT_MAPPED_ID
    54 
    55 #define LOG_BUFFER_DEFAULT_SIZE         128 * 1024
    56 
    57 #define LOG_DATETIME_LENGTH             sizeof ("0000-00-00 00:00:00.000") - 1
    58 
    59 /** 로그 컨텍스트 (Opaque) */
    60 typedef void *  CF_Log_Ctx;
    61 
    62 typedef struct __cf_util_datetime__
    63 {
    64     int year;
    65     int month;
    66     int day;
    67     int week; /* SUN:0 ~ SAT:6 */
    68 
    69     int hour;
    70     int min;
    71     int sec;
    72     int usec;
    73 } CF_LOG_DATETIME;
    74 
    75 /** 로그 컨텍스트 (CF_Log_Ctx의 구현) */
     40#define ASSERT_ARGS(x)  \
     41    if ((x))            \
     42        return CF_ERROR_LOG_INVALID_ARGS
     43
     44/** 로그 컨텍스트 (cf_ctx의 구현) */
    7645typedef struct __cf_log_ctx__
    7746{
    7847    char            path[NAME_LENGTH + 1];
    79     int             fd;
     48    cf_ctx          file;
    8049    char            * buffer;
    8150    size_t          size;   /* entire size of buffer */
    8251    size_t          length; /* data length in current */
    83     CF_Mutex_Ctx    mutex;
     52    cf_ctx  mutex;
    8453} CF_LOG_CONTEXT;
    85 
    86 typedef struct __cf_log_array__
    87 {
    88     CF_Log_Ctx  * ctxPool;
    89     int         poolSize;
    90 } CF_LOG_POOL;
    91 
    92 static CF_LOG_POOL  gLogPool;
    93 
    94 #if defined(_WIN32) || defined(_WIN64)
    95 /* {{{ */
    96 struct timezone
    97 {
    98     int tz_minuteswest; /* minutes W of Greenwich */
    99     int tz_dsttime;     /* type of dst correction */
    100 };
    101 
    102 int gettimeofday (struct timeval *tv, struct timezone *tz)
    103 {
    104     FILETIME            ft;
    105     unsigned __int64    buf =0;
    106     //static int tzflag = 0;
    107 
    108     if (NULL != tv)
    109     {
    110         GetSystemTimeAsFileTime (&ft);
    111 
    112         buf |=  ft.dwHighDateTime;
    113         buf <<= 32;
    114         buf |=  ft.dwLowDateTime;
    115 
    116         if (buf)
    117         {
    118             buf /= 10;
    119             buf -= ((369 * 365 + 89) * (unsigned __int64) 86400) * 1000000;
    120         }
    121 
    122         tv->tv_sec = (long)(buf / 1000000UL);
    123         tv->tv_usec = (long)(buf % 1000000UL);
    124     }
    125 
    126     /*
    127     if (NULL != tz)
    128     {
    129         if (!tzflag)
    130         {
    131             _tzset();
    132             tzflag++;
    133         }
    134 
    135         // Adjust for the timezone west of Greenwich
    136         tz->tz_minuteswest = _timezone / 60;
    137         tz->tz_dsttime = _daylight;
    138     }
    139     */
    140 
    141     return 0;
    142 }
    143 /* }}} */
    144 #endif
    145 
    146 static int
    147 CF_Log_Local_GetTime (CF_LOG_DATETIME * dt)
    148 {
    149     struct timeval  timeVal;
    150     struct tm       * timeSt;
    151 
    152     gettimeofday (&timeVal, NULL);
    153     timeSt = localtime ((const time_t *)&timeVal.tv_sec);
    154 
    155     dt->year    = timeSt->tm_year + 1900;
    156     dt->month   = timeSt->tm_mon + 1;
    157     dt->day     = timeSt->tm_mday;
    158     dt->week    = timeSt->tm_wday;
    159 
    160     dt->hour    = timeSt->tm_hour;
    161     dt->min     = timeSt->tm_min;
    162     dt->sec     = timeSt->tm_sec;
    163 
    164     dt->usec    = (int) timeVal.tv_usec;
    165 
    166     return CF_OK;
    167 }
    168 
    169 static int
    170 CF_Log_Local_GetTimeString (char * buffer)
    171 {
    172     CF_LOG_DATETIME dt;
    173     CF_Log_Local_GetTime (&dt);
    174 
    175     snprintf (buffer, LOG_DATETIME_LENGTH,
    176               "%04d-%02d-%02d %02d:%02d:%02d.%03d",
    177               dt.year, dt.month, dt.day,
    178               dt.hour, dt.min, dt.sec, dt.usec);
    179 
    180     return CF_OK;
    181 }
    18254
    18355static int
    18456CF_Log_Local_Flush (CF_LOG_CONTEXT * ctx)
    18557{
    186     if (CF_File_Write (ctx->fd, ctx->buffer, ctx->length) < 0)
     58    if (CF_File_Write (ctx->file, ctx->buffer, ctx->length) < 0)
    18759        return CF_ERROR_LOG_FLUSH;
    18860
     
    20880                   const size_t     demandSize)
    20981{
    210     int result = CF_OK;
     82    int result = 0;
     83
     84    size_t writeSize;
     85    size_t remainSize;
    21186
    21287    if (ctx->size > 0) /* 버퍼단위 버퍼링.... */
    21388    {
    214         size_t writeSize;
    215         size_t remainSize;
    216 
    21789        remainSize = demandSize;
    21890        while (remainSize)
    21991        {
    220             writeSize = (ctx->size - ctx->length) < remainSize ? (ctx->size - ctx->length) : remainSize;
    221 
    222             memcpy (ctx->buffer + ctx->length, buffer + demandSize - remainSize, writeSize);
     92            writeSize = (ctx->size - ctx->length) < remainSize
     93                      ? (ctx->size - ctx->length)
     94                      : remainSize;
     95
     96            memcpy (ctx->buffer + ctx->length,
     97                    buffer + demandSize - remainSize,
     98                    writeSize);
    22399            ctx->length += writeSize;
    224100
     
    247123 * \param ctx 로그 컨텍스트
    248124 */
    249 static int
    250 CF_Log_SetMultiThread (CF_Log_Ctx ctx)
    251 {
    252     CF_LOG_CONTEXT * context = (CF_LOG_CONTEXT *) ctx;
    253 
    254     ASSERT_CTX (ctx);
    255 
    256     if (CF_Mutex_CreateCtx (&context->mutex) < 0)
     125int
     126CF_Log_SetMultiThread (cf_ctx ctx)
     127{
     128    CF_LOG_CONTEXT * context = (CF_LOG_CONTEXT *) ctx;
     129
     130    ASSERT_CTX (ctx);
     131
     132    if (CF_Mutex_Create (&context->mutex) < 0)
    257133        return CF_ERROR_LOG_SET_MULTITHREAD;
    258134
     
    267143 * \param ctx 로그 컨텍스트
    268144 */
    269 static int
    270 CF_Log_UnsetMultiThread (CF_Log_Ctx ctx)
    271 {
    272     CF_LOG_CONTEXT * context = (CF_LOG_CONTEXT *) ctx;
    273 
    274     ASSERT_CTX (ctx);
    275 
    276     if (CF_Mutex_DestoryCtx (context->mutex) < 0)
     145int
     146CF_Log_UnsetMultiThread (cf_ctx ctx)
     147{
     148    CF_LOG_CONTEXT * context = (CF_LOG_CONTEXT *) ctx;
     149
     150    ASSERT_CTX (ctx);
     151
     152    if (CF_Mutex_Destory (context->mutex) < 0)
    277153        return CF_ERROR_LOG_UNSET_MULTITHREAD;
    278154
     
    293169 */
    294170static int
    295 CF_Log_Local_WriteVA (CF_Log_Ctx    ctx,
    296                       const char    * prefix,
    297                       const char    * fmt,
    298                       va_list       valist)
     171CF_Log_Local_WriteVA (CF_LOG_CONTEXT    * context,
     172                      const char        * prefix,
     173                      const char        * fmt,
     174                      va_list           valist)
    299175{
    300176#define BUF_LEN 16 * 1024
    301     CF_LOG_CONTEXT  * context = (CF_LOG_CONTEXT *) ctx;
    302     char        buffer[BUF_LEN + 1] = {0x00,};
    303     char        datetime[LOG_DATETIME_LENGTH + 1] = {0x00,};
    304     int         length = 0;
    305     int         result = 0;
    306 
    307     ASSERT_CTX (ctx);
    308 
    309     CF_Log_Local_GetTimeString (datetime);
     177    char    buffer[BUF_LEN + 1] = {0x00,};
     178    char    datetime[CF_UTIL_DATETIME_LENGTH + 1] = {0x00,};
     179    int     length = 0;
     180    int     result = 0;
     181
     182    CF_UTIL_DATETIME dt;
     183
     184    ASSERT_CTX (context);
     185
     186    CF_Util_GetCurrentTime (&dt);
     187    CF_Util_GetTimeString (&dt, datetime);
    310188    length = snprintf (buffer, BUF_LEN, "[%s][%s] ", datetime, prefix);
    311189    vsnprintf (&buffer[length], BUF_LEN - (size_t)length, fmt, valist);
     
    329207 */
    330208int
    331 CF_Log_WriteCtx (CF_Log_Ctx ctx,
    332                  const char * prefix,
    333                  const char * fmt, ...)
    334 {
     209CF_Log_Write (cf_ctx        ctx,
     210              const char    * prefix,
     211              const char    * fmt, ...)
     212{
     213    CF_LOG_CONTEXT * context = (CF_LOG_CONTEXT *) ctx;
     214
    335215    int     result = 0;
    336216    va_list valist;
    337217
    338218    va_start (valist, fmt);
    339     result = CF_Log_Local_WriteVA (ctx, prefix, fmt, valist);
     219    result = CF_Log_Local_WriteVA (context, prefix, fmt, valist);
    340220    va_end (valist);
    341221
     
    350230 * \param ctx 로그 컨텍스트
    351231 */
    352 static int
    353 CF_Log_FlushCtx (CF_Log_Ctx ctx)
    354 {
    355     CF_LOG_CONTEXT  * context = (CF_LOG_CONTEXT *) ctx;
    356     int         result = 0;
     232int
     233CF_Log_Flush (cf_ctx ctx)
     234{
     235    int result = 0;
     236
     237    CF_LOG_CONTEXT * context = (CF_LOG_CONTEXT *) ctx;
    357238
    358239    ASSERT_CTX (ctx);
     
    372253 * \param ctx 로그 컨텍스트
    373254 */
    374 static int
    375 CF_Log_DestroyCtx (CF_Log_Ctx ctx)
     255int
     256CF_Log_Destroy (cf_ctx ctx)
    376257{
    377258    CF_LOG_CONTEXT * context = (CF_LOG_CONTEXT *) ctx;
     
    381262    if (context->size > 0)
    382263    {
    383         CF_Log_FlushCtx (ctx);
     264        CF_Log_Flush (ctx);
    384265        free (context->buffer);
    385266        context->buffer = NULL;
     
    387268    }
    388269
    389     CF_File_Close (context->fd);
    390 
    391     CF_Mutex_DestoryCtx (context->mutex);
     270    CF_File_Close (context->file);
     271
     272    CF_Mutex_Destory (context->mutex);
    392273    context->mutex = NULL;
     274
     275    free (context);
    393276
    394277    return CF_OK;
     
    406289 * \see CF_LOG_DEFAULT_BUFFER, CF_LOG_NO_BUFFER
    407290 */
    408 static int
    409 CF_Log_CreateCtx (CF_Log_Ctx    * ctx,
    410                   const char    * path,
    411                   const int     memsize)
     291int
     292CF_Log_Create (cf_ctx       * ctx,
     293               const char   * path,
     294               const int    memsize)
    412295{
    413296    int result = 0;
     
    417300             : memsize;
    418301
    419     CF_LOG_CONTEXT  * context = NULL;
    420 
    421     if (path == NULL)
    422         return CF_ERROR_LOG_INVALID_ARGS;
     302    CF_LOG_CONTEXT * context = NULL;
     303
     304    ASSERT_CTX (ctx);
     305    ASSERT_ARGS (path == NULL);
    423306
    424307    TRY
    425308    {
    426         context = (CF_LOG_CONTEXT *) calloc (sizeof (CF_LOG_CONTEXT), 1);
     309        context = NEWCTX (CF_LOG_CONTEXT);
    427310        if (context == NULL)
    428311        {
     
    431314        }
    432315
    433         context->fd = CF_File_Open (path, fileFlag);
    434         if (context->fd < 0)
     316        result = CF_File_Open (&context->file, path, fileFlag);
     317        if (result < 0)
    435318        {
    436319            result = CF_ERROR_LOG_CREATE_FILE;
    437320            TRY_BREAK;
    438321        }
    439         snprintf (context->path, sizeof (context->path) -1, "%s", path);
     322        snprintf (context->path, sizeof (context->path) - 1, "%s", path);
    440323
    441324        if (size > 0)
     
    450333        }
    451334
    452         *ctx = (CF_Log_Ctx) context;
     335        *ctx = (cf_ctx) context;
    453336    }
    454337    CATCH_IF (result < 0)
    455338    {
    456         CF_Log_DestroyCtx ((CF_Log_Ctx) context);
    457     }
    458 
    459     return result;
    460 }
    461 
    462 /**
    463  * 로그 컨텍스트에 아이디 넘버 할당<br />
    464  * 로그 기록 시, 아이디 넘버를 사용하면 해당 로그로 기록할 수 있음
    465  *
    466  * \return 성공 시, CF_OK; 실패 시, 오류 코드
    467  *
    468  * \param mapid 부여할 아이디 넘버
    469  * \param ctx   로그 컨텍스트
    470  *
    471  * \remarks 반드시 먼저 초기화 해야하며, 초기화 시에 주어진 번호보다 작은 아이디 넘버를 사용
    472  */
    473 static int
    474 CF_Log_MapCtxID (const int          mapid,
    475                  const CF_Log_Ctx   ctx)
    476 {
    477     ASSERT_INIT ();
    478     ASSERT_MAPID (mapid);
    479     ASSERT_MAPPED_CTX (mapid);
    480 
    481     gLogPool.ctxPool[mapid] = ctx;
    482 
    483     return CF_OK;
    484 }
    485 
    486 /**
    487  * 아이디 넘버에 해당하는 로그를 닫고 해당하는 컨텍스트를 해제
    488  *
    489  * \return 성공 시, CF_OK; 실패 시, 오류 코드
    490  *
    491  * \param mapid 로그의 아이디 넘버
    492  *
    493  * \remarks 아이디 넘버에 해당하는 컨텍스트가 해제되므로 주의
    494  */
    495 static int
    496 CF_Log_UnmapCtxID (const int mapid)
    497 {
    498     ASSERT_INIT ();
    499     ASSERT_MAPID (mapid);
    500     ASSERT_NOT_MAPPED_CTX (mapid);
    501 
    502     CF_Log_DestroyCtx (gLogPool.ctxPool[mapid]);
    503 
    504     free (gLogPool.ctxPool[mapid]);
    505     gLogPool.ctxPool[mapid] = NULL;
    506 
    507     return CF_OK;
    508 }
    509 
    510 /**
    511  * 아이디 넘버에 해당하는 로그 컨텍스트를 얻기
    512  *
    513  * \return 성공 시, CF_OK; 실패 시, 오류 코드
    514  *
    515  * \param mapid 로그의 아이디 넘버
    516  * \param ctx   로그 컨텍스트 받을 주소
    517  */
    518 static int
    519 CF_Log_GetMappedCtx (const int  mapid,
    520                      CF_Log_Ctx * ctx)
    521 {
    522     ASSERT_INIT ();
    523     ASSERT_MAPID (mapid);
    524     ASSERT_NOT_MAPPED_CTX (mapid);
    525 
    526     *ctx = gLogPool.ctxPool[mapid];
    527 
    528     return CF_OK;
    529 }
    530 
    531 /**
    532  * 로그를 사용하기 위해 초기화
    533  *
    534  * \return 성공 시, CF_OK; 실패 시, 오류 코드
    535  *
    536  * \param poolSize  로그 풀 크기로, 로그 아이디 넘버의 최대 값
    537  */
    538 int
    539 CF_Log_Initialize (const int poolSize)
    540 {
    541     memset (&gLogPool, 0x00, sizeof (CF_LOG_POOL));
    542 
    543     if (poolSize > 0)
    544     {
    545         gLogPool.ctxPool =
    546             (CF_Log_Ctx *) calloc ((size_t) poolSize, sizeof (CF_Log_Ctx));
    547         if (gLogPool.ctxPool == NULL)
    548             return CF_ERROR_LOG_INITIALIZE;
    549         gLogPool.poolSize = poolSize;
    550     }
    551 
    552     return CF_OK;
    553 }
    554 
    555 /**
    556  * 로그가 모두 사용된 후 자원 해제
    557  *
    558  * \return CF_OK 반환
    559  */
    560 int
    561 CF_Log_Finalize (void)
    562 {
    563     int mapid = 0;
    564 
    565     for (mapid = 0 ; mapid < gLogPool.poolSize ; mapid++)
    566     {
    567         CF_Log_UnmapCtxID (mapid);
    568     }
    569 
    570     if (gLogPool.ctxPool != NULL)
    571         free (gLogPool.ctxPool);
    572 
    573     memset (&gLogPool, 0x00, sizeof (CF_LOG_POOL));
    574 
    575     return CF_OK;
    576 }
    577 
    578 /**
    579  * 로그 열기
    580  *
    581  * \return 성공 시, CF_OK; 실패 시, 오류 코드
    582  *
    583  * \param mapid     로그의 아이디 넘버
    584  * \param path      로그 파일 경로
    585  * \param memsize   로그 버퍼 크기
    586  *
    587  * \see CF_LOG_DEFAULT_BUFFER, CF_LOG_NO_BUFFER
    588  */
    589 int
    590 CF_Log_Open (const int  mapid,
    591              const char * path,
    592              const int  memsize)
    593 {
    594     int         result = 0;
    595     CF_Log_Ctx  ctx = NULL;
    596 
    597     result = CF_Log_CreateCtx (&ctx, path, memsize);
    598     if (result < 0)
    599         return result;
    600 
    601     result = CF_Log_MapCtxID (mapid, ctx);
    602     if (result < 0)
    603         CF_Log_DestroyCtx (ctx);
    604 
    605     return result;
    606 }
    607 
    608 /**
    609  * 로그 닫기
    610  *
    611  * \return 성공 시, CF_OK; 실패 시, 오류 코드
    612  *
    613  * \param mapid 로그의 아이디 넘버
    614  */
    615 int
    616 CF_Log_Close (const int mapid)
    617 {
    618     return CF_Log_UnmapCtxID (mapid);
    619 }
    620 
    621 /**
    622  * 로그 버퍼의 데이터를 즉시 로그 파일에 쓰기
    623  *
    624  * \return 성공 시, CF_OK; 실패 시, 오류 코드
    625  *
    626  * \param mapid 로그의 아이디 넘버
    627  */
    628 int
    629 CF_Log_Flush (const int mapid)
    630 {
    631     int         result = 0;
    632     CF_Log_Ctx  ctx = NULL;
    633 
    634     result = CF_Log_GetMappedCtx (mapid, &ctx);
    635     if (result < 0)
    636         return result;
    637 
    638     result = CF_Log_FlushCtx (ctx);
    639 
    640     return result;
    641 }
    642 
    643 /**
    644  * 로그 컨텍스트에 멀티쓰레드 모드 설정
    645  *
    646  * \return 성공 시, CF_OK; 실패 시, 오류 코드
    647  *
    648  * \param mapid 로그의 아이디 넘버
    649  * \param flag  설정/해제 bool 플래그
    650  *
    651  * \see CF_BOOL
    652  */
    653 int
    654 CF_Log_SetMT (const int     mapid,
    655               const CF_BOOL flag)
    656 {
    657     int         result = 0;
    658     CF_Log_Ctx  ctx = NULL;
    659 
    660     result = CF_Log_GetMappedCtx (mapid, &ctx);
    661     if (result < 0)
    662         return result;
    663 
    664     result = (flag) ? CF_Log_SetMultiThread (ctx) :
    665                       CF_Log_UnsetMultiThread (ctx);
    666 
    667     return result;
    668 }
    669 
    670 /**
    671  * 로그 쓰기
    672  *
    673  * \return 성공 시, CF_OK; 실패 시, 오류 코드
    674  *
    675  * \param mapid     로그의 아이디 넘버
    676  * \param prefix    로그의 프리픽스 문자열
    677  * \param fmt       포맷 스트링
    678  * \param ...       가변 인자
    679  */
    680 int
    681 CF_Log_Write (const int     mapid,
    682               const char    * prefix,
    683               const char    * fmt, ...)
    684 {
    685     int         result = 0;
    686     CF_Log_Ctx  ctx = NULL;
    687     va_list     valist;
    688 
    689     result = CF_Log_GetMappedCtx (mapid, &ctx);
    690     if (result < 0)
    691         return result;
    692 
    693     va_start (valist, fmt);
    694     result = CF_Log_Local_WriteVA (ctx, prefix, fmt, valist);
    695     va_end (valist);
    696 
    697     return result;
    698 }
     339        CF_Log_Destroy ((cf_ctx) context);
     340    }
     341
     342    return result;
     343}
Note: See TracChangeset for help on using the changeset viewer.