cout << std::flush会让我的println(..) 在Docker日志中被刷新。我尝试了两种替代方法:setvbuf和 cout << std::unitbuf,但都没有成功。
我的C++程序在一个 docker-compose 里面运行。
只要在它们之后执行一个 cout << std::flush,我就可以把它的 println 调用输出到Docker日志中:
println("Hello! I'm tempete C++ module, starting...");
cout << std::flush;
否则,我的程序的 stdout 不会被刷新。这个方法可行,但很繁琐。
为了避免这种情况,在程序开头我尝试了以下这些语句(在不同的执行中)。但都没有效果。
cout << std::unitbuf;
或者
setvbuf(stdout, NULL, _IONBF, 0);
有什么单一的函数调用 / 语句,能够让我要在每次 println 之后都不再执行 cout << std::flush 吗?
如果你尝试这个简单的程序:
#include <print>
int main(int argc, char* argv[]) {
println("Hello! I'm tempete C++ module, starting...");
while(true);
return 0;
}
然后在与其他语言编写的程序一起运行一个 docker compose up | grep Hello,你会看到:
galerne-beaufort | Hello! I'm galerne Rust module, starting...
brise-beaufort | 06:46:53.216 [main] INFO fr.beaufort.brise.application.BriseApplication -- Hello! I'm brise Java module, starting...
orchestrator-beaufort | 06:46:53.268 [main] INFO fr.beaufort.orchestrator.application.OrchestratorApplication -- Hello! I'm orchestrator Java module, starting...
ponant-beaufort | Hello! I'm ponant Typescript module, starting...
Java由 Logger Log4j、TypeScript通过 console.log(...)、Rust通过 println(...) 宏,它们都能够输出到Docker日志,但仅凭C++及其 println(...) 自己则不行。
如果你在C++的 println 之后再加一个 std::cout << std::flush;,你就会看到这条消息。
tempete-beaufort | Hello! I'm tempete C++ module, starting...
galerne-beaufort | Hello! I'm galerne Rust module, starting...
brise-beaufort | 06:48:19.873 [main] INFO fr.beaufort.brise.application.BriseApplication -- Hello! I'm brise Java module, starting...
orchestrator-beaufort | 06:48:19.904 [main] INFO fr.beaufort.orchestrator.application.OrchestratorApplication -- Hello! I'm orchestrator Java module, starting...
ponant-beaufort | Hello! I'm ponant Typescript module, starting...
所以,在我的想法里,这不是Docker的问题,而是C++的一个怪异之处,因为 println(...),按它的名字来看,应该写入一个 \n(它确实会写入),这在某种程度上应该会自动引发一次刷新。
但如果 std::cout 与 stdout 并非真正统一,这可能就能解释清楚。
解决方案
@Someprogrammerdude led me to the solution:
In docker-compose.yaml ask the container to act as a tty, by a tty: true.
tempete:
build:
context: apps/tempete
dockerfile: Dockerfile
container_name: tempete-beaufort
tty: true
environment:
- KAFKA_BOOTSTRAP_SERVERS_CONFIG=kafka:9092
depends_on:
kafka:
condition: service_healthy
这解决了问题,并避免了手动刷新。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。