Skip to content

Commit 0da2a01

Browse files
authored
Merge pull request ClickHouse#88835 from ClickHouse/backport/25.8/88814
Backport ClickHouse#88814 to 25.8: Catch exceptions when async logging fails to prevent program aborts
2 parents ab168b0 + c37f56c commit 0da2a01

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

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

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

@@ -530,40 +550,59 @@ void OwnAsyncSplitChannel::runTextLog()
530550
auto notification = text_log_queue.waitDequeueMessage();
531551
while (is_open)
532552
{
533-
if (flush_text_logs)
553+
try
534554
{
535-
auto text_log_locked = text_log.lock();
536-
if (!text_log_locked)
537-
return;
555+
if (flush_text_logs)
556+
{
557+
auto text_log_locked = text_log.lock();
558+
if (!text_log_locked)
559+
return;
538560

539-
if (notification)
540-
log_notification(notification, text_log_locked);
561+
if (notification)
562+
log_notification(notification, text_log_locked);
541563

542-
flush_queue(text_log_locked);
564+
flush_queue(text_log_locked);
543565

544-
flush_text_logs = false;
545-
flush_text_logs.notify_all();
566+
flush_text_logs = false;
567+
flush_text_logs.notify_all();
568+
}
569+
else if (notification)
570+
{
571+
auto text_log_locked = text_log.lock();
572+
if (!text_log_locked)
573+
return;
574+
log_notification(notification, text_log_locked);
575+
}
576+
577+
notification = text_log_queue.waitDequeueMessage();
546578
}
547-
else if (notification)
579+
catch (...)
548580
{
549-
auto text_log_locked = text_log.lock();
550-
if (!text_log_locked)
551-
return;
552-
log_notification(notification, text_log_locked);
581+
const std::string & exception_message = getCurrentExceptionMessage(true);
582+
writeRetry(STDERR_FILENO, "Cannot log message in OwnAsyncSplitChannel text log: ");
583+
writeRetry(STDERR_FILENO, exception_message.data(), exception_message.size());
584+
writeRetry(STDERR_FILENO, "\n");
553585
}
554-
555-
notification = text_log_queue.waitDequeueMessage();
556586
}
557587

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

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

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

0 commit comments

Comments
 (0)