Hi All,

The Kannel has made me 2G log during a night and it stopped because of limits 
of filesystem. Of course it was abnormal operation and usually a Kannel log
file isn't so big. But I have modified the logging system of Kannel and it
won't happen again. If the size of a log file grows above 100Mb it renames
it and start writing into a new one. My another modification in the logging
system modify the time precision to milliseconds. I have too much log lines
with the same timestamp, I suppose it is very useful at bursts.

Zoli

--
Zoltan Dudas
Software Engineer
SEI Hungary
Office  +36-52-889-532 Ext: 2032
Fax     +36-52-889-599
Email   [EMAIL PROTECTED]
URL     www.sei-it.com



? log.diff
Index: gwlib/log.c
===================================================================
RCS file: /home/cvs/gateway/gwlib/log.c,v
retrieving revision 1.48
diff -u -r1.48 log.c
--- gwlib/log.c	8 Aug 2004 21:46:51 -0000	1.48
+++ gwlib/log.c	13 Oct 2004 09:34:26 -0000
@@ -107,6 +107,7 @@
     int minimum_output_level;
     char filename[FILENAME_MAX + 1]; /* to allow re-open */
     enum excl_state exclusive;
+	Mutex *mutex;
 } logfiles[MAX_LOGFILES];
 static int num_logfiles = 0;
 
@@ -160,6 +161,7 @@
     logfiles[num_logfiles].file = stderr;
     logfiles[num_logfiles].minimum_output_level = GW_DEBUG;
     logfiles[num_logfiles].exclusive = GW_NON_EXCL;
+	logfiles[num_logfiles].mutex= mutex_create();
     ++num_logfiles;
 }
 
@@ -244,7 +246,8 @@
     for (i = 0; i < num_logfiles; ++i) {
         if (logfiles[i].file != stderr) {
             found = 0;
-
+			
+			mutex_lock(logfiles[i].mutex);
             /*
              * Reverse seek for allready reopened logfile.
              * If we find a previous file descriptor for the same file
@@ -266,6 +269,7 @@
                 error(errno, "Couldn't re-open logfile `%s'.",
                       logfiles[i].filename);
             }
+			mutex_unlock(logfiles[i].mutex);
         }
     }
 
@@ -290,10 +294,12 @@
 
     while (num_logfiles > 0) {
         --num_logfiles;
+		mutex_lock(logfiles[num_logfiles].mutex);
         if (logfiles[num_logfiles].file != stderr &&
             logfiles[num_logfiles].file != NULL)
             fclose(logfiles[num_logfiles].file);
         logfiles[num_logfiles].file = NULL;
+		mutex_unlock(logfiles[num_logfiles].mutex);
     }
 
     /*
@@ -351,6 +357,7 @@
     logfiles[num_logfiles].file = f;
     logfiles[num_logfiles].minimum_output_level = level;
     logfiles[num_logfiles].exclusive = excl;
+	logfiles[num_logfiles].mutex= mutex_create();
     strcpy(logfiles[num_logfiles].filename, filename);
     ++num_logfiles;
     info(0, "Added logfile `%s' with level `%d'.", filename, level);
@@ -373,23 +380,23 @@
     };
     static int tab_size = sizeof(tab) / sizeof(tab[0]);
     time_t t;
+	struct timeval timeval;
     struct tm tm;
     char *p, prefix[1024];
     long tid, pid;
     
     p = prefix;
-
+ 
     if (with_timestamp) {
-        time(&t);
+	gettimeofday(&timeval,NULL);
 #if LOG_TIMESTAMP_LOCALTIME
-        tm = gw_localtime(t);
+	localtime_r((time_t*)&timeval.tv_sec,&tm);
 #else
-        tm = gw_gmtime(t);
+	gmtime_r((time_t*)&timeval.tv_sec,&tm);
 #endif
-        sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d ",
+        sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d.%04d ",
         tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
-        tm.tm_hour, tm.tm_min, tm.tm_sec);
-    
+        tm.tm_hour, tm.tm_min, tm.tm_sec, timeval.tv_usec/1000);
         p = strchr(p, '\0');
     }
 
@@ -464,6 +471,40 @@
     }
 }
 
+/* 
+ * Generate filename for log file
+ */
+char *log_gen_new_filename(const char *oldfilename)
+{
+	time_t t;
+	struct tm tm;
+	time(&t);
+	tm = gw_localtime(t);
+	char *new_filename= gw_malloc(FILENAME_MAX + 1);
+	snprintf(new_filename,FILENAME_MAX,"%s.%04d-%02d-%02d_%02d%02d%02d",
+		oldfilename,
+		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+		tm.tm_hour, tm.tm_min, tm.tm_sec);
+	return new_filename;
+}
+
+/*
+ * Exchange a too big log file to an empty one
+ */
+void log_exchange(int log_file_idx)
+{
+	FILE *lfile= logfiles[log_file_idx].file;
+	if (lfile != stderr && lseek(fileno(lfile),0,SEEK_CUR) > 100*1024*1024 /* 100M */) {
+		fclose(logfiles[log_file_idx].file);
+		char *new_filename= log_gen_new_filename(logfiles[log_file_idx].filename);
+		rename(logfiles[log_file_idx].filename,new_filename);
+		gw_free(new_filename);
+		logfiles[log_file_idx].file = fopen(logfiles[log_file_idx].filename, "a");
+		if (logfiles[log_file_idx].file == NULL) {
+			error(errno, "Couldn't re-open logfile `%s'.",logfiles[log_file_idx].filename);
+		}
+    }
+}	
 
 /*
  * Almost all of the message printing functions are identical, except for
@@ -490,9 +531,12 @@
 		if (logfiles[i].exclusive == GW_NON_EXCL && \
                     level >= logfiles[i].minimum_output_level && \
                     logfiles[i].file != NULL) { \
+				mutex_lock(logfiles[i].mutex); \
+				log_exchange(i); \
 		        va_start(args, fmt); \
 		        output(logfiles[i].file, buf, args); \
 		        va_end(args); \
+				mutex_unlock(logfiles[i].mutex); \
 		} \
 	    } \
             if (writers != NULL) \
@@ -519,9 +563,12 @@
             if (logfiles[e].exclusive == GW_EXCL && \
                 level >= logfiles[e].minimum_output_level && \
                 logfiles[e].file != NULL) { \
+				mutex_lock(logfiles[e].mutex); \
+				log_exchange(e); \
                 va_start(args, fmt); \
                 output(logfiles[e].file, buf, args); \
                 va_end(args); \
+				mutex_unlock(logfiles[e].mutex); \
             } \
             if (writers != NULL) \
               list_remove_producer(writers); \

Reply via email to