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+
149157void 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+
217287static 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
0 commit comments