Skip to content

Commit bcaf181

Browse files
Backport #88814 to 25.7: Catch exceptions when async logging fails to prevent program aborts
1 parent d41ee02 commit bcaf181

File tree

1 file changed

+73
-34
lines changed

1 file changed

+73
-34
lines changed

src/Loggers/OwnSplitChannel.cpp

Lines changed: 73 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -434,20 +434,40 @@ void OwnAsyncSplitChannel::runChannel(size_t i)
434434

435435
while (is_open)
436436
{
437-
log_notification(notification);
438-
notification = queues[i]->waitDequeueMessage();
437+
try
438+
{
439+
log_notification(notification);
440+
notification = queues[i]->waitDequeueMessage();
441+
}
442+
catch (...)
443+
{
444+
const std::string & exception_message = getCurrentExceptionMessage(true);
445+
writeRetry(STDERR_FILENO, "Cannot log message in OwnAsyncSplitChannel channel: ");
446+
writeRetry(STDERR_FILENO, exception_message.data(), exception_message.size());
447+
writeRetry(STDERR_FILENO, "\n");
448+
}
439449
}
440450

441-
/// Flush everything before closing
442-
log_notification(notification);
443-
444-
/// We want to process only what's currently in the queue and not block other logging
445-
auto queue = queues[i]->getCurrentQueueAndClear();
446-
while (!queue.empty())
451+
try
447452
{
448-
notification = queue.front();
449-
queue.pop_front();
453+
/// Flush everything before closing
450454
log_notification(notification);
455+
456+
/// We want to process only what's currently in the queue and not block other logging
457+
auto queue = queues[i]->getCurrentQueueAndClear();
458+
while (!queue.empty())
459+
{
460+
notification = queue.front();
461+
queue.pop_front();
462+
log_notification(notification);
463+
}
464+
}
465+
catch (...)
466+
{
467+
const std::string & exception_message = getCurrentExceptionMessage(true);
468+
writeRetry(STDERR_FILENO, "Cannot flush messages in OwnAsyncSplitChannel channel: ");
469+
writeRetry(STDERR_FILENO, exception_message.data(), exception_message.size());
470+
writeRetry(STDERR_FILENO, "\n");
451471
}
452472
}
453473

@@ -477,40 +497,59 @@ void OwnAsyncSplitChannel::runTextLog()
477497
auto notification = text_log_queue.waitDequeueMessage();
478498
while (is_open)
479499
{
480-
if (flush_text_logs)
500+
try
481501
{
482-
auto text_log_locked = text_log.lock();
483-
if (!text_log_locked)
484-
return;
502+
if (flush_text_logs)
503+
{
504+
auto text_log_locked = text_log.lock();
505+
if (!text_log_locked)
506+
return;
485507

486-
if (notification)
487-
log_notification(notification, text_log_locked);
508+
if (notification)
509+
log_notification(notification, text_log_locked);
488510

489-
flush_queue(text_log_locked);
511+
flush_queue(text_log_locked);
490512

491-
flush_text_logs = false;
492-
flush_text_logs.notify_all();
513+
flush_text_logs = false;
514+
flush_text_logs.notify_all();
515+
}
516+
else if (notification)
517+
{
518+
auto text_log_locked = text_log.lock();
519+
if (!text_log_locked)
520+
return;
521+
log_notification(notification, text_log_locked);
522+
}
523+
524+
notification = text_log_queue.waitDequeueMessage();
493525
}
494-
else if (notification)
526+
catch (...)
495527
{
496-
auto text_log_locked = text_log.lock();
497-
if (!text_log_locked)
498-
return;
499-
log_notification(notification, text_log_locked);
528+
const std::string & exception_message = getCurrentExceptionMessage(true);
529+
writeRetry(STDERR_FILENO, "Cannot log message in OwnAsyncSplitChannel text log: ");
530+
writeRetry(STDERR_FILENO, exception_message.data(), exception_message.size());
531+
writeRetry(STDERR_FILENO, "\n");
500532
}
501-
502-
notification = text_log_queue.waitDequeueMessage();
503533
}
504534

505-
/// We want to flush everything already in the queue before closing so all messages are logged
506-
auto text_log_locked = text_log.lock();
507-
if (!text_log_locked)
508-
return;
509-
510-
if (notification)
511-
log_notification(notification, text_log_locked);
535+
try
536+
{
537+
/// We want to flush everything already in the queue before closing so all messages are logged
538+
auto text_log_locked = text_log.lock();
539+
if (!text_log_locked)
540+
return;
512541

513-
flush_queue(text_log_locked);
542+
if (notification)
543+
log_notification(notification, text_log_locked);
544+
flush_queue(text_log_locked);
545+
}
546+
catch (...)
547+
{
548+
const std::string & exception_message = getCurrentExceptionMessage(true);
549+
writeRetry(STDERR_FILENO, "Cannot flush queue in OwnAsyncSplitChannel text log: ");
550+
writeRetry(STDERR_FILENO, exception_message.data(), exception_message.size());
551+
writeRetry(STDERR_FILENO, "\n");
552+
}
514553
}
515554

516555
void OwnAsyncSplitChannel::setChannelProperty(const std::string & channel_name, const std::string & name, const std::string & value)

0 commit comments

Comments
 (0)