3030#include <stdlib.h>
3131#include "protocol_extension.h"
3232
33+ #define NEW_DO_USERLOG 1
34+
3335static EXTENSION_LOG_LEVEL current_log_level = EXTENSION_LOG_WARNING ;
3436SERVER_HANDLE_V1 * sapi ;
3537
@@ -60,12 +62,15 @@ static int current_flength; // current file length
6062static char hname_pid [100 ]; // hostname + pid for prefix
6163static int hname_len ; // length of hname_pid
6264static int prefix_len ; // length of date_time + hname_pid
65+ #ifdef NEW_DO_USERLOG
66+ #else
6367static time_t prev_time ; // save the previous time
6468static int msg_cnt ; // # of inputted messages in the interval
6569static int drop_cnt ; // # of messages to be dropped in a second
6670static bool drop_mode ; // indicate the DROP mode when over RATE_LIMIT
67- static bool reduction_mode ; // duplication reduction or not. user setting or default(=False)
6871static int samelog_cnt ;
72+ #endif
73+ static bool reduction_mode ; // duplication reduction or not. user setting or default(=False)
6974static char prevtime_str [200 ];
7075static char prev_log [2048 ];
7176static int prev_len ;
@@ -112,11 +117,14 @@ static void do_print_dup(char *time_str, int dup_cnt)
112117 fflush (current_fp );
113118}
114119
120+ #ifdef NEW_DO_USERLOG
121+ #else
115122static void do_process_dup (char * time_str , int dup_cnt )
116123{
117124 do_print_dup (time_str , dup_cnt );
118125 samelog_cnt = 1 ;
119126}
127+ #endif
120128
121129static void do_save_log (char * log_buf , int len )
122130{
@@ -125,6 +133,94 @@ static void do_save_log(char *log_buf, int len)
125133 prev_len = len ;
126134}
127135
136+ #ifdef NEW_DO_USERLOG
137+ static void do_print_drop_begin_message (time_t cur_time )
138+ {
139+ char * tmpstr = " user_logger begins to drop messages due to rate-limiting\n" ;
140+ do_make_prefix (prevtime_str , cur_time );
141+ do_print_msg (prevtime_str , prefix_len , tmpstr , 60 );
142+ }
143+
144+ static void do_print_drop_stat_message (time_t cur_time , int drop_cnt )
145+ {
146+ char tmpbuf [128 ];
147+ int tmplen = sprintf (tmpbuf , " user_logger lost %d messages due to rate-limiting (%d)\n" ,
148+ drop_cnt , loglimit_burst );
149+ do_make_prefix (prevtime_str , cur_time );
150+ do_print_msg (prevtime_str , prefix_len , tmpbuf , tmplen );
151+ }
152+
153+ static bool do_userlog_internal (time_t cur_time , char * body_buf , int len )
154+ {
155+ if (reduction_mode ) {
156+ static time_t samelog_time = 0 ;
157+ static int samelog_cnt = 0 ;
158+ if (len == prev_len && memcmp (body_buf , prev_log , len ) == 0 ) {
159+ samelog_time = cur_time ;
160+ samelog_cnt ++ ; // Just increase the count and save the time
161+ return false;
162+ }
163+
164+ // Two log messages are different. Print the count and the previous time,
165+ // then restart the count.
166+ if (samelog_cnt > 0 ) {
167+ do_make_prefix (prevtime_str , samelog_time );
168+ do_print_dup (prevtime_str , samelog_cnt );
169+ samelog_cnt = 0 ;
170+ }
171+ do_save_log (body_buf , len );
172+ }
173+
174+ do_make_prefix (prevtime_str , cur_time );
175+ do_print_msg (prevtime_str , prefix_len , body_buf , len );
176+ return true;
177+ }
178+
179+ static void do_userlog_basic (char * body_buf , int len )
180+ {
181+ time_t cur_time = time (0 );
182+ (void )do_userlog_internal (cur_time , body_buf , len );
183+ }
184+
185+ static void do_userlog_ratelimit (char * body_buf , int len )
186+ {
187+ static bool drop_mode = false;
188+ static int drop_cnt = 0 ;
189+ static int msg_cnt = 0 ;
190+ static time_t prev_time = 0 ;
191+ time_t cur_time = time (0 );
192+ double time_diff = difftime (cur_time , prev_time );
193+
194+ if (time_diff > (double )loglimit_interval ) {
195+ if (drop_mode ) {
196+ if (drop_cnt > 0 ) {
197+ do_print_drop_stat_message (cur_time , drop_cnt );
198+ drop_cnt = 0 ;
199+ }
200+ drop_mode = false;
201+ }
202+ prev_time = cur_time ;
203+ msg_cnt = 0 ;
204+ } else {
205+ if (drop_mode ) {
206+ drop_cnt ++ ;
207+ return ;
208+ }
209+ }
210+
211+ if (do_userlog_internal (cur_time , body_buf , len )) {
212+ msg_cnt ++ ;
213+ if (msg_cnt >= loglimit_burst ) { // if duplicates remains, print that.
214+ do_print_drop_begin_message (cur_time );
215+ drop_cnt = 0 ;
216+ drop_mode = true;
217+ }
218+ }
219+ }
220+ #endif
221+
222+ #ifdef NEW_DO_USERLOG
223+ #else
128224static void do_userlog (char * body_buf , int len )
129225{
130226 char prefix_buf [200 ];
@@ -211,6 +307,7 @@ static void do_userlog(char *body_buf, int len)
211307 }
212308 }
213309}
310+ #endif
214311
215312static void logger_log (EXTENSION_LOG_LEVEL severity ,
216313 const void * client_cookie ,
@@ -242,7 +339,15 @@ static void logger_log(EXTENSION_LOG_LEVEL severity,
242339 }
243340 }
244341
342+ #ifdef NEW_DO_USERLOG
343+ if (loglimit_interval == 0 ) {
344+ do_userlog_basic (log_buf , len );
345+ } else {
346+ do_userlog_ratelimit (log_buf , len );
347+ }
348+ #else
245349 do_userlog (log_buf , len ); // userlog codes
350+ #endif
246351
247352 if (current_flength >= MAX_LOGFILE_SIZE ) {
248353 fclose (current_fp );
@@ -320,10 +425,13 @@ EXTENSION_ERROR_CODE memcached_extensions_initialize(const char *config,
320425 }
321426 }
322427 if (loglimit_interval != 0 ) {
428+ #ifdef NEW_DO_USERLOG
429+ #else
323430 prev_time = time (0 );
324431 msg_cnt = 0 ;
325432 drop_cnt = 0 ;
326433 drop_mode = false;
434+ #endif
327435 loglimit_burst = DEFAULT_RATELIMIT ;
328436 env = getenv ("UserLogRateLimitBurst" );
329437 if (env != NULL ) {
@@ -337,7 +445,10 @@ EXTENSION_ERROR_CODE memcached_extensions_initialize(const char *config,
337445 if (env != NULL && strcmp (env , "on" ) == 0 )
338446 reduction_mode = true;
339447 if (reduction_mode == true) { // default is false
448+ #ifdef NEW_DO_USERLOG
449+ #else
340450 samelog_cnt = 1 ;
451+ #endif
341452 prev_log [0 ] = 0 ;
342453 prev_len = 0 ;
343454 prevtime_str [0 ] = 0 ;
0 commit comments