add resistance on blocking writes to stdout
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7363 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
62bcc9e0fc
commit
a2d8262289
|
@ -69,6 +69,8 @@ struct listener {
|
||||||
switch_hash_t *event_hash;
|
switch_hash_t *event_hash;
|
||||||
switch_thread_rwlock_t *rwlock;
|
switch_thread_rwlock_t *rwlock;
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
|
int lost_events;
|
||||||
|
int lost_logs;
|
||||||
struct listener *next;
|
struct listener *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,7 +108,19 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l
|
||||||
if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) {
|
if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) {
|
||||||
char *data = strdup(node->data);
|
char *data = strdup(node->data);
|
||||||
if (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 {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
||||||
}
|
}
|
||||||
|
@ -153,7 +167,21 @@ static void event_handler(switch_event_t *event)
|
||||||
|
|
||||||
if (send) {
|
if (send) {
|
||||||
if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
|
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 {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ static switch_memory_pool_t *module_pool = NULL;
|
||||||
static switch_hash_t *log_hash = NULL;
|
static switch_hash_t *log_hash = NULL;
|
||||||
static uint32_t all_level = 0;
|
static uint32_t all_level = 0;
|
||||||
static int32_t hard_log_level = SWITCH_LOG_DEBUG;
|
static int32_t hard_log_level = SWITCH_LOG_DEBUG;
|
||||||
|
static int32_t failed_write = 0;
|
||||||
static void del_mapping(char *var)
|
static void del_mapping(char *var)
|
||||||
{
|
{
|
||||||
switch_core_hash_insert(log_hash, var, NULL);
|
switch_core_hash_insert(log_hash, var, NULL);
|
||||||
|
@ -147,6 +147,36 @@ static switch_status_t config_logger(void)
|
||||||
return SWITCH_STATUS_SUCCESS;
|
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)
|
static switch_status_t switch_console_logger(const switch_log_node_t *node, switch_log_level_t level)
|
||||||
{
|
{
|
||||||
FILE *handle;
|
FILE *handle;
|
||||||
|
@ -155,6 +185,21 @@ static switch_status_t switch_console_logger(const switch_log_node_t *node, swit
|
||||||
return SWITCH_STATUS_SUCCESS;
|
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) {
|
if (level > hard_log_level) {
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -178,6 +223,16 @@ static switch_status_t switch_console_logger(const switch_log_node_t *node, swit
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok) {
|
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) {
|
if (COLORIZE) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
SetConsoleTextAttribute(hStdout, COLORS[node->level]);
|
SetConsoleTextAttribute(hStdout, COLORS[node->level]);
|
||||||
|
@ -213,19 +268,21 @@ SWITCH_STANDARD_API(console_api_function)
|
||||||
|
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 1) {
|
||||||
err = "missing arg";
|
err = "missing arg";
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcasecmp(argv[0], "loglevel")) {
|
if (!strcasecmp(argv[0], "loglevel")) {
|
||||||
int level;
|
int level = hard_log_level;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
if (*argv[1] > 47 && *argv[1] < 58) {
|
if (*argv[1] > 47 && *argv[1] < 58) {
|
||||||
level = atoi(argv[1]);
|
level = atoi(argv[1]);
|
||||||
} else {
|
} else {
|
||||||
level = switch_log_str2level(argv[1]);
|
level = switch_log_str2level(argv[1]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (level == SWITCH_LOG_INVALID) {
|
if (level == SWITCH_LOG_INVALID) {
|
||||||
stream->write_function(stream, "-ERR syntax error, console log level not set!\n");
|
stream->write_function(stream, "-ERR syntax error, console log level not set!\n");
|
||||||
|
@ -235,7 +292,9 @@ SWITCH_STANDARD_API(console_api_function)
|
||||||
}
|
}
|
||||||
goto end;
|
goto end;
|
||||||
} else if (!strcasecmp(argv[0], "colorize")) {
|
} else if (!strcasecmp(argv[0], "colorize")) {
|
||||||
|
if (argc > 1) {
|
||||||
COLORIZE = switch_true(argv[1]);
|
COLORIZE = switch_true(argv[1]);
|
||||||
|
}
|
||||||
stream->write_function(stream, "+OK console color %s\n", COLORIZE ? "enabled" : "disabled");
|
stream->write_function(stream, "+OK console color %s\n", COLORIZE ? "enabled" : "disabled");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
|
@ -647,8 +647,13 @@ SWITCH_DECLARE(switch_status_t) switch_event_dup(switch_event_t **event, switch_
|
||||||
hp2 = (*event)->headers;
|
hp2 = (*event)->headers;
|
||||||
|
|
||||||
for (hp = todup->headers; hp; hp = hp->next) {
|
for (hp = todup->headers; hp; hp = hp->next) {
|
||||||
if ((header = ALLOC(sizeof(*header))) == 0) {
|
void *pop;
|
||||||
return SWITCH_STATUS_MEMERR;
|
|
||||||
|
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));
|
memset(header, 0, sizeof(*header));
|
||||||
|
@ -662,7 +667,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_dup(switch_event_t **event, switch_
|
||||||
(*event)->headers = header;
|
(*event)->headers = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
last = header;
|
(*event)->last_header = last = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (todup->body) {
|
if (todup->body) {
|
||||||
|
|
|
@ -253,8 +253,28 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char
|
||||||
} else {
|
} else {
|
||||||
if (level == SWITCH_LOG_CONSOLE || !LOG_QUEUE || !THREAD_RUNNING) {
|
if (level == SWITCH_LOG_CONSOLE || !LOG_QUEUE || !THREAD_RUNNING) {
|
||||||
if (handle) {
|
if (handle) {
|
||||||
|
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);
|
fprintf(handle, "%s", data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
free(data);
|
free(data);
|
||||||
} else if (level <= MAX_LEVEL) {
|
} else if (level <= MAX_LEVEL) {
|
||||||
switch_log_node_t *node;
|
switch_log_node_t *node;
|
||||||
|
|
Loading…
Reference in New Issue