[Freeswitch-svn] [commit] r7363 - in freeswitch/trunk/src: . mod/event_handlers/mod_event_socket mod/loggers/mod_console

Freeswitch SVN anthm at freeswitch.org
Fri Jan 25 18:09:33 EST 2008


Author: anthm
Date: Fri Jan 25 18:09:33 2008
New Revision: 7363

Modified:
   freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
   freeswitch/trunk/src/mod/loggers/mod_console/mod_console.c
   freeswitch/trunk/src/switch_event.c
   freeswitch/trunk/src/switch_log.c

Log:
add resistance on blocking writes to stdout

Modified: freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c	(original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c	Fri Jan 25 18:09:33 2008
@@ -69,6 +69,8 @@
 	switch_hash_t *event_hash;
 	switch_thread_rwlock_t *rwlock;
 	switch_core_session_t *session;
+	int lost_events;
+	int lost_logs;
 	struct listener *next;
 };
 
@@ -106,7 +108,19 @@
 		if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) {
 			char *data = strdup(node->data);
 			if (data) {
-				switch_queue_push(l->log_queue, data);
+				if (switch_queue_trypush(l->log_queue, data) == SWITCH_STATUS_SUCCESS) {
+					int ll =  l->lost_logs;
+					switch_event_t *event;
+					l->lost_logs = 0;
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Lost %d log lines!\n", ll);
+					if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
+						switch_event_add_header(event, SWITCH_STACK_BOTTOM, "info", "lost %d log lines", ll);
+						switch_event_fire(&event);
+					}
+				} else {
+					switch_safe_free(data);
+					l->lost_logs++;
+				}
 			} else {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
 			}
