Skip to content

Commit aa1bbc5

Browse files
committed
feat: support logger_set_truncate_percent
1 parent c9f07f9 commit aa1bbc5

File tree

7 files changed

+104
-12
lines changed

7 files changed

+104
-12
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ unittest: prepare
233233
$(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/mkdir_p unittest/mkdir_test.c base/hbase.c
234234
$(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/rmdir_p unittest/rmdir_test.c base/hbase.c
235235
$(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/date unittest/date_test.c base/htime.c
236+
$(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/hlog_test unittest/hlog_test.c base/hlog.c
236237
$(CC) -g -Wall -O0 -std=c99 -I. -Ibase -o bin/hatomic_test unittest/hatomic_test.c -pthread
237238
$(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -o bin/hatomic_cpp_test unittest/hatomic_test.cpp -pthread
238239
$(CXX) -g -Wall -O0 -std=c++11 -I. -Ibase -o bin/hthread_test unittest/hthread_test.cpp -pthread

base/hlog.c

+73-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "hlog.h"
22

3+
#include <assert.h>
34
#include <stdio.h>
45
#include <stdlib.h>
56
#include <string.h>
@@ -44,6 +45,7 @@ struct logger_s {
4445
// for file logger
4546
char filepath[256];
4647
unsigned long long max_filesize;
48+
float truncate_percent;
4749
int remain_days;
4850
int enable_fsync;
4951
FILE* fp_;
@@ -67,6 +69,7 @@ static void logger_init(logger_t* logger) {
6769

6870
logger->fp_ = NULL;
6971
logger->max_filesize = DEFAULT_LOG_MAX_FILESIZE;
72+
logger->truncate_percent = DEFAULT_LOG_TRUNCATE_PERCENT;
7073
logger->remain_days = DEFAULT_LOG_REMAIN_DAYS;
7174
logger->enable_fsync = 1;
7275
logger_set_file(logger, DEFAULT_LOG_FILE);
@@ -146,6 +149,11 @@ void logger_set_remain_days(logger_t* logger, int days) {
146149
logger->remain_days = days;
147150
}
148151

152+
void logger_set_truncate_percent(logger_t* logger, float percent) {
153+
assert(percent <= 1.0f);
154+
logger->truncate_percent = percent;
155+
}
156+
149157
void logger_set_max_bufsize(logger_t* logger, unsigned int bufsize) {
150158
logger->bufsize = bufsize;
151159
logger->buf = (char*)realloc(logger->buf, bufsize);
@@ -214,6 +222,68 @@ static void logfile_name(const char* filepath, time_t ts, char* buf, int len) {
214222
tm->tm_mday);
215223
}
216224

225+
static void logfile_truncate(logger_t* logger) {
226+
// close
227+
if (logger->fp_) {
228+
fclose(logger->fp_);
229+
logger->fp_ = NULL;
230+
}
231+
char tmp_logfile[sizeof(logger->cur_logfile) + 4] = {0};
232+
FILE* tmpfile = NULL;
233+
if (logger->truncate_percent < 1.0f) {
234+
snprintf(tmp_logfile, sizeof(tmp_logfile), "%s.tmp", logger->cur_logfile);
235+
tmpfile = fopen(tmp_logfile, "w");
236+
}
237+
if (tmpfile) {
238+
// truncate percent
239+
logger->fp_ = fopen(logger->cur_logfile, "r");
240+
if (logger->fp_) {
241+
fseek(logger->fp_, 0, SEEK_END);
242+
long filesize = ftell(logger->fp_);
243+
long truncate_size = (long)((double)filesize * logger->truncate_percent);
244+
fseek(logger->fp_, -(filesize - truncate_size), SEEK_CUR);
245+
long cur_pos = ftell(logger->fp_);
246+
char buf[4096] = {0};
247+
const char* pbuf = buf;
248+
size_t nread = 0, nwrite = 0;
249+
char find_newline = 0;
250+
while ((nread = fread(buf, 1, sizeof(buf), logger->fp_)) > 0) {
251+
pbuf = buf;
252+
if (find_newline == 0) {
253+
while (nread > 0) {
254+
if (*pbuf == '\n') {
255+
find_newline = 1;
256+
++pbuf;
257+
--nread;
258+
break;
259+
}
260+
++pbuf;
261+
--nread;
262+
}
263+
}
264+
if (nread > 0) {
265+
nwrite += fwrite(pbuf, 1, nread, tmpfile);
266+
}
267+
}
268+
fclose(tmpfile);
269+
fclose(logger->fp_);
270+
logger->fp_ = NULL;
271+
remove(logger->cur_logfile);
272+
rename(tmp_logfile, logger->cur_logfile);
273+
}
274+
} else {
275+
// truncate all
276+
// remove(logger->cur_logfile);
277+
logger->fp_ = fopen(logger->cur_logfile, "w");
278+
if (logger->fp_) {
279+
fclose(logger->fp_);
280+
logger->fp_ = NULL;
281+
}
282+
}
283+
// reopen
284+
logger->fp_ = fopen(logger->cur_logfile, "a");
285+
}
286+
217287
static FILE* logfile_shift(logger_t* logger) {
218288
time_t ts_now = time(NULL);
219289
int interval_days = logger->last_logfile_ts == 0 ? 0 : (ts_now+s_gmtoff) / SECONDS_PER_DAY - (logger->last_logfile_ts+s_gmtoff) / SECONDS_PER_DAY;
@@ -258,17 +328,8 @@ static FILE* logfile_shift(logger_t* logger) {
258328
fseek(logger->fp_, 0, SEEK_END);
259329
long filesize = ftell(logger->fp_);
260330
if (filesize > logger->max_filesize) {
261-
fclose(logger->fp_);
262-
logger->fp_ = NULL;
263-
// ftruncate
264-
logger->fp_ = fopen(logger->cur_logfile, "w");
265-
// reopen with O_APPEND for multi-processes
266-
if (logger->fp_) {
267-
fclose(logger->fp_);
268-
logger->fp_ = fopen(logger->cur_logfile, "a");
269-
}
270-
}
271-
else {
331+
logfile_truncate(logger);
332+
} else {
272333
logger->can_write_cnt = (logger->max_filesize - filesize) / logger->bufsize;
273334
}
274335
}
@@ -419,7 +480,7 @@ int logger_print(logger_t* logger, int level, const char* fmt, ...) {
419480
len += snprintf(buf + len, bufsize - len, "%s", CLR_CLR);
420481
}
421482

422-
if(len<bufsize) {
483+
if(len < bufsize) {
423484
buf[len++] = '\n';
424485
}
425486

base/hlog.h

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ typedef enum {
6767
#define DEFAULT_LOG_REMAIN_DAYS 1
6868
#define DEFAULT_LOG_MAX_BUFSIZE (1<<14) // 16k
6969
#define DEFAULT_LOG_MAX_FILESIZE (1<<24) // 16M
70+
#define DEFAULT_LOG_TRUNCATE_PERCENT 0.99f // truncate when exceeded max filesize
7071

7172
// logger: default file_logger
7273
// network_logger() see event/nlog.h
@@ -113,6 +114,7 @@ HV_EXPORT void logger_set_max_filesize(logger_t* logger, unsigned long long file
113114
// 16, 16M, 16MB
114115
HV_EXPORT void logger_set_max_filesize_by_str(logger_t* logger, const char* filesize);
115116
HV_EXPORT void logger_set_remain_days(logger_t* logger, int days);
117+
HV_EXPORT void logger_set_truncate_percent(logger_t* logger, float percent);
116118
HV_EXPORT void logger_enable_fsync(logger_t* logger, int on);
117119
HV_EXPORT void logger_fsync(logger_t* logger);
118120
HV_EXPORT const char* logger_get_cur_file(logger_t* logger);
@@ -133,6 +135,7 @@ HV_EXPORT void hv_destroy_default_logger(void);
133135
#define hlog_set_max_filesize(filesize) logger_set_max_filesize(hlog, filesize)
134136
#define hlog_set_max_filesize_by_str(filesize) logger_set_max_filesize_by_str(hlog, filesize)
135137
#define hlog_set_remain_days(days) logger_set_remain_days(hlog, days)
138+
#define hlog_set_truncate_percent(val) logger_set_truncate_percent(hlog, val)
136139
#define hlog_enable_fsync() logger_enable_fsync(hlog, 1)
137140
#define hlog_disable_fsync() logger_enable_fsync(hlog, 0)
138141
#define hlog_fsync() logger_fsync(hlog)

docs/API.md

+1
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@
254254
- logger_set_max_bufsize
255255
- logger_set_max_filesize
256256
- logger_set_remain_days
257+
- logger_set_truncate_percent
257258
- logger_get_cur_file
258259
- hlogd, hlogi, hlogw, hloge, hlogf
259260
- LOGD, LOGI, LOGW, LOGE, LOGF

docs/cn/hlog.md

+3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ void logger_set_max_filesize(logger_t* logger, unsigned long long filesize);
6464
// 16, 16M, 16MB
6565
void logger_set_max_filesize_by_str(logger_t* logger, const char* filesize);
6666

67+
// 设置日志文件翻转截断百分比
68+
void logger_set_truncate_percent(logger_t* logger, float percent);
69+
6770
// 设置日志文件保留天数
6871
void logger_set_remain_days(logger_t* logger, int days);
6972

scripts/unittest.sh

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ bin/ifconfig
1111
bin/mkdir_p 123/456
1212
bin/ls
1313
bin/rmdir_p 123/456
14+
bin/hlog_test
1415

1516
bin/base64
1617
bin/md5

unittest/hlog_test.c

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include "hlog.h"
2+
3+
int main(int argc, char* argv[]) {
4+
char logfile[] = "hlog_test.log";
5+
hlog_set_file(logfile);
6+
hlog_set_level(LOG_LEVEL_INFO);
7+
8+
// test log max filesize
9+
hlog_set_max_filesize_by_str("1M");
10+
for (int i = 100000; i <= 999999; ++i) {
11+
hlogi("[%d] xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", i);
12+
}
13+
14+
// test log level
15+
hlogd("%s", "not show debug");
16+
hlogi("%s", "show info");
17+
hlogw("%s", "show warn");
18+
hloge("%s", "show error");
19+
hlogf("%s", "show fatal");
20+
21+
return 0;
22+
}

0 commit comments

Comments
 (0)