Efficient Logging in C++

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pmatos

    #1

    Efficient Logging in C++

    Hi all,

    I am trying to create a simple but efficient C++ logging class. I know
    there are lots of them out there but I want something simple and
    efficient. The number one requirement is the possibility of shutting
    logging down at compile time and suffer no performance penalty
    whatsoever for getting logging on whenever I wish. Of course that I
    would need to recompile the project each time I want to turn logging on
    or off. But given a LOGGING variable what's the best way to turn log on
    or off with no performance penalty?

    My idea is to have a singleton logger class to log to a file or to
    stdout and then provide some macros that would be used all around the
    code that would either not do anything or call logging object methods
    if LOGGING is defined.

    Are any better ideas out there?

    Cheers,

    Paulo Matos

  • Stephen M. Webb

    #2
    Re: Efficient Logging in C++

    "pmatos" <pocm@sat.ine sc-id.pt> wrote in message news:<110846727 8.790055.281280 @o13g2000cwo.go oglegroups.com> ...[color=blue]
    > I am trying to create a simple but efficient C++ logging class. I know
    > there are lots of them out there but I want something simple and
    > efficient. The number one requirement is the possibility of shutting
    > logging down at compile time and suffer no performance penalty
    > whatsoever for getting logging on whenever I wish. Of course that I
    > would need to recompile the project each time I want to turn logging on
    > or off. But given a LOGGING variable what's the best way to turn log on
    > or off with no performance penalty?
    >
    > My idea is to have a singleton logger class to log to a file or to
    > stdout and then provide some macros that would be used all around the
    > code that would either not do anything or call logging object methods
    > if LOGGING is defined.
    >
    > Are any better ideas out there?[/color]

    Consider logging to std::clog. You can replace the clog streambuf
    with the streambuf of your choice (to a file, socket, window,
    whatever). Principle of least surprise for your readers.

    If you disable logging by using an "if (loggingIsEnabl ed) { std::clog
    << ...; }" then unless logging is enabled you pay no performance
    penalty, and the enabling is done at run time so you don't have two
    code streams to test.

    --
    Stephen M. Webb

    Comment

    • pmatos

      #3
      Re: Efficient Logging in C++

      Well, yeah, but having to test at run-time if(loggingIsEna bled) is
      already a performance penalty if I do it a zillion times, right?

      Comment

      • Dieter Beaven

        #4
        Re: Efficient Logging in C++

        Hi Paulo,

        Using the Singleton Pattern is a good idea, and provides a centralised
        point of control over the logging. One way to control the type of
        logging is to provide different derived classes implementing the
        logging in different ways, including a class that does no logging (
        i.e. different logging Strategies ).


        class Logging
        {
        public:
        static Logging& instance()
        { if ( 0 == Logging::single ton )
        { if ( LOGGING_TYPE == COUT_LOGGING )
        { Logging::single ton = new CoutLogging();
        }
        else if ( LOGGING_TYPE == FILE_LOGGING )
        { Logging::single ton = new FileLogging();
        }
        // etc...
        else
        { Logging::single ton = new NoLogging();
        }
        }
        return *Logging::singl eton;
        }

        public:
        virtual Logging& loggingInterfac eMethods() = 0;

        protected:
        Logging();

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

        private:
        static Logging* singleton;
        };

        class NoLogging : public Logging
        {
        public:
        virtual Logging& loggingInterfac eMethods() { /* NOOP */ }
        };

        // etc ...


        The selecting value LOGGING_TYPE could either be a #define in source
        or in the make file / project settings for compile time selection, or
        you could make it a dynamic property of the Logger to allow the
        logging to vary at runtime after resetting the Logging class.

        If your application peformance really is sensitive to even the ( 0 ==
        Logging::single ton ) test ( which you can't avoid for this style of
        Singleton Idiom in C++ ), then its worth considering if you really
        need ( or even can afford ) to log the performance critical section of
        code.

        A possible alternative to the Singleton Pattern would be to use
        Template Meta Programming techniques whereby the Logging Strategy
        becomes a Policy template and the compiler can be used to ensure that
        NoLogging Policy never generates any code at all ( similiar effect to
        using MACROs, but far superior ). I'll refer you to the Modern C++
        Design book if you're keen to learn those ideas.

        You can in principle combine the two ideas, but now we're diverging
        away from the quick and simple...

        IMHO, I think the log4cpp library is excellent, and a good place to
        start if looking for ideas ( http://log4cpp.sourceforge.net/ )

        Regards,

        Dieter Beaven

        Comment

        • davidrubin@warpmail.net

          #5
          Re: Efficient Logging in C++

          You want to use a macro interface to your logging API. This way, you
          can define the macros to no-ops if necessary. /david

          Comment

          • Fazl

            #6
            Re: Efficient Logging in C++

            davidrubin@warp mail.net wrote in message news:<110861022 0.964816.76280@ g14g2000cwa.goo glegroups.com>. ..[color=blue]
            > You want to use a macro interface to your logging API. This way, you
            > can define the macros to no-ops if necessary. /david[/color]

            Or, use a constant switch set to true or false, then the compiler can
            select to include the logging call or not at compile time.

            You may not gain runtime flexibility, but you get the 'no overhead
            when not used' benefit without having to pollute your code with
            macros.

            Macro values remain at the mercy of any third party headers you may
            #include and the compiler may never warn you.

            -Fazl

            Comment

            • Matthew P. Cashdollar

              #7
              Re: Efficient Logging in C++

              pmatos wrote:[color=blue]
              > Are any better ideas out there?[/color]

              There's no sense in reinventing the wheel. Check this out:
              http://www.torjo.com/code/logging-v131.zip Even if you don't use it, it
              will give you some ideas.

              To compile it, unzip it in the boost directory tree (www.boost.org) and
              run bjam.

              -Matt

              Comment

              Working...