int log_init() { log_filter = get_log_level_from_config(); log_info_message("log filter is %s", log_level_string(log_filter)); pthread_mutex_init(&log_thread_mutex, NULL); if(0 != pthread_create(&log_thread_t, NULL, log_monitor, NULL)) { log_error_message("log monitor thread fail"); pthread_mutex_destroy(&log_thread_mutex); return -1; } return 0; }
void log_message(LOG_LEVEL log_evel, int line, const char *funcname, const char *fmt, ...) { struct timespec now; struct tm *p; char timep[128] = {0}; char errorinfo[128] = {0}; char str[1024] = {0}; char msg[1024] = {0}; va_list vargs; if(log_evel < log_filter) { return ; } pthread_mutex_lock(&log_thread_mutex); va_start(vargs, fmt); vsnprintf(str, sizeof(str), fmt, vargs); /*get time string*/ clock_gettime(CLOCK_REALTIME, &now); p = localtime(&now.tv_sec); snprintf(timep, sizeof(timep), "%04d-%02d-%02d %02d:%02d:%02d:%03d", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, (int)(now.tv_nsec/1000000)); snprintf(msg, sizeof(msg), "%s: %s : %s:%d : %s\n", timep, log_level_string(log_evel), funcname, line, str); if (NULL == msg) goto cleanup; log_file_open(); if (gLogFd > 0) { if (safewrite(gLogFd, msg, strlen(msg)) < 0) { print_log_to_syslog(msg); } close(gLogFd); } else { print_log_to_syslog(msg); } cleanup: va_end(vargs); pthread_mutex_unlock(&log_thread_mutex); }
void log_msg(int msg_log_level, time_t *rawtime, const char *source, const char *format, const va_list args) { char buffer[20], lls_buffer[10]; log_entry *ent = malloc(sizeof(log_entry)); if(ent == NULL) { pthread_mutex_lock(&mxs); fprintf(log_stream, "in log_msg: memory allocation failed: (%s)\n", strerror(errno)); pthread_mutex_unlock(&mxs); goto ON_ERROR; } memset(ent, 0, sizeof(log_entry)); ent->severity = msg_log_level; vsprintf(ent->event, format, args); strcpy(ent->source, source); ent->rawtime = rawtime; if(lstack_push(&log_stack, ent) != 0) { pthread_mutex_lock(&mxs); fprintf(log_stream, "in log_msg: enqueue log entry failed (size %d)\n", lstack_size(&log_stack)); pthread_mutex_unlock(&mxs); free(ent); goto ON_ERROR; } return; ON_ERROR: strftime(buffer, 20, "%F %H:%M:%S", localtime(rawtime)); log_level_string(lls_buffer, msg_log_level); pthread_mutex_lock(&mxs); fprintf(log_stream, "[%s: %s] ", lls_buffer, buffer); vfprintf(log_stream, format, args); pthread_mutex_unlock(&mxs); free(rawtime); }
/// output MessagePack object to stream in text format void log_text(FILE *stream, msgpack_object *msg) { // helper macro to access a specific array element #define MEMBER(n) msg->via.array.ptr[n] //msgpack_object_print(stream, *msg); // (print msgpack array, DEBUG only) // process ID if (MEMBER(3).type != MSGPACK_OBJECT_NIL) fprintf(stream, "PID 0x%X ", (unsigned int)MEMBER(3).via.u64); // indentation (DEBUG only) //fprintf(stream, "@%u ", (unsigned int)MEMBER(1).via.u64); // serial (DEBUG only) //fprintf(stream, "#%u ", (uint32_t)MEMBER(7).via.u64); // log level LOG_LEVEL level = MEMBER(0).via.u64; putc('[', stream); fputs(log_level_string(level), stream); fputs("] ", stream); double timestamp = MEMBER(2).via.f64; if (timestamp > 0) { // log timestamp (UTC seconds since the Epoch) char time_str[16]; format_timestamp(time_str, sizeof(time_str), "%H:%M:%S.qqq ", timestamp, true); fputs(time_str, stream); } // message origin (e.g. module) if (msgpack_object_str_fwrite(MEMBER(4).via.str, stream)) fputs(": ", stream); switch (level) { case LOG_LEVEL_SEPARATOR: // no message text, no attachment fputs("----------------------------------------", stream); break; case LOG_LEVEL_CHECKPOINT: fputs("Check point '", stream); msgpack_object_str_fwrite(MEMBER(5).via.str, stream); // msg = ID/name fputs("' #", stream); msgpack_object_print(stream, MEMBER(6)); // attachment = pass count break; case LOG_LEVEL_SCRATCHPAD: msgpack_object_str_fwrite(MEMBER(5).via.str, stream); // msg = key fputs(" <- ", stream); msgpack_object_str_fwrite(MEMBER(6).via.str, stream); // attachment = value break; default: msgpack_object_str_fwrite(MEMBER(5).via.str, stream); // the actual message // optional attachment (arbitrary MessagePack object) if (MEMBER(6).type != MSGPACK_OBJECT_NIL) { fputs("\n\t", stream); // new line and TAB msgpack_object_print(stream, MEMBER(6)); } } putc('\n', stream); fflush(stream); }
void *log_func(void *param) { int err; struct user_data_log *userdata = param; log_entry* ent = NULL; connect_to_database(userdata->configs->serv_addr, userdata->configs->username, userdata->configs->passwd); while(!need_quit(&mxq)) { // TODO add proper polling system if((ent = lstack_pop(&log_stack)) != NULL) { if(ent->severity >= userdata->log_level) { char buffer[20], lls_buffer[10]; strftime(buffer, 20, "%F %H:%M:%S", localtime(ent->rawtime)); log_level_string(lls_buffer, ent->severity); pthread_mutex_lock(&mxs); fprintf(log_stream, "[%s: %s] %s", lls_buffer, buffer, ent->event); pthread_mutex_unlock(&mxs); } if((err = log_to_database(ent)) != 0) { if((err != CR_SERVER_GONE_ERROR && err != -1) || (err = connect_to_database(userdata->configs->serv_addr, userdata->configs->username, userdata->configs->passwd)) != 0 || (err = log_to_database (ent)) != 0) { pthread_mutex_lock(&mxs); fprintf(log_stream, "could not log to database (%d)\n", err); pthread_mutex_unlock(&mxs); } } free(ent->rawtime); free(ent); } usleep(50000); } while((ent = lstack_pop(&log_stack)) != NULL) { if(ent->severity >= userdata->log_level) { char buffer[20], lls_buffer[10]; strftime(buffer, 20, "%F %H:%M:%S", localtime(ent->rawtime)); log_level_string(lls_buffer, ent->severity); pthread_mutex_lock(&mxs); fprintf(log_stream, "[%s: %s] %s", lls_buffer, buffer, ent->event); pthread_mutex_unlock(&mxs); } if((err = log_to_database(ent)) != 0) { if((err != CR_SERVER_GONE_ERROR && err != -1) || (err = connect_to_database(userdata->configs->serv_addr, userdata->configs->username, userdata->configs->passwd)) != 0 || (err = log_to_database (ent)) != 0) { const char *error = dblogger_error(); if(error != NULL) { pthread_mutex_lock(&mxs); fprintf(log_stream, "could not log to database (%d : %s)\n", err, error); pthread_mutex_unlock(&mxs); }else { pthread_mutex_lock(&mxs); fprintf(log_stream, "could not log to database (%d)\n", err); pthread_mutex_unlock(&mxs); } } } free(ent->rawtime); free(ent); } if((err = disconnect()) != 0) { fprintf(log_stream, "error while disconnecting from database (%d)\n", err); } return NULL; }