{"id":174757,"date":"2014-08-26T18:54:03","date_gmt":"2014-08-26T14:54:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=174757"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=174757","title":{"rendered":"<span class=\"post_title\">\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043b\u043e\u0433\u0433\u0435\u0440 \u0434\u043b\u044f C++<\/span>"},"content":{"rendered":"<div class=\"content html_format\"> \t\t\t\u041e\u0434\u043d\u0430\u0436\u0434\u044b, \u043a\u0430\u043a \u0438 \u0430\u0432\u0442\u043e\u0440\u0443 <a href=\"http:\/\/habrahabr.ru\/post\/174469\/\">\u043f\u043e\u0445\u043e\u0436\u0435\u0433\u043e \u0442\u043e\u043f\u0438\u043a\u0430<\/a>, \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u043e\u0435 \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u0435. \u041f\u0440\u0438\u0447\u0451\u043c \u043f\u043e\u0434\u0443\u043c\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u043b\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434 \u043d\u0430 \u043f\u0430\u0440\u0443 \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u043a\u043e\u0434\u0430, \u0447\u0435\u043c \u043f\u0440\u0438\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0451\u043d\u043d\u044b\u0439. \u041f\u0440\u0430\u0432\u0434\u0430, \u043f\u043e\u0442\u043e\u043c \u044d\u0442\u0438 2 \u044d\u043a\u0440\u0430\u043d\u0430 <a href=\"https:\/\/github.com\/poddav\/logger\">\u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u0437\u043b\u0438\u0441\u044c<\/a>, \u0442\u0430\u043a \u043a\u0430\u043a \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0435\u0449\u0435 \u0440\u0430\u0441\u043a\u0440\u0430\u0441\u0438\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u00ab\u0443\u0440\u043e\u0432\u043d\u044f\u00bb \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0434\u043b\u044f win32-\u0432\u0435\u0440\u0441\u0438\u0438 \u0435\u0449\u0451 \u0438 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u0432 \u043a\u043e\u0434\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 (\u0432 \u0440\u0443\u0441\u0441\u043a\u043e\u0439 \u0432\u0438\u043d\u0434\u0435 \u044d\u0442\u043e CP866), \u0447\u0442\u043e\u0431\u044b \u0440\u0443\u0441\u0441\u043a\u0438\u0435 \u0431\u0443\u043a\u0432\u044b \u0447\u0438\u0442\u0430\u043b\u0438\u0441\u044c \u0441 \u044d\u043a\u0440\u0430\u043d\u0430 \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b.<\/p>\n<p>  <a name=\"habracut\"><\/a>\u0427\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:  <\/p>\n<ul>\n<li>\u0434\u043b\u044f \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 std::clog \u0438 std::cerr;<\/li>\n<li>\u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u0434\u0430, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0438\u043b\u0438\u043d\u043a\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u0438\u043a;<\/li>\n<li>\u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0440\u0435\u0434\u044b \u043c\u043e\u0433\u0443\u0442 \u0432\u0435\u0441\u0442\u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0436\u0443\u0440\u043d\u0430\u043b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e, \u0431\u0435\u0437 \u00ab\u0441\u043b\u0438\u0432\u0430\u043d\u0438\u044f\u00bb \u0437\u0430\u043f\u0438\u0441\u0435\u0439.<\/li>\n<\/ul>\n<p>  \u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438:  <\/p>\n<ul>\n<li>\u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u043e\u0441\u0442\u044c;<\/li>\n<li>\u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0435 \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 (\u0442\u043e \u0435\u0441\u0442\u044c \u0434\u043e \u0432\u0445\u043e\u0434\u0430 \u0432 main);<\/li>\n<li>\u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u0430\u044f \u00ab\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c\u00bb, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Boost.Thread.<\/li>\n<\/ul>\n<p>  \u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432, \u0442\u043e \u0434\u043b\u044f \u0438\u0445 \u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f: \u0434\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 Boost.Log \u2014 <a href=\"http:\/\/boost-log.sourceforge.net\/libs\/log\/doc\/html\/index.html\">\u043e\u0434\u0438\u043d<\/a>, <a href=\"http:\/\/torjo.com\/log2\/doc\/html\/index.html\">\u0432\u0442\u043e\u0440\u043e\u0439<\/a>, <a href=\"http:\/\/www.pantheios.org\/\">Panthios<\/a>, <a href=\"http:\/\/logging.apache.org\/log4cxx\/index.html\">log4cxx<\/a>, <a href=\"https:\/\/code.google.com\/p\/google-glog\/\">glog<\/a>, \u0438 \u0442.\u0434. \u041f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u2014 \u0440\u0435\u0447\u044c \u0438\u0434\u0451\u0442 \u043e \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0451\u043d\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0435\u0434\u0438\u043d\u0438\u0446\u0430\u0445 \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438. \u041e\u0431\u044b\u0447\u043d\u043e \u044d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u043e\u043c, \u043e\u0434\u043d\u0430\u043a\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0436\u0443\u0440\u043d\u0430\u043b \u0438\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0438 \u043f\u0438\u0441\u0430\u0442\u044c, \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u0442\u0440\u0430\u0448\u043d\u043e\u0433\u043e \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043d \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a std::cerr.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c, \u0432\u043a\u0440\u0430\u0442\u0446\u0435 \u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0431\u0443\u0444\u0435\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0438\u0448\u0443\u0442 \u043f\u043e\u0442\u043e\u043a\u0438 std::clog \u0438 std::cerr, \u043d\u0430\u0448 \u043b\u043e\u0433\u0433\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 <a href=\"http:\/\/www.cplusplus.com\/reference\/streambuf\/streambuf\/\">std::streambuf<\/a> \u0438 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b <a href=\"http:\/\/www.cplusplus.com\/reference\/streambuf\/streambuf\/overflow\/\">overflow<\/a> \u0438 <a href=\"http:\/\/www.cplusplus.com\/reference\/streambuf\/streambuf\/xsputn\/\">xsputn<\/a>. \u0411\u0443\u0444\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u0430\u044f, \u0441 \u043e\u043f\u0443\u0441\u0442\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u0431\u0443\u0444\u0435\u0440\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043d\u0435\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 &#8216;\\n&#8217;. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"http:\/\/www.boost.org\/doc\/libs\/release\/doc\/html\/thread\/thread_local_storage.html\">boost::thread_specific_ptr<\/a> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0440\u0435\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u043d \u0441\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0439 \u0431\u0443\u0444\u0435\u0440.<\/p>\n<pre><code>using boost::thread_specific_ptr;  class logger : public std::streambuf { public:     typedef char                                char_type;     typedef std::char_traits&lt;char_type&gt;         traits_type;     typedef traits_type::int_type               int_type;      struct line_buffer;      explicit logger (sys::raw_handle console, bool prepend_time = true);     ~logger ();  protected:     virtual int_type overflow (int_type c);     virtual std::streamsize xsputn (const char_type* buf, std::streamsize size);  private:     line_buffer* buffer ();     void write_line (const char* data, size_t size);     void write_line (const std::string&amp; line) { write_line (line.data(), line.size()); }      sys::raw_handle     m_con;     thread_specific_ptr&lt;line_buffer&gt;                         m_buffer;     bool                m_console_output;     bool                m_prepend_time; }; <\/code><\/pre>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0431\u0443\u0444\u0435\u0440 \u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440:<\/p>\n<pre><code>class logger_init { public:     logger_init ();     ~logger_init ();  private:     logger*     \tm_clog;     logger*\t        m_cerr;     std::streambuf*     m_clog_native;     std::streambuf*     m_cerr_native;     sys::file_handle    m_file; } std_stream_logger;  logger_init::logger_init ()     : m_clog (0)     , m_cerr (0)     , m_clog_native (0)     , m_cerr_native (0) {     sys::raw_handle con = sys::io::err();     if (!sys::handle::valid (con) || !sys::file_handle::valid (con))         return;     m_clog = new logger (con);     m_cerr = new logger (con);     m_clog_native = std::clog.rdbuf (m_clog);     m_cerr_native = std::cerr.rdbuf (m_cerr); }  logger_init::~logger_init () {     if (m_clog)     {         std::cerr.rdbuf (m_cerr_native);         std::clog.rdbuf (m_clog_native);         delete m_cerr;         delete m_clog;     } } <\/code><\/pre>\n<p>  \u0412 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0438\u043c\u0451\u043d sys \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b <a href=\"https:\/\/github.com\/poddav\/sys--\">\u043e\u0431\u0451\u0440\u0442\u043a\u0438 \u043d\u0430\u0434 \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c\u0438 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438<\/a>.<\/p>\n<p>  \u00ab\u041c\u0430\u0433\u0438\u044f\u00bb thread-local storage \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 logger::buffer(), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0431\u0443\u0444\u0435\u0440, \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430.<\/p>\n<pre><code>logger::line_buffer* logger:: buffer () {     line_buffer* bufptr = m_buffer.get();     if (!bufptr)         m_buffer.reset (bufptr = new line_buffer (this));     return bufptr; } <\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 overflow \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0438\u043c\u0432\u043e\u043b \u0432 \u0431\u0443\u0444\u0435\u0440 \u0438 \u043e\u043f\u0443\u0441\u0442\u043e\u0448\u0430\u0435\u0442 \u0435\u0433\u043e, \u0435\u0441\u043b\u0438 \u0431\u044b\u043b \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0441\u0438\u043c\u0432\u043e\u043b \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<pre><code>logger::int_type logger:: overflow (int_type c) {     \/\/ \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430 -- \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 eof(), \u043d\u0430\u0434\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c not_eof()     if (traits_type::eq_int_type (c, traits_type::eof()))         return traits_type::not_eof (c);      char_type chr = traits_type::to_char_type (c);     if (traits_type::eq (chr, '\\n'))         buffer()-&gt;flush();     else         buffer()-&gt;append (&amp;chr, 1);     return (c); } <\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 xsputn \u0438\u0449\u0435\u0442 \u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0431\u0443\u0444\u0435\u0440.<\/p>\n<pre><code>std::streamsize logger:: xsputn (const char_type* buf, std::streamsize sz) {     line_buffer* bufptr = buffer();     for (std::streamsize size = sz; size &gt; 0; )     {         const char* nl = traits_type::find (buf, size, '\\n');         if (!nl)         {             \/\/ \u0441\u0438\u043c\u0432\u043e\u043b \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0435 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0441\u044f - \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0446\u0435\u043b\u0438\u043a\u043e\u043c             bufptr-&gt;append (buf, size);             break;         }         if (nl != buf)         {             \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0431\u0443\u0444\u0435\u0440 \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 '\\n'             bufptr-&gt;append (buf, nl-buf);         }         bufptr-&gt;flush(); \/\/ \u043e\u043f\u0443\u0441\u0442\u043e\u0448\u0430\u0435\u043c \u0431\u0443\u0444\u0435\u0440         ++nl;         size -= nl - buf;         buf = nl;     }     return sz; } <\/code><\/pre>\n<p>  \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430.<\/p>\n<pre><code>struct logger::line_buffer {     static const size_t s_limit = 1000; \/\/ \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438      explicit line_buffer (logger* owner) : m_owner (owner) { }      void append (const char* buf, size_t size);     void flush ();  private:     void append_time ();     void append_crlf ();      logger*         m_owner;     std::string     m_text; };  void logger::line_buffer:: append (const char* buf, size_t size) {     if (m_owner-&gt;m_prepend_time &amp;&amp; m_text.empty())         append_time();     while (size + m_text.size() &gt; s_limit)     {         assert (m_text.size() &lt; s_limit);         size_t chunk = std::min (s_limit - m_text.size(), size);         m_text.append (buf, chunk);         flush();         size -= chunk;         buf += chunk;         if (size &amp;&amp; m_owner-&gt;m_prepend_time)             append_time();     }     if (size)         m_text.append (buf, size); }  void logger::line_buffer:: flush () {     append_crlf();     m_owner-&gt;write_line (m_text);     m_text.clear(); }  inline void logger::line_buffer:: append_crlf () { #ifdef _WIN32     m_text.append (&quot;\\r\\n&quot;, 2); #else     m_text.push_back ('\\n'); #endif }  inline void logger:: write_line (const char* data, size_t size) {     sys::write_file (m_con, data, size); } <\/code><\/pre>\n<p>  \u041f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0440\u0435\u043c\u044f \u0441 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0430\u043c\u0438 \u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0440\u0435\u0434\u0430.<\/p>\n<pre><code>#ifdef _WIN32  void logger::line_buffer:: append_time () {     char cvtbuf[32];     SYSTEMTIME time;     GetLocalTime (&amp;time);     int rc = _snprintf (cvtbuf, sizeof(cvtbuf), &quot;%02d:%02d:%02d.%03d [%04lu] &quot;,                         time.wHour, time.wMinute, time.wSecond, time.wMilliseconds,                         GetCurrentThreadId());     if (rc &lt; 0 || rc &gt; int (sizeof(cvtbuf))) \trc = sizeof(cvtbuf);     m_text.append (cvtbuf, rc); }  #else  void logger::line_buffer:: append_time () {     char cvtbuf[32];     struct timeval sys_time;     int rc = ::gettimeofday (&amp;sys_time, NULL);     if (rc != -1)     {         struct tm time;         localtime_r (&amp;sys_time.tv_sec, &amp;time);         rc = ::snprintf (cvtbuf, sizeof(cvtbuf), &quot;%02d:%02d:%02d.%03d [%08x] &quot;, time.tm_hour,                          time.tm_min, time.tm_sec, int(sys_time.tv_usec\/1000),                          (unsigned) pthread_self());         if (rc &gt; int (sizeof(cvtbuf)))             rc = sizeof(cvtbuf);     }     if (rc != -1)         m_text.append (cvtbuf, rc); }  #endif \/\/ _WIN32 <\/code><\/pre>\n<p>  <a href=\"https:\/\/github.com\/poddav\/logger\">\u0420\u0430\u0431\u043e\u0447\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043a\u043e\u0434\u0430<\/a> \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0440\u0430\u0441\u0446\u0432\u0435\u0442\u043a\u0430 \u0434\u043b\u044f \u043a\u043e\u043d\u0441\u043e\u043b\u0438, \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u0444\u0430\u0439\u043b \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 \u0432 \u043a\u043e\u0434\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0434\u043b\u044f win32. \u0417\u0430\u043c\u0435\u0447\u0443 \u0435\u0449\u0451 \u0440\u0430\u0437, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0433\u043e \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u00ab\u043e\u0431\u0435\u0440\u0442\u043a\u0438\u00bb \u043d\u0430\u0434 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c\u0438 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0438\u043c\u0451\u043d sys. \u0418\u0445 \u0440\u0430\u0437\u0431\u043e\u0440 \u0443\u0436\u0435 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u044d\u0442\u043e\u0439 \u0437\u0430\u043c\u0435\u0442\u043a\u0438, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0443 <a href=\"https:\/\/github.com\/poddav\/sys--\">\u0441\u0441\u044b\u043b\u043a\u0443 \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f<\/a>. \t\t\t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/174757\/\"> http:\/\/habrahabr.ru\/post\/174757\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\"> \t\t\t\u041e\u0434\u043d\u0430\u0436\u0434\u044b, \u043a\u0430\u043a \u0438 \u0430\u0432\u0442\u043e\u0440\u0443 <a href=\"http:\/\/habrahabr.ru\/post\/174469\/\">\u043f\u043e\u0445\u043e\u0436\u0435\u0433\u043e \u0442\u043e\u043f\u0438\u043a\u0430<\/a>, \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u043e\u0435 \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u0435. \u041f\u0440\u0438\u0447\u0451\u043c \u043f\u043e\u0434\u0443\u043c\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u043b\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434 \u043d\u0430 \u043f\u0430\u0440\u0443 \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u043a\u043e\u0434\u0430, \u0447\u0435\u043c \u043f\u0440\u0438\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0451\u043d\u043d\u044b\u0439. \u041f\u0440\u0430\u0432\u0434\u0430, \u043f\u043e\u0442\u043e\u043c \u044d\u0442\u0438 2 \u044d\u043a\u0440\u0430\u043d\u0430 <a href=\"https:\/\/github.com\/poddav\/logger\">\u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u0437\u043b\u0438\u0441\u044c<\/a>, \u0442\u0430\u043a \u043a\u0430\u043a \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0435\u0449\u0435 \u0440\u0430\u0441\u043a\u0440\u0430\u0441\u0438\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u00ab\u0443\u0440\u043e\u0432\u043d\u044f\u00bb \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0434\u043b\u044f win32-\u0432\u0435\u0440\u0441\u0438\u0438 \u0435\u0449\u0451 \u0438 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u0432 \u043a\u043e\u0434\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 (\u0432 \u0440\u0443\u0441\u0441\u043a\u043e\u0439 \u0432\u0438\u043d\u0434\u0435 \u044d\u0442\u043e CP866), \u0447\u0442\u043e\u0431\u044b \u0440\u0443\u0441\u0441\u043a\u0438\u0435 \u0431\u0443\u043a\u0432\u044b \u0447\u0438\u0442\u0430\u043b\u0438\u0441\u044c \u0441 \u044d\u043a\u0440\u0430\u043d\u0430 \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-174757","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/174757","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=174757"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/174757\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=174757"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=174757"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=174757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}