38 #include <sys/types.h>    51 #define LOG_MAX_FILESIZE (256* 1024)    53 #ifndef _INSTALL_DIR //HACK    54 #define _INSTALL_DIR "./"    56 #ifndef _PROCNAME //HACK    57 #define _PROCNAME "stdout"    59 #define LOG_FILEPATH    _INSTALL_DIR"/var/log/"_PROCNAME    60 #define LOG_FILE        LOG_FILEPATH"/"_PROCNAME".log"    61 #define LOG_FILE_OLD    LOG_FILEPATH"/"_PROCNAME".old.log"    64 #ifdef LOG_FORCE_USING_STDOUT    66     #define CNRM "\x1B[0m"    67     #define CRED "\033[1;31m" // Bold-red    68     #define CGRN "\x1B[32m"    69     #define CYEL "\x1B[33m"    70     #define CMAG "\x1B[35m"    71     #define CBLU "\x1B[34m"    73     #define LOG_VERBOSE_HIGHLIGHT   CNRM    74     #define LOG_DEBUG_HIGHLIGHT     CNRM    75     #define LOG_WARNING_HIGHLIGHT   CYEL    76     #define LOG_ERROR_HIGHLIGHT     CRED    77     #define LOG_RAW_HIGHLIGHT       CNRM    78     #define LOG_EVENT_HIGHLIGHT     CGRN    82     #define CLOSE_FILE(FD)    83     #define UPDATE_USE_STDOUT_FLAG() \    86     #define LOG_VERBOSE_HIGHLIGHT   "VERBOSE: "    87     #define LOG_DEBUG_HIGHLIGHT     "DEBUG:   "    88     #define LOG_WARNING_HIGHLIGHT   "WARNING: "    89     #define LOG_ERROR_HIGHLIGHT     "ERROR:   "    90     #define LOG_RAW_HIGHLIGHT       ""    91     #define LOG_EVENT_HIGHLIGHT     "EVENT: "    94         open(LOG_FILE, O_RDWR| O_APPEND| O_TRUNC| O_CREAT, S_IRUSR| S_IWUSR)    95     #define CLOSE_FILE(FD) \    97     #define UPDATE_USE_STDOUT_FLAG() \   134 static void log_trace_fd(log_level_t type, 
const char *filename, 
int line,
   135         const char *format, va_list arg);
   136 static void log_trace_buf(log_level_t type, 
log_ctx_t *log_ctx,
   137         const char *filename, 
int line, 
const char *format, va_list arg);
   138 static void log_module_fflush();
   143 static int logfile_fd= -1;
   144 static pthread_mutex_t logfile_mutex= PTHREAD_MUTEX_INITIALIZER;
   145 static int flag_use_stdout= 0;
   147 int log_module_open()
   149     int ret_code, end_code= STAT_ERROR;
   153     logfile_fd= OPEN_FILE();
   155         printf(
"Could not open LOG file '%s'\n", LOG_FILE);
   160     ret_code= pthread_mutex_init(&logfile_mutex, NULL);
   164     UPDATE_USE_STDOUT_FLAG();
   166     end_code= STAT_SUCCESS;
   168     if(end_code!= STAT_SUCCESS)
   173 void log_module_close()
   179     CLOSE_FILE(logfile_fd);
   183     ret_code= pthread_mutex_destroy(&logfile_mutex);
   192     int ret_code, end_code= STAT_ERROR;
   202     ret_code= pthread_mutex_init(&log_ctx->
mutex, NULL);
   209     end_code= STAT_SUCCESS;
   211     if(end_code!= STAT_SUCCESS)
   220     if(ref_log_ctx== NULL)
   223     if((log_ctx= *ref_log_ctx)!= NULL) {
   228         ret_code= pthread_mutex_destroy(&log_ctx->
mutex);
   235             log_line_ctx_release(&log_line_ctx);
   243 void log_trace(log_level_t type, 
log_ctx_t *log_ctx, 
const char *filename,
   244         int line, 
const char *format, ...)
   246     va_list arg, arg_cpy;
   249     if(type>= LOG_TYPE_MAX) 
return;
   250     if(format== NULL) 
return;
   254         printf(
"'LOG' module should be initialized previously\n");
   258     va_start(arg, format);
   259     va_copy(arg_cpy, arg);
   261     if(flag_use_stdout== 0 && log_ctx!= NULL) {
   263         log_trace_buf(type, log_ctx, filename, line, format, arg_cpy);
   265         log_trace_fd(type, filename, line, format, arg_cpy);
   274     llist_t *curr_node, *prev_node;
   281     pthread_mutex_lock(&log_ctx->
mutex);
   286     while(curr_node!= NULL) {
   291         log_line_ctx2= log_line_ctx_dup((
const log_line_ctx_t*)curr_node->data);
   292         if(log_line_ctx2== NULL)
   299         new_node->data= (
void*)log_line_ctx2;
   300         new_node->next= NULL;
   304             prev_node->next= new_node;
   306             log_line_ctx_llist= new_node;
   310         curr_node= curr_node->next;
   313     pthread_mutex_unlock(&log_ctx->
mutex);
   323     pthread_mutex_lock(&log_ctx->
mutex);
   329         log_line_ctx_release(&log_line_ctx);
   335     pthread_mutex_unlock(&log_ctx->
mutex);
   348     if(log_line_ctx_arg== NULL)
   352     log_line_ctx= log_line_ctx_allocate();
   353     if(log_line_ctx== NULL)
   357     strncpy(log_line_ctx->code, log_line_ctx_arg->code, LOG_LINE_SIZE);
   358     strncpy(log_line_ctx->desc, log_line_ctx_arg->desc, LOG_LINE_SIZE);
   359     strncpy(log_line_ctx->date, log_line_ctx_arg->date, LOG_DATE_SIZE);
   360     log_line_ctx->ts= log_line_ctx_arg->ts;
   361     log_line_ctx->count= log_line_ctx_arg->count;
   370     if(ref_log_line_ctx== NULL)
   373     if((log_line_ctx= *ref_log_line_ctx)!= NULL) {
   375         *ref_log_line_ctx= NULL;
   379 void log_trace_byte_table(
const char *label, 
const char *file, 
int line,
   380         uint8_t *data, 
size_t len, 
size_t xsize)
   386     if(file== NULL || data== NULL) 
return;
   388         log_trace(LOG_ERROR, NULL, __FILENAME__, __LINE__,
   389                 "Parameter 'xsize' MUST be a multiple of 4.\n");
   393     log_trace(LOG_RAW, NULL, __FILENAME__, __LINE__,
   394             "%s %d: \n> ======== %s ========\n", file, line,
   395             label!= NULL? label: 
"");
   396     for(i= 0; i< len; i+= xsize) {
   397         log_trace(LOG_RAW, NULL, __FILENAME__, __LINE__, 
"> ");
   398         for(j= 0; j< xsize; j++) {
   401             log_trace(LOG_RAW, NULL, __FILENAME__, __LINE__, 
"%02x", p[i+j]);
   403                 log_trace(LOG_RAW, NULL, __FILENAME__, __LINE__, 
" ");
   405         log_trace(LOG_RAW, NULL, __FILENAME__, __LINE__, 
"\n");
   407     log_trace(LOG_RAW, NULL, __FILENAME__, __LINE__, 
">\n\n");
   411 static void log_trace_fd(log_level_t type, 
const char *filename, 
int line,
   412         const char *format, va_list arg)
   414     char str[LOG_LINE_SIZE], *highlight_prefix;
   418     pthread_mutex_lock(&logfile_mutex);
   423         highlight_prefix= LOG_VERBOSE_HIGHLIGHT;
   426         highlight_prefix= LOG_DEBUG_HIGHLIGHT;
   429         highlight_prefix= LOG_WARNING_HIGHLIGHT;
   432         highlight_prefix= LOG_ERROR_HIGHLIGHT;
   435         highlight_prefix= LOG_RAW_HIGHLIGHT;
   438         highlight_prefix= LOG_EVENT_HIGHLIGHT;
   441         highlight_prefix= 
"";
   444     str_size+= snprintf(&str[str_size], 
sizeof(str)- str_size, 
"%s",
   448     if(filename!= NULL && type!= LOG_RAW) {
   449         if(str_size>= 
sizeof(str)) 
goto end;
   450         str_size+= snprintf(&str[str_size], 
sizeof(str)- str_size, 
"%s %d ",
   455     if(str_size>= 
sizeof(str)) 
goto end;
   456     str_size+= vsnprintf(&str[str_size], 
sizeof(str)- str_size, format, arg);
   459     if(str_size>= 
sizeof(str)) str_size= 
sizeof(str);
   460     written= write(logfile_fd, str, str_size);
   462     if(written!= str_size) written= -1;
   468     pthread_mutex_unlock(&logfile_mutex);
   473 static void log_trace_buf(log_level_t type, 
log_ctx_t *log_ctx,
   474         const char *filename, 
int line, 
const char *format, va_list arg)
   476     char code[LOG_LINE_SIZE], *extp;
   480     uint64_t oldest_ts= 0;
   481     struct timespec monotime_curr= {0};
   482     time_t t= time(NULL);
   483     struct tm *tm= localtime(&t);
   490     if(clock_gettime(CLOCK_MONOTONIC, &monotime_curr)!= 0)
   494     snprintf(code, LOG_LINE_SIZE, 
"%d%s", line, filename);
   495     extp= strstr(code, 
".c");
   499     pthread_mutex_lock(&log_ctx->
mutex);
   507     while(*ref_curr_node!= NULL) {
   510         llist_t *curr_node= *ref_curr_node;
   514         if(log_line_ctx_ith== NULL)
   518         if(strncmp(code, log_line_ctx_ith->code, strlen(code))== 0) {
   520             vsnprintf(log_line_ctx_ith->desc, LOG_LINE_SIZE, format, arg);
   521             log_line_ctx_ith->count++;
   522             log_line_ctx_ith->ts= (uint64_t)monotime_curr.tv_sec;
   524                 snprintf(log_line_ctx_ith->date, LOG_DATE_SIZE,
   525                         "%d:%d:%d %d-%d-%d", tm->tm_hour, tm->tm_min,
   526                         tm->tm_sec, tm->tm_year + 1900, tm->tm_mon + 1,
   529                 memset(log_line_ctx_ith->date, 0, LOG_DATE_SIZE);
   535         if((ts_ith= log_line_ctx_ith->ts)< oldest_ts) {
   541         if((*ref_curr_node)->next== NULL)
   545         ref_curr_node= &(*ref_curr_node)->next;
   552     new_log_line_ctx= log_line_ctx_allocate();
   553     if(new_log_line_ctx== NULL)
   555     strncpy(new_log_line_ctx->code, code, LOG_LINE_SIZE);
   556     vsnprintf(new_log_line_ctx->desc, LOG_LINE_SIZE, format, arg);
   557     new_log_line_ctx->count= 1;
   558     new_log_line_ctx->ts= (uint64_t)monotime_curr.tv_sec;
   560         snprintf(new_log_line_ctx->date, LOG_DATE_SIZE, 
"%d:%d:%d %d-%d-%d",
   561                 tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year + 1900,
   562                 tm->tm_mon + 1, tm->tm_mday);
   564         memset(new_log_line_ctx->date, 0, LOG_DATE_SIZE);
   571     new_node->data= (
void*)new_log_line_ctx;
   572     new_log_line_ctx= NULL; 
   573     new_node->next= NULL; 
   584         llist_t *log_line_ctx_llist_oldest=
   587                 log_line_ctx_llist_oldest->data;
   588         if(log_line_ctx_oldest!= NULL)
   589             log_line_ctx_release(&log_line_ctx_oldest);
   593                 log_line_ctx_llist_oldest->next;
   594         free(log_line_ctx_llist_oldest);
   599 #if 0 //RAL: comment-me   602         printf(
"LOG-traces list length (id= %d): %d; "   603                 "last log-trace code: %s\n",
   605                 log_line_ctx_llist!= NULL?
   611     pthread_mutex_unlock(&log_ctx->
mutex);
   612     if(new_log_line_ctx!= NULL)
   613         log_line_ctx_release(&new_log_line_ctx);
   620 #ifdef LOG_FORCE_USING_STDOUT   622 static void log_module_fflush()
   630 static void log_module_fflush()
   635     logfile_off= lseek(logfile_fd, 0, SEEK_CUR);
   636     if(logfile_off> LOG_MAX_FILESIZE) {
   637         CLOSE_FILE(logfile_fd);
   638         unlink(LOG_FILE_OLD);
   639         rename(LOG_FILE, LOG_FILE_OLD);
   640         logfile_fd= OPEN_FILE();
   642             printf(
"Error: Unable to create log-file '%s'.\n", LOG_FILE);
 int log_line_ctx_llist_len
General status codes enumeration. 
#define CHECK_DO(COND, ACTION)
llist_t * log_line_ctx_llist
Simple linked-list utility implementation. 
llist_t ** log_line_ctx_llist_tail_ref
void * llist_pop(llist_t **ref_llist_head)
llist_t ** log_line_ctx_llist_oldest_ref