C++11 Logging Architecture To create a Logging system for a larger application, I came up with the following draft. The log sinks aren't detailed yet, but the factory method for logger creation and a rough draft of the logger itself are. Is this a good start and worth continuing? Or are there pitfalls you can see?

class LoggingSink; // abstract base class
class ConsoleSink : public LoggingSink; // some concrete logging sink
class LogfileSink : public LoggingSink; // ... too

/***********************************************/
class Logger {
public:
    void log(const std::string&amp; msg) {
        for (LoggingSink ls : Sinks)
            ls.log(msg);
    }

private:
    std::list&lt;std::reference_wrapper&lt;LoggingSink&gt;&gt; Sinks;
    friend class LoggerFactory;
};


/***********************************************/
class LoggerFactory {
public:
    std::unique_ptr&lt;Logger&gt; create() {
        std::unique_ptr&lt;Logger&gt; result = std::make_unique&lt;Logger&gt;();
        result-&gt;Sinks.assign(StandardAssignedSinks.begin(), StandardAssignedSinks.end());
        return result;
    }

    void addStandardSink(LoggingSink&amp; ls) {
        Sinks.push_back(std::reference_wrapper&lt;LoggingSink&gt;(ls));
    }

private:
    std::list&lt;std::reference_wrapper&lt;LoggingSink&gt;&gt; StandardAssignedSinks;
};

/***********************************************/
int main() {
    ConsoleSink cs;
    LogfileSink lfs("mylogfile.txt");

    LoggerFactory lf;
    lf.addStandardSink(cs);  // adding as reference for polymorphism
    lf.addStandardSink(lfs); // perhaps the addition of some standard sinks should be done in the constructor of LoggerFactory???

    std::unique_ptr&lt;Logger&gt; myLogger = lf.create();

    myLogger-&gt;log("Hello Log, I'm going to be injected soon!");
    MyClass myClassInstance(myLogger); // constructor dependency injection

    MyClass myOtherInstance(lf.create()); // direct DI
}


I'm also unsure about the friend class. This is something I never really liked with factories. Any ideas how to improve here?
As noted in the comments:

I would make the factory retain ownership:

class LoggerFactory {

typedef std::map&lt;std::string, std::unique_ptr&lt;Logger&gt;&gt;  Container;
typedef Container::iterator                             iterator;
typedef Container::const_iterator                       const_iterator;
typedef Container::value_type                           value_type;

typedef std::list&lt;std::reference_wrapper&lt;LoggingSink&gt;&gt;  SinkHolder;

public:
    Logger&amp; get(std::string const&amp; loggerName = "default")
    {
        iterator find = cont.find(loggerName);
        if (find == cont.end())
        {

            std::unique_ptr&lt;Logger&gt; result = std::make_unique&lt;Logger&gt;();

            // Personally I would not do this.
            // I would pass the iterators to the constructor
            // of the Logger object.
            result-&gt;Sinks.assign(std::begin(standardAssignedSinks),
                                 std::end(standardAssignedSinks));

            auto insertR = cont.insert(value_type(loggerName, result));
            if (!insertR.second)
            {    throw std::runtime_error("Insertion Failed");
            }
            find = insertR.first;           
        }
        return *(find-&gt;second);
    }

    void addStandardSink(LoggingSink&amp; ls) {
        standardAssignedSinks.empace_back(ls);
    }

private:
    SinkHolder standardAssignedSinks;
    Container  cont;
};


Now you can have multiple loggers. But you can re-use loggers (as each logger has its own name. Most of the time people should be using the default logger.

Building a streamming logger is not that difficult it just requires an intermediate buffer object to accumulate the message. When it is destroyed it sends the message to the logger.

class Logger {
    public:
        template&lt;typename T&gt;
        LogStreamBuffer  operator&lt;&lt;(T const&amp; data) // Member so left hand side  implied as Logger
        {
            // This is not perfect
            // This may cause a copy (and thus a destruction)
            // If there is a copy/destruction cycle an extra message will be
            // sent. You can code around this problem.
            // This is just to get you started.

            return LogStreamBuffer(*this) &lt;&lt; data;
        }
    // OTHER STUFF
};
class LogStreamBuffer
{
    Logger&amp;            parent;
    std::stringstream  buffer;

    public:
        LogStreamBuffer(Logger&amp; parent)
           : parent()
        {}
        ~LogStreamBuffer()
        {
            // When the object is destroyed.
            // Log the accumulated message with the parent.
            parent.log(buffer.str());
        }
        template&lt;typename T&gt;
        LogStreamBuffer&amp;  operator&lt;&lt;(T const&amp; data)
        {
            // Anything you log is just appended to the message.
            buffer &lt;&lt; data;
            return *this;   // return a reference to yourself.
                            // So you can chain messages.
        }
};

// Usage:
int main()
{
     LoggerFactory   factory;
     Logger          logger = factory.get("MyLogger");


     logger &lt;&lt; "This is a test: " &lt;&lt; 1 &lt;&lt; " Got it";
       //   ^^^
       //   Creates a LogStreamBuffer
       //   As an invisable temporary object.
       //   The subsequent `operator&lt;&lt;` will accumulate
       //   data in the buffer. When the statement is
       //   finished (at the ;) all temporaies will be
       //   destroyed. This calls the LogStreamBuffer
       //   destructor and logs your data to the Logger
       //   object. 

}