I am designing a shared library that will mainly provide a class with specific logging capabilities for client applications. I would rather not presume how this class might be used to be more generic.
The responsibility of the Logger
class is to encapsulate application datas with a header and a tailer and write a line to a single file where the file path is specified by the application but not its name.
A first (simplified) skeleton of the Logger
class could be :
class Logger
{
public:
Logger(const QString &filepath);
bool log(const QString &datas);
...
};
As the application can use this Logger
class anywhere and in any thread, i would like to ensure that the filepath
is set only once by the application and that it is thread safe to protected concurrent file access.
Singleton pattern seems a good candidate for this class but i ask myself 3 questions :
How to make it thread safe without using C++11 or more recent compilers ?
The second point is that filepath
should be set only once by the application. With Singleton, we still can add a filepath
in getInstance(const &QString filepath)
but even if this ensure that the filepath
won't change, it might be called in the application with different arguments leading to
// let's say this is the firstcall so filepath = filepath1 and won't change
Logger::getInstance(filepath1);
...
Logger::getInstance(filepath2); // Ok we still have filepath = filepath1
... // and so on from anywhere in the code and possibly from different threads
This will work. But from the application point of view, i find this not clear because a developer might think that it creates a log in filepath1
and filepath2
but he is not. Moreover, each time the client has to call the singleton, he has to pass all arguments. Ideally, filepath
should be set only once in the client code, and then it simply call the log
method. How to make it more clear for the client application ?
The last point is about the singleton pattern itself : i would rather avoid it especially in a multi threaded context as a good thread safe implementation is not as easy as it seems to be. Am i missing something obvious ?
Thank you.