I have this problem that I need to solve for one of my projects. I need to create ONE log file for 3 different services (don't ask why, my boss requested it like this). Each service can have multiple threads trying to log info into the file, so my question is, what's the best way to do this?
Should I use a global mutex? Something like this:
procedure LogToFile(fn, str: string);
var
F: TextFile;
begin
logMutex.Acquire;
try
{$I+}
try
AssignFile(F, fn);
if FileExists(fn) then
Append(F)
else
Rewrite(F);
Writeln(F, DateTimeToStr(Now) + ': ' + str);
CloseFile(F);
except
end;
{$I-}
finally
logMutex.Release;
end;
end;
initialization
logMutex := SyncObjs.TMutex.Create(nil, False,'some_global_mutex');
finalization
logMutex.Free;
Any better ideas?
Edit: Should I build another service, a logger service, that waits for messages that need to be logged from the other services and then only one service has to deal with the log files? If this is a good solution, what's the best way to communicate between services? I could use Indy...
Your solution using a named mutex will work and is for sure the simplest approach.
In a big project with around 50-80 applications running on multiple Terminal Servers (which makes it hard to synchronize), I managed to collect all log output to single central file.
The apps write the log output to a application server over UDP, using the open source Log4D framework and Internet Direct (Indy). The application server has a UDP server app running which receives the log messages and writes them to a single file.
As the log messages include meta information (logger name etc.), the logging server still can be configured to write separate files per application, in addition to the main file. For example, some log messages sent from the clients contain database performance data, they will be written to a separate log file to have them ready for analysis without further filtering steps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With