开发者

How to improve this logging scheme (A little more)

Basically, I have this logger class and prefixer.

class Logger
{
    public:
        enum LogType
        {
            LT_DEBUG = 0,
            LT_WARNING,
            LT_ERROR,
            LT_STAT,
            LT_TEXT,
            LT_INFO,
            LT_OTHER,
            LT_UNKNOWN
        };

        __attribute__((format(printf, 7, 8)))
        virtual const char* EHLog(LogType,  //LogType
                bool,                       //Send to FE
                int,                        //Error code
                const char*,                //File
                int,                        //Line
                const char*,                //Format
                ...) = 0;

        virtual void PushPrependString(const char*) = 0;
        virtual void PopPrependString() = 0;

        virtual ~Logger(){}
};

class Prepender
{
    public:
        Prepender(Logger& oLogger, const char* zPrependString)
            :o_Logger(oLogger)
        {
            o_Logger.PushPrependString(zPrependString);
        }

        ~Prepender()
        {
            o_Logger.PopPrependString();
        }

    private:
        Prepender();
        Prepender(const Prepender&);
        Prepender& operator=(const Prepender&);

        Logger& o_Logger;
};

Now, In the functions where any logging is done, I do this:

void SomeObject::SomeMethod()
{
   Prepender(*p_Logger, __PRETTY_FUNCTION__);

   //Do stuff
}

which works fine.

Is there any way to improve this by doing away with creating a Prepender object manually where I need logging? (Even macros?) (I do understand that it maybe impossible, I want to know what ideas others have).

EDIT: As I see lot of people getting wrong ideas, I'd ideally like to do this:

void SomeObject::SomeMethod()
{
   //Prepender(*p_Logger, __PRETTY_FUNCTION__);

   //Do stuff
   //And the same results!!!
}

The main motivation开发者_如何学Go for doing this is to make sure that I do not forget to prefix a function when there is logging being done in it. If I did, the function reported will be one level up than the real one.


EDIT2:

Based on the revised Edit in OP, it is not possible to achieve the desired goals of logging in an portable manner at least, IMO.

EDIT1:

  1. Don't you want to support wide characters?
  2. Why not using string (wstring) instead of char*?
  3. Logger should be either a Singleton or a Monostate (should take care of your challenge related to creating it at each function entry)
  4. Is this requried to be thread safe?
  5. Why not a pure virtual destructor in Logger?
  6. The name logger doesn't look right. It should indicate something like LogInterface etc.
  7. What about exception handling?

I can go on with a few more, until you tell us the specs!!


Well, you could use a macro:

METHOD(void SomeObject::SomeMethod())
   // do your stuff...
ENDMETHOD

where:

#define METHOD(method_declaration) method_declaration \
   Prepender(*p_Logger, __PRETTY_FUNCTION__); 

#define ENDMETHOD }

you could add something to the method's end too, if you like.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