Skip to content

Commit 1aec2bc

Browse files
Backport #88814 to 25.9: Catch exceptions when async logging fails to prevent program aborts
1 parent 8c20526 commit 1aec2bc

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
@@ -488,20 +488,40 @@ void OwnAsyncSplitChannel::runChannel(size_t i)
488488

489489
while (is_open)
490490
{
491-
log_notification(notification);
492-
notification = queues[i]->waitDequeueMessage();
491+
try
492+
{
493+
log_notification(notification);
494+
notification = queues[i]->waitDequeueMessage();
495+
}
496+
catch (...)
497+
{
498+
const std::string & exception_message = getCurrentExceptionMessage(true);
499+
writeRetry(STDERR_FILENO, "Cannot log message in OwnAsyncSplitChannel channel: ");
500+
writeRetry(STDERR_FILENO, exception_message.data(), exception_message.size());
501+
writeRetry(STDERR_FILENO, "\n");
502+
}
493503
}
494504

495-
/// Flush everything before closing
496-
log_notification(notification);
497-
498-
/// We want to process only what's currently in the queue and not block other logging
499-
auto queue = queues[i]->getCurrentQueueAndClear();
500-
while (!queue.empty())
505+
try
501506
{
502-
notification = queue.front();
503-
queue.pop_front();
507+
/// Flush everything before closing
504508
log_notification(notification);
509+
510+
/// We want to process only what's currently in the queue and not block other logging
511+
auto queue = queues[i]->getCurrentQueueAndClear();
512+
while (!queue.empty())
513+
{
514+
notification = queue.front();
515+
queue.pop_front();
516+
log_notification(notification);
517+
}
518+
}
519+
catch (...)
520+
{
521+
const std::string & exception_message = getCurrentExceptionMessage(true);
522+
writeRetry(STDERR_FILENO, "Cannot flush messages in OwnAsyncSplitChannel channel: ");
523+
writeRetry(STDERR_FILENO, exception_message.data(), exception_message.size());
524+
writeRetry(STDERR_FILENO, "\n");
505525
}
506526
}
507527

@@ -531,40 +551,59 @@ void OwnAsyncSplitChannel::runTextLog()
531551
auto notification = text_log_queue.waitDequeueMessage();
532552
while (is_open)
533553
{
534-
if (flush_text_logs)
554+
try
535555
{
536-
auto text_log_locked = text_log.lock();
537-
if (!text_log_locked)
538-
return;
556+
if (flush_text_logs)
557+
{
558+
auto text_log_locked = text_log.lock();
559+
if (!text_log_locked)
560+
return;
539561

540-
if (notification)
541-
log_notification(notification, text_log_locked);
562+
if (notification)
563+
log_notification(notification, text_log_locked);
542564

543-
flush_queue(text_log_locked);
565+
flush_queue(text_log_locked);
544566

545-
flush_text_logs = false;
546-
flush_text_logs.notify_all();
567+
flush_text_logs = false;
568+
flush_text_logs.notify_all();
569+
}
570+
else if (notification)
571+
{
572+
auto text_log_locked = text_log.lock();
573+
if (!text_log_locked)
574+
return;
575+
log_notification(notification, text_log_locked);
576+
}
577+
578+
notification = text_log_queue.waitDequeueMessage();
547579
}
548-
else if (notification)
580+
catch (...)
549581
{
550-
auto text_log_locked = text_log.lock();
551-
if (!text_log_locked)
552-
return;
553-
log_notification(notification, text_log_locked);
582+
const std::string & exception_message = getCurrentExceptionMessage(true);
583+
writeRetry(STDERR_FILENO, "Cannot log message in OwnAsyncSplitChannel text log: ");
584+
writeRetry(STDERR_FILENO, exception_message.data(), exception_message.size());
585+
writeRetry(STDERR_FILENO, "\n");
554586
}
555-
556-
notification = text_log_queue.waitDequeueMessage();
557587
}
558588

559-
/// We want to flush everything already in the queue before closing so all messages are logged
560-
auto text_log_locked = text_log.lock();
561-
if (!text_log_locked)
562-
return;
563-
564-
if (notification)
565-
log_notification(notification, text_log_locked);
589+
try
590+
{
591+
/// We want to flush everything already in the queue before closing so all messages are logged
592+
auto text_log_locked = text_log.lock();
593+
if (!text_log_locked)
594+
return;
566595

567-
flush_queue(text_log_locked);
596+
if (notification)
597+
log_notification(notification, text_log_locked);
598+
flush_queue(text_log_locked);
599+
}
600+
catch (...)
601+
{
602+
const std::string & exception_message = getCurrentExceptionMessage(true);
603+
writeRetry(STDERR_FILENO, "Cannot flush queue in OwnAsyncSplitChannel text log: ");
604+
writeRetry(STDERR_FILENO, exception_message.data(), exception_message.size());
605+
writeRetry(STDERR_FILENO, "\n");
606+
}
568607
}
569608

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

0 commit comments

Comments
 (0)