@@ -153,7 +167,21 @@
 
 		if (send) {
 			if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
-				switch_queue_push(l->event_queue, clone);
+				if (switch_queue_trypush(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) {
+					if (l->lost_events) {
+						int le = l->lost_events;
+						l->lost_events = 0;
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Lost %d events!\n", le);
+						clone = NULL;
+						if (switch_event_create(&clone, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
+							switch_event_add_header(clone, SWITCH_STACK_BOTTOM, "info", "lost %d events", le);
+							switch_event_fire(&clone);
+						}
+					}
+				} else {
+					l->lost_events++;
+					switch_event_destroy(&clone);
+				}
 			} else {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
 			}

Modified: freeswitch/trunk/src/mod/loggers/mod_console/mod_console.c
==============================================================================
--- freeswitch/trunk/src/mod/loggers/mod_console/mod_console.c	(original)
+++ freeswitch/trunk/src/mod/loggers/mod_console/mod_console.c	Fri Jan 25 18:09:33 2008
@@ -62,7 +62,7 @@
 static switch_hash_t *log_hash = NULL;
 static uint32_t all_level = 0;
 static int32_t hard_log_level = SWITCH_LOG_DEBUG;
-
+static int32_t failed_write = 0;
 static void del_mapping(char *var)
 {
 	switch_core_hash_insert(log_hash, var, NULL);
@@ -147,6 +147,36 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
+static int can_write(FILE *handle, int ms)
+{
+#ifndef WIN32
+	int aok = 1;
+	fd_set can_write;
+	int fd;
+	struct timeval to;
+	int sec, usec;
+
+	sec = ms / 1000;
+	usec = ms % 1000;
+
+	fd = fileno(handle);
+	memset(&to, 0, sizeof(to));
+	FD_SET(fd, &can_write);
+	to.tv_sec = sec;
+	to.tv_usec = usec;
+	if (select(fd+1, NULL, &can_write, NULL, &to) > 0) {
+		aok = FD_ISSET(fd, &can_write);
+	} else {
+		aok = 0;
+	}
+	
+	return aok;
+#else 
+	return 1;
+#endif
+}
+
+
 static switch_status_t switch_console_logger(const switch_log_node_t *node, switch_log_level_t level)
 {
 	FILE *handle;
@@ -155,6 +185,21 @@
 		return SWITCH_STATUS_SUCCESS;
 	}
 
+	if (failed_write) {
+		if ((handle = switch_core_data_channel(SWITCH_CHANNEL_ID_LOG))) {
+			int aok = can_write(handle, 5);
+			if (aok) {
+				const char *msg = "Failed to write to the console! Logging disabled! RE-enable with the 'console loglevel' command\n";
+				if (COLORIZE) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s%s%s",  COLORS[1], msg, SWITCH_SEQ_DEFAULT_COLOR);
+				} else {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s", msg);
+				}
+				failed_write = 0;
+			}
+		}
+	}
+
 	if (level > hard_log_level) {
 		return SWITCH_STATUS_SUCCESS;
 	}
@@ -162,7 +207,7 @@
 	if ((handle = switch_core_data_channel(SWITCH_CHANNEL_ID_LOG))) {
         size_t mask = 0;
         size_t ok = 0;
-    
+		
         ok = switch_log_check_mask(all_level, level);
         
 		if (log_hash) {
@@ -178,6 +223,16 @@
 		}
 
 		if (ok) {
+#ifndef WIN32
+			int aok = can_write(handle, 2000);
+			
+			if (!aok) {
+				hard_log_level = 0;
+				failed_write++;
+				return SWITCH_STATUS_SUCCESS;
+			}
+#endif
+
 			if (COLORIZE) {
 #ifdef WIN32
 				SetConsoleTextAttribute(hStdout, COLORS[node->level]);
@@ -213,18 +268,20 @@
 
 	if (argc > 0) {
 
-		if (argc < 2) {
+		if (argc < 1) {
 			err = "missing arg";
 			goto end;
 		}
 
 		if (!strcasecmp(argv[0], "loglevel")) {
-			int level;
+			int level = hard_log_level;
 			
-			if (*argv[1] > 47 && *argv[1] < 58) {
-				level = atoi(argv[1]);
-			} else {
-				level = switch_log_str2level(argv[1]);
+			if (argc > 1) {
+				if (*argv[1] > 47 && *argv[1] < 58) {
+					level = atoi(argv[1]);
+				} else {
+					level = switch_log_str2level(argv[1]);
+				}
 			}
 
 			if (level == SWITCH_LOG_INVALID) {
@@ -235,7 +292,9 @@
 			}
 			goto end;
 		} else if (!strcasecmp(argv[0], "colorize")) {
-			COLORIZE = switch_true(argv[1]);
+			if (argc > 1) {
+				COLORIZE = switch_true(argv[1]);
+			}
 			stream->write_function(stream,  "+OK console color %s\n", COLORIZE ? "enabled" : "disabled");
 			goto end;
 		}

Modified: freeswitch/trunk/src/switch_event.c
==============================================================================
--- freeswitch/trunk/src/switch_event.c	(original)
+++ freeswitch/trunk/src/switch_event.c	Fri Jan 25 18:09:33 2008
@@ -647,8 +647,13 @@
 	hp2 = (*event)->headers;
 
 	for (hp = todup->headers; hp; hp = hp->next) {
-		if ((header = ALLOC(sizeof(*header))) == 0) {
-			return SWITCH_STATUS_MEMERR;
+		void *pop;
+		
+		if (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) {
+			header = (switch_event_header_t *) pop;
+		} else {
+			header = ALLOC(sizeof(*header));
+			switch_assert(header);
 		}
 
 		memset(header, 0, sizeof(*header));
@@ -662,7 +667,7 @@
 			(*event)->headers = header;
 		}
 
-		last = header;
+		(*event)->last_header = last = header;
 	}
 
 	if (todup->body) {

Modified: freeswitch/trunk/src/switch_log.c
==============================================================================
--- freeswitch/trunk/src/switch_log.c	(original)
+++ freeswitch/trunk/src/switch_log.c	Fri Jan 25 18:09:33 2008
@@ -253,7 +253,27 @@
 		} else {
 			if (level == SWITCH_LOG_CONSOLE || !LOG_QUEUE || !THREAD_RUNNING) {
 				if (handle) {
-					fprintf(handle, "%s", data);
+					int aok = 1;
+#ifndef WIN32
+
+					fd_set can_write;
+					int fd;
+					struct timeval to;
+					
+					fd = fileno(handle);
+					memset(&to, 0, sizeof(to));
+					FD_SET(fd, &can_write);
+					to.tv_sec = 0;
+					to.tv_usec = 5000;
+					if (select(fd+1, NULL, &can_write, NULL, &to) > 0) {
+						aok = FD_ISSET(fd, &can_write);
+					} else {
+						aok = 0;
+					}
+#endif
+					if (aok) {
+						fprintf(handle, "%s", data);
+					}
 				}
 				free(data);
 			} else if (level <= MAX_LEVEL) {



More information about the Freeswitch-svn mailing list