我想在 C 中实现日志记录功能并将消息记录到标准输出和某些文件中。我想写类似 fprintf(logout, "msg"); 以某种方式声明的 FILE* logout 会将字符串重定向到标准输出和某个文件。是否可以?
3 回答
If this is on Linux, you can open a pipe to the tee
command:
FILE *logout = popen("tee logfile", "w");
您显然需要一个类似FILE
- 的对象,将其写入重定向到两个底层FILE
s (stdout
和日志文件)。标准 C 不允许FILE
以任何方式“子类化”对象,因此这在 C 中是不可能的。但是,GNU libc 可以,因此如果您的程序仅适用于 Linux,您可以通过一些编程来做到这一点。由于这是非常不便携的,因此强烈建议不要这样做。
实现此目的的一种更可移植的方法是写入管道并创建一个进程或线程,该进程或线程从管道读取并写入两个底层文件。例如,假设 POSIX:
FILE *tee_file(FILE *fp1, FILE *fp2)
{
int fds[2];
if (pipe(fds))
return NULL;
switch (fork()) {
case 0: {
char buf[512];
int nread;
FILE *r = fdopen(fds[0], "r");
close(fds[1]);
while ((nread = fread(buf, 1, sizeof buf, r)) {
fwrite(buf, 1, nread, fp1);
fwrite(buf, 1, nread, fp2);
}
_exit(0);
}
case -1:
return NULL;
}
close(fds[0]);
return fdopen(fds[1], "w");
}
/* after calling "fp = tee_file(fp1, fp2)", writes to fp
end up in fp1 and fp2. */
Both approach add a good deal of complication to your program which should be justified by a very good reason. What you want is to use a logging framework that allows writing to multiple outputs (they all do), or write your own as outlined by H2CO3's answer.
你为什么不做你自己的日志功能呢?
int log_fprintf(FILE *stream, const char *restrict fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stream, fmt, args);
va_end(args);
va_start(args, fmt);
int n = vfprintf(stdout, fmt, args);
// conceptually, rather `stderr`, please!
va_end(args);
return n;
}