Reputation: 2098
I'm working on a feature which requires writing a single log file(identified by its path) in multiple processes. Previously, each process used to call printf
to stream the log on terminal(standard output). Now I need to change the output destination to a file. So I tried using freopen
to redirect the stdout to the file in each process.
freopen(file_path, "a", stdout); //
But it seems it doesn't work well. Some log is missing. What's the common practice to achieve this ?
B.T.W In our requirement, the user should be allowed to switch logging destination between file and standard output, so the first argument "file_path" could be tty when switched back to terminal. Is that OK to call freopen(tty, "a", stdout)
?
Upvotes: 1
Views: 2598
Reputation: 58589
Writes in O_APPEND mode will do what you want as long as they are less than PIPE_BUF bytes, which is usually plenty of room (about 4k).
So, set the newly freopen()ed file to line buffered (_IOLBF below), and then make sure your writes contain a newline to flush the buffer:
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!
Upvotes: 1
Reputation: 14900
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.
Upvotes: 0
Reputation: 121669
You have many options:
1) the simplest approach would be for every process to simply write to the same log independently. The problem, of course, is that the file would get scrambled if any two processes wrote different messages at the same time.
2) You could instead have the processes send messages to one "master logger", which would then output messages one at a time, in the order received. The "master logger" might use sockets. If all the processes were on the same host, you might instead use a message queue or a named pipe.
3) Even simpler, you could have a system-wide semaphore to insure only one message at a time gets written.
4) Yet another approach could be to use an open-source logger such as log4j or syslog-ng
Upvotes: 2