1
1
#include "hlog.h"
2
2
3
+ #include <assert.h>
3
4
#include <stdio.h>
4
5
#include <stdlib.h>
5
6
#include <string.h>
@@ -44,6 +45,7 @@ struct logger_s {
44
45
// for file logger
45
46
char filepath [256 ];
46
47
unsigned long long max_filesize ;
48
+ float truncate_percent ;
47
49
int remain_days ;
48
50
int enable_fsync ;
49
51
FILE * fp_ ;
@@ -67,6 +69,7 @@ static void logger_init(logger_t* logger) {
67
69
68
70
logger -> fp_ = NULL ;
69
71
logger -> max_filesize = DEFAULT_LOG_MAX_FILESIZE ;
72
+ logger -> truncate_percent = DEFAULT_LOG_TRUNCATE_PERCENT ;
70
73
logger -> remain_days = DEFAULT_LOG_REMAIN_DAYS ;
71
74
logger -> enable_fsync = 1 ;
72
75
logger_set_file (logger , DEFAULT_LOG_FILE );
@@ -146,6 +149,11 @@ void logger_set_remain_days(logger_t* logger, int days) {
146
149
logger -> remain_days = days ;
147
150
}
148
151
152
+ void logger_set_truncate_percent (logger_t * logger , float percent ) {
153
+ assert (percent <= 1.0f );
154
+ logger -> truncate_percent = percent ;
155
+ }
156
+
149
157
void logger_set_max_bufsize (logger_t * logger , unsigned int bufsize ) {
150
158
logger -> bufsize = bufsize ;
151
159
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) {
214
222
tm -> tm_mday );
215
223
}
216
224
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
+
217
287
static FILE * logfile_shift (logger_t * logger ) {
218
288
time_t ts_now = time (NULL );
219
289
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) {
258
328
fseek (logger -> fp_ , 0 , SEEK_END );
259
329
long filesize = ftell (logger -> fp_ );
260
330
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 {
272
333
logger -> can_write_cnt = (logger -> max_filesize - filesize ) / logger -> bufsize ;
273
334
}
274
335
}
@@ -419,7 +480,7 @@ int logger_print(logger_t* logger, int level, const char* fmt, ...) {
419
480
len += snprintf (buf + len , bufsize - len , "%s" , CLR_CLR );
420
481
}
421
482
422
- if (len < bufsize ) {
483
+ if (len < bufsize ) {
423
484
buf [len ++ ] = '\n' ;
424
485
}
425
486
0 commit comments