How to add an error logger to a class
I would like to use a generic error msg handler so I can GetLastError
and SetError
easily for any class. I came up with this scheme. But I have a couple of questions. Please note this implementation is just for testing. But I want to get the basic design right.
#include <iostream>
#include <stdarg.h>
class ErrorHandler
{
public:
virtual void SetError(const char* zFormat, ...)
{
va_list args;
va_start (args, zFormat);
vsnprintf (z_ErrorBuf, sz_MaxBufSize, zFormat, args);
va_end (args);
}
const char* GetError() const
{
return z_ErrorBuf;
}
virtual ~ErrorHandler(){}
explicit ErrorHandler(const size_t szMaxBufSize = 1024)
{
z_ErrorBuf = malloc(sizeof(char)*szMaxBufSize);
sz_MaxBufSize = szMaxBufSize;
}
void ResizeBuffer(const size_t szMaxBufSize)
{
z_ErrorBuf = realloc(z_ErrorBuf, szMaxBufSize);
sz_MaxBufSize = szMaxBufSize;
}
protected:
char* z_ErrorBuf;
size_t sz_MaxBufSize;
};
class MyClass;
//Worker can be just an interface if needed. So, can't use friend.
class Worker
{
public:
void Work(MyClass& oGod);
};
void Worke开发者_如何学运维r::Work(MyClass& oGod)
{
//Work
//OnError
oGod.GetErrorHandler().SetError("Save me %s", "not");
}
class RecordingErrors
{
public:
const char* GetLastError() const
{
return oErrorHandler.GetError();
}
//GetErrorHandler is public
ErrorHandler& GetErrorHandler()
{
return oErrorHandler;
}
private:
ErrorHandler oErrorHandler;
};
class MyClass : public RecordingErrors
{
public:
bool GetThingsDone(Worker& me)
{
me.Work(*this);
//on Error
return false;
}
};
int main()
{
MyClass oL;
Worker w;
if(!oL.GetThingsDone(w))
{
std::cout << oL.GetLastError() << std::endl;
}
}
- Can I override this function in a child class?
virtual void SetError(const char* zFormat, ...)
. - Can I do away with the
RecordingErrors
class? I feel that thenMyClass
would have to inherit fromErrorHandler
which I don't think is good. Am I right or wrong? Is this another question about composition over inheritence. EDIT: I don't mean the name, but the idea? - Any possible scenarios this approach would fail?
- is there a better way to implement error logging?(logging is not the right word here. What is it)
Error Handler and logger are two different entities. Error handler decides what to do with the errors. Should it be send to logger immediately, should it be saved in databases, or should it be simply saved in some buffer till someone asks.
Logger decides how to log the given message. Should it be shown on the console or should it be saved in the disk file, in what format it should be shown.
Keep in mind the features of the logger.
1) It should be independent class. It's behavior should not depend on the other classes.
2) Logger most preferable should be singleton. You don't need many objects floating around doing the same thing. But then singleton classes has their own headaches when come to multi-threading. So I know this point is debatable.
3) It must and must have capabilities of asynchronous logging. This means producer and consumer implementation. (Logging is an i/o operation and hence expensive in nature. You don't want your main processing hogging for this. But then again you may not want to use threads to scrap this one.)
In you implementation of error logger I can't see any logger. Also your error handler is saving a single error. You may need the vector of errors. Keep SetError with fixed arguments. Pass arguments like error id, error message and error buffer length. Let the caller create the error message.
精彩评论