1

我正在开发一个需要在多个进程中编写单个日志文件(由其路径标识)的功能。以前,每个进程都用来调用printf终端上的日志流(标准输出)。现在我需要将输出目标更改为文件。所以我尝试使用freopen将标准输出重定向到每个进程中的文件。

freopen(file_path, "a", stdout); //

但似乎效果不佳。缺少一些日志。实现这一目标的常见做法是什么?

顺便说一句,在我们的要求中,应该允许用户在文件和标准输出之间切换日志记录目标,因此当切换回终端时,第一个参数“file_path”可以是 tty。可以打电话freopen(tty, "a", stdout)吗?

4

3 回答 3

2

你有很多选择:

1)最简单的方法是让每个进程简单地独立写入同一个日志。当然,问题是如果任何两个进程同时写入不同的消息,文件就会被打乱。

2)您可以改为让进程将消息发送到一个“主记录器”,然后它会按照收到的顺序一次输出一条消息。“主记录器”可能使用套接字。如果所有进程都在同一台主机上,您可能会改用消息队列或命名管道。

3) 更简单的是,您可以拥有一个系统范围的信号量来确保一次只写入一条消息。

4) 另一种方法是使用开源记录器,例如log4jsyslog-ng

于 2013-04-15T15:56:39.517 回答
1

只要它们小于 PIPE_BUF 字节,在 O_APPEND 模式下的写入就会执行您想要的操作,这通常有足够的空间(大约 4k)。

因此,将新的 freopen()ed 文件设置为行缓冲(下面的_IOLBF),然后确保您的写入包含换行符以刷新缓冲区:

freopen(file_path, "a", stdout);
setvbuf(stdout, (char *)NULL, _IOLBF, 0); // a.k.a. setlinebuf(stdout) under BSD

...

printf("Some log line\n"); // Note the newline!
于 2013-04-15T16:14:12.343 回答
0

Pipe your output to a file handle called, say, output using fprintf. Since file handle's are just pointers, just set output = stdout or output = yourFile. Then every fprintf(output, "sometext") winds up going wherever that handle is set at the moment. You can even have a function to dynamically redirect the output on the fly based upon user input.

于 2013-04-15T16:12:01.857 回答