Удивительно, но ни один из популярных контейнерных тулов этого не делает.
docker service logs, kubectl logs, stern, kubetail, k9s — все они просто перемешивают потоки по мере поступления. Стандартный костыль – прогонять вывод через | sort 🙃Чтобы сделать это правильно, нельзя просто сразу печатать строку лога: более медленный поток может прислать запись с более ранним таймстампом. Нужно понять, когда её печатать безопасно.
Для новой команды
uc logs используется следующий подход:1. Low watermark
Трекать минимальный timestamp среди всех лог-стримов и безопасно печатать буферизированные логи с таймстампами ниже этой метки.
watermark = min(latest_timestamp for each stream)
sort and print all buffered logs where timestamp < watermark
2. Heartbeat-таймстампы
Что если контейнер замолчит? Весь поток залипнет, потому что watermark больше не будет сдвигаться.
Решение: периодически отправлять пустые heartbeat-записи с текущим timestamp от серверов. Это своего рода обещание: «У меня нет логов старше этого».
Это позволяет клиенту продвигать watermark сразу, не блокируя вывод. Интервал в 500 мс – 1 с работает хорошо на практике.
Что насчёт несинхронизированных часов?
Много тут не сделать, если не плодить лишнюю сложность. Просто детектируйте ситуацию, предупредите пользователя, и на этом всё.
👉 DevOps Portal