title: Logging using c++ stl stringstream with real-time performance requirements
body: <p>I'm attempting to implement logging functionality in an application that is required to run in real-time (meaning, spending a few milliseconds writing to a file during execution of the main loop will significantly affect performance since we are interfacing with several systems that require low latency).  My current implementation logs a line into a stringstream object each millisecond, and then writes the resulting string to a file only upon shutdown:</p>
  
  <pre><code>class ControlDemo {
    public:
      ControlDemo();
      ~ControlDemo();
      void spin();
      // Other public methods
    private:
      void logLine(std::vector&lt;double&gt; data);
      void writeLogFile();
      std::stringstream m_logged_data;
      std::string m_log_filename;
      bool m_continue_spinning;
      // Other private methods
  };
  
  ControlDemo::~ControlDemo() {
    writeLogFile();  // write log data in RAM to a file
  }
  
  void ControlDemo::spin() {
    while(m_continue_spinning){
      // do stuff
      logLine(data_to_log);
      sleepRemainingTime();  // maintaining ~1ms loop rate
    }
  }
  
  void ControlDemo::logLine(std::vector&lt;double&gt; data) {
    m_logged_data &lt;&lt; getCurrentTime();
    for (std::vector&lt;double&gt;::iterator it = data.begin(); it != data.end(); ++it)
      m_logged_data &lt;&lt; ', ' &lt;&lt; *it;
    m_logged_data &lt;&lt; std::endl;
  }
  
  void ControlDemo::writeLogFile() {
    std::ofstream file;
    file.open(m_log_file_path.c_str());
  
    file &lt;&lt; m_logged_data.str();
    file.close();
    std::cerr &lt;&lt; "Wrote log to " &lt;&lt; m_log_file_path &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>My desire is to implement some type of buffering functionality whereby I can specify the maximum number of lines in my log, after which, the initial lines will be discarded (essentially a circular buffer).  In this way, I am not wasting a bunch of RAM and slowing down my application by continuing to accumulate logged data, when maybe only the last 20 seconds of data is important.  I attempted this by modifying the <code>logLine()</code> method as follows:</p>
  
  <pre><code>void ControlDemo::logLine(std::vector&lt;double&gt; data) {
    static int line_num = 0;
    if(line_num &lt; m_max_num_lines)
      line_num++;
    else  // discard first line before inserting next line
      m_logged_data.ignore(1000,'\n');  // move get ptr to next line
  
    m_logged_data &lt;&lt; getCurrentTime();
    for (std::vector&lt;double&gt;::iterator it = data.begin(); it != data.end(); ++it)
      m_logged_data &lt;&lt; ', ' &lt;&lt; *it;
    m_logged_data &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>However the <code>m_logged_data.str()</code> that is called in <code>writeLogFile()</code> still returns all logged data rather than just the last <code>m_max_num_lines</code>, which suggests that moving the stringstream get pointer with <code>ignore()</code> does not affect the size of the buffer used by the stringstream object or optimize the code in any of the ways that I intended.</p>
  
  <p>I feel like either I am missing something obvious about the <code>stringstream</code> class (why isn't there a <code>setBufferSize()</code>?? see <a href="https://stackoverflow.com/questions/1494182/setting-the-internal-buffer-used-by-a-standard-stream-pubsetbuf">this</a>), or I should be using something else to manage the logging functionality.  If the latter, any suggestions on what class I should be using? One of the nice things about <code>stringstream</code> is all of the built-in formatting features, which I am using (although I didn't show it in the code snippets above). So, retaining those formatting capabilities would be nice if possible.</p>