diff --git a/src/tlog.c b/src/tlog.c index 22307b2..5506845 100644 --- a/src/tlog.c +++ b/src/tlog.c @@ -40,6 +40,7 @@ #define TLOG_LOG_NAME_LEN 128 #define TLOG_BUFF_LEN (PATH_MAX + TLOG_LOG_NAME_LEN * 3) #define TLOG_SUFFIX_GZ ".gz" +#define TLOG_SUFFIX_LOG "" #define TLOG_SEGMENT_MAGIC 0xFF446154 @@ -68,9 +69,11 @@ struct tlog_log { int segment_log; tlog_output_func output_func; - void *private; + void *private_data; time_t last_try; + time_t last_waitpid; + int waiters; int is_exit; struct tlog_log *next; @@ -277,13 +280,13 @@ int tlog_localtime(struct tlog_time *tm) return _tlog_gettime(tm); } -void tlog_set_private(tlog_log *log, void *private) +void tlog_set_private(tlog_log *log, void *private_data) { if (log == NULL) { return; } - log->private = private; + log->private_data = private_data; } void *tlog_get_private(tlog_log *log) @@ -292,7 +295,7 @@ void *tlog_get_private(tlog_log *log) return NULL; } - return log->private; + return log->private_data; } static int _tlog_format(char *buff, int maxlen, struct tlog_info *info, void *userptr, const char *format, va_list ap) @@ -336,7 +339,7 @@ static int _tlog_root_log_buffer(char *buff, int maxlen, void *userptr, const ch { int len = 0; int log_len = 0; - struct tlog_info_inter *info_inter = userptr; + struct tlog_info_inter *info_inter = (struct tlog_info_inter *)userptr; struct tlog_segment_log_head *log_head = NULL; if (tlog_format == NULL) { @@ -389,10 +392,42 @@ static int _tlog_print_buffer(char *buff, int maxlen, void *userptr, const char return total_len; } +static int _tlog_need_drop(struct tlog_log *log) +{ + int maxlen = 0; + int ret = -1; + if (log->block) { + return -1; + } + + pthread_mutex_lock(&tlog.lock); + if (log->end == log->start) { + if (log->ext_end == 0) { + /* if buffer is empty */ + maxlen = log->buffsize - log->end; + } + } else if (log->end > log->start) { + maxlen = log->buffsize - log->end; + } else { + /* if reverse */ + maxlen = log->start - log->end; + } + + /* if free buffer length is less than min line length */ + if (maxlen < TLOG_MAX_LINE_LEN) { + log->dropped++; + ret = 0; + } + pthread_mutex_unlock(&tlog.lock); + return ret; +} + static int _tlog_vprintf(struct tlog_log *log, vprint_callback print_callback, void *userptr, const char *format, va_list ap) { int len; int maxlen = 0; + char buff[TLOG_MAX_LINE_LEN]; + struct tlog_segment_head *segment_head = NULL; if (log == NULL || format == NULL) { @@ -403,6 +438,15 @@ static int _tlog_vprintf(struct tlog_log *log, vprint_callback print_callback, v return -1; } + if (_tlog_need_drop(log) == 0) { + return -1; + } + + len = print_callback(buff, sizeof(buff), userptr, format, ap); + if (len <= 0 || len >= TLOG_MAX_LINE_LEN) { + return -1; + } + pthread_mutex_lock(&tlog.lock); do { if (log->end == log->start) { @@ -448,23 +492,14 @@ static int _tlog_vprintf(struct tlog_log *log, vprint_callback print_callback, v if (log->segment_log) { segment_head = (struct tlog_segment_head *)(log->buff + log->end); - /* write log to buffer */ - len = print_callback(segment_head->data, maxlen - sizeof(*segment_head), userptr, format, ap); - if (len <= 0) { - pthread_mutex_unlock(&tlog.lock); - return -1; - } + memcpy(segment_head->data, buff, len); log->end += len + sizeof(*segment_head) + 1; segment_head->len = len + 1; segment_head->data[len] = '\0'; segment_head->magic = TLOG_SEGMENT_MAGIC; } else { /* write log to buffer */ - len = print_callback(log->buff + log->end, maxlen, userptr, format, ap); - if (len <= 0) { - pthread_mutex_unlock(&tlog.lock); - return -1; - } + memcpy(log->buff + log->end, buff, len); log->end += len; } @@ -653,7 +688,7 @@ static int _tlog_get_oldest_callback(const char *path, struct dirent *entry, voi { struct stat sb; char filename[TLOG_BUFF_LEN]; - struct oldest_log *oldestlog = userptr; + struct oldest_log *oldestlog = (struct oldest_log *)userptr; struct tlog_log *log = oldestlog->log; char logname[TLOG_LOG_NAME_LEN * 2]; @@ -1026,7 +1061,12 @@ static int _tlog_write(struct tlog_log *log, char *buff, int bufflen) len = write(log->fd, buff, bufflen); if (len > 0) { log->filesize += len; - } + } else { + if (log->fd > 0 && errno == ENOSPC) { + close(log->fd); + log->fd = -1; + } + } return len; } @@ -1072,34 +1112,32 @@ static int _tlog_any_has_data(void) static int _tlog_wait_pids(void) { - static time_t last = -1; - time_t now = 0; - + time_t now = time(0); struct tlog_log *next = NULL; + static struct tlog_log *last_log = NULL; pthread_mutex_lock(&tlog.lock); - next = tlog.log; - while (next) { - if (next->zip_pid > 0) { - if (now == 0) { - now = time(0); - } - - if (now != last) { - pthread_mutex_unlock(&tlog.lock); - /* try to archive compressed file */ - _tlog_wait_pid(next, 0); - last = now; - return 0; - } + for (next = tlog.log; next != NULL; next = next->next) { + if (next->zip_pid <= 0) { + continue; } - next = next->next; - } - pthread_mutex_unlock(&tlog.lock); - if (now != 0) { - last = now; + if (next == last_log) { + continue; + } + + if (next->last_waitpid == now) { + continue; + } + + last_log = next; + next->last_waitpid = now; + pthread_mutex_unlock(&tlog.lock); + _tlog_wait_pid(next, 0); + return 0; } + last_log = NULL; + pthread_mutex_unlock(&tlog.lock); return 0; } @@ -1420,10 +1458,10 @@ int tlog_reg_format_func(tlog_format_func callback) return 0; } -int tlog_reg_log_output_func(tlog_log_output_func output, void *private) +int tlog_reg_log_output_func(tlog_log_output_func output, void *private_data) { tlog.output_func = output; - tlog_set_private(tlog.root, private); + tlog_set_private(tlog.root, private_data); return 0; } @@ -1447,7 +1485,7 @@ tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int bu return NULL; } - log = malloc(sizeof(*log)); + log = (struct tlog_log *)malloc(sizeof(*log)); if (log == NULL) { fprintf(stderr, "malloc log failed."); return NULL; @@ -1482,12 +1520,12 @@ tlog_log *tlog_open(const char *logfile, int maxlogsize, int maxlogcount, int bu strncpy(log->logname, basename(log_file), sizeof(log->logname)); log->logname[sizeof(log->logname) - 1] = '\0'; if (log->nocompress) { - log->suffix[0] = '\0'; + strncpy(log->suffix, TLOG_SUFFIX_LOG, sizeof(sizeof(log->suffix))); } else { strncpy(log->suffix, TLOG_SUFFIX_GZ, sizeof(log->suffix)); } - log->buff = malloc(log->buffsize); + log->buff = (char *)malloc(log->buffsize); if (log->buff == NULL) { fprintf(stderr, "malloc log buffer failed, %s\n", strerror(errno)); goto errout; diff --git a/src/tlog.h b/src/tlog.h index 2875ea2..5e71b0d 100644 --- a/src/tlog.h +++ b/src/tlog.h @@ -115,8 +115,8 @@ extern int tlog_reg_format_func(tlog_format_func func); /* register log output callback Note: info is invalid when flag TLOG_SEGMENT is not set. */ -typedef int (*tlog_log_output_func)(struct tlog_info *info, char *buff, int bufflen, void *private); -extern int tlog_reg_log_output_func(tlog_log_output_func output, void *private); +typedef int (*tlog_log_output_func)(struct tlog_info *info, char *buff, int bufflen, void *private_data); +extern int tlog_reg_log_output_func(tlog_log_output_func output, void *private_data); struct tlog_log; typedef struct tlog_log tlog_log; @@ -160,7 +160,7 @@ typedef int (*tlog_output_func)(struct tlog_log *log, char *buff, int bufflen); extern int tlog_reg_output_func(tlog_log *log, tlog_output_func output); /* set private data */ -extern void tlog_set_private(tlog_log *log, void *private); +extern void tlog_set_private(tlog_log *log, void *private_data); /* get private data */ extern void *tlog_get_private(tlog_log *log);