2014-11-14 48 views
3

我想將日誌字符串發送到boost 1.57的最新版本中的文件,並且由於某些原因在linux上,線程ID始終設置爲0。我有一種感覺,它可能與使用本地線程而不是boost線程有關 - 但這並不能解釋它爲什麼在Windows環境中工作。任何幫助,將不勝感激。Boost Logging顯示linux thread id全部爲0

這是我在logger.cpp文件中的初始化代碼。

編輯:如下圖所示我也包括我Logger.h這表明我使用記錄器的類型 - 有效利用BOOST_LOG_CHANNEL_SEV宏登錄到

的boost ::登錄::來源: :Windows顯示就好即

上severity_channel_logger_mt <的boost ::登錄::瑣碎:: severity_level>

#include <boost/log/core.hpp> 
#include <boost/log/sinks/sync_frontend.hpp> 
#include <boost/log/sinks/text_ostream_backend.hpp> 
#include <boost/log/support/date_time.hpp> 
#include <boost/log/expressions.hpp> 
#include <boost/log/utility/setup/console.hpp> 
#include <boost/log/attributes/scoped_attribute.hpp> 
#include <boost/log/expressions/formatters/date_time.hpp> 
#include <boost/log/utility/setup/common_attributes.hpp> 
#include <boost/log/utility/manipulators/add_value.hpp> 
#include <boost/log/sources/severity_channel_logger.hpp> 

. . . 

namespace fs = boost::filesystem; 
namespace logging = boost::log; 
namespace src = boost::log::sources; 
namespace expr = boost::log::expressions; 
namespace sinks = boost::log::sinks; 
namespace attrs = boost::log::attributes; 
namespace keywords = boost::log::keywords; 
namespace trivial = boost::log::trivial; 
void 
Logger::init(
    const fs::path& rErrEvtPath, 
    const fs::path& rStatusPath) 
{ 
    // register common attributes - ThreadID, LineID, TimeStamp etc. 
    logging::add_common_attributes(); 

    // Construct the sink for the "event_log" channel 
    typedef sinks::synchronous_sink< 
     sinks::text_ostream_backend> text_sink; 
    auto sink = boost::make_shared<text_sink>(); 
    sink->locked_backend()->auto_flush(true); 
    sink->locked_backend()->add_stream(
     boost::make_shared<std::ofstream>(rErrEvtPath.c_str())); 
    sink->set_formatter(
     expr::format("%1% [%2%] tid[%3%] %4%") 
     % expr::format_date_time<boost::posix_time::ptime>("TimeStamp", "%H:%M:%S.%f") 
     % logging::trivial::severity 
     % expr::attr<attrs::current_thread_id::value_type>("ThreadID") 
     % expr::smessage); 
    sink->set_filter(expr::attr<std::string>("Channel") == "event"); 
    logging::core::get()->add_sink(sink); 

    // Construct the sink for the "status_log" channel 
    sink = boost::make_shared<text_sink>(); 
    sink->locked_backend()->auto_flush(true); 
    sink->locked_backend()->add_stream(
     boost::make_shared<std::ofstream>(rStatusPath.c_str())); 
    sink->set_formatter(
     expr::format("%1% [%2%] tid[%3%] %4%") 
     % expr::format_date_time<boost::posix_time::ptime>("TimeStamp", "%H:%M:%S.%f") 
     % logging::trivial::severity 
     % expr::attr<attrs::current_thread_id::value_type>("ThreadID") 
     % expr::smessage); 
    sink->set_filter(expr::attr<std::string>("Channel") == "status"); 
    logging::core::get()->add_sink(sink); 
} 

日誌

15:42:35.205747 [info] tid[0x00000e14] module[NIC:192.168.1.1] SETCNTX IP_ADDR 192.168.1.1 
15:42:35.207747 [info] tid[0x00000e14] module[NIC:192.168.1.1] SETCNTX RESP_ON 
15:42:35.209747 [info] tid[0x00000e14] module[NIC:192.168.1.1] SETCNTX SET_FTP_TIMEOUT 10 
15:42:35.212747 [info] tid[0x00000e14] module[NIC:192.168.1.1] FTPNOPROMPT [192.168.1.1] [timeout 10(s)] 
15:42:35.552781 [info] tid[0x00000e14] module[NIC:192.168.1.1] SETCNTX RESP_OFF 
15:42:35.553781 [info] tid[0x00000e14] module[NIC:192.168.1.1] FTPQUOTE "site attrib 0 DEOS" 
然而

使用升壓1.57.0相同版本的Linux(PPC)日誌如下:

13:43:45.092206 [info] tid[0000000000] module[N/A] MLFCommand - command group(5) - end 
13:43:45.092568 [info] tid[0000000000] module[N/A] SETCNTX IP_ADDR 192.168.1.23 
13:43:45.097037 [info] tid[0000000000] module[N/A] SETCNTX RESP_ON 
13:43:45.098691 [info] tid[0000000000] module[N/A] SETCNTX SET_FTP_TIMEOUT 10 
13:43:45.100474 [info] tid[0000000000] module[N/A] FTPNOPROMPT [192.168.1.23] [timeout 10(s)] 
13:43:49.191856 [warning] tid[0000000000] module[N/A] [>TIMEOUT<] 

編輯:爲完整 - 包括我logger.h

#ifndef _logger_h_ 
#define _logger_h_ 

// SYSTEM INCLUDES 
#include <mutex> 
#include <string> 
#include <memory> 
#include <boost/filesystem.hpp> 
#if !defined(__GNUC__) 
#pragma warning(push) 
#pragma warning(disable: 4714 4100 4510 4503 4512 4610) 
#endif 
#include <boost/log/trivial.hpp> 
#include <boost/log/sources/record_ostream.hpp> 
#include <boost/log/sources/severity_channel_logger.hpp> 
#if !defined(__GNUC__) 
#pragma warning(pop) 
#endif 

// APPLICATION INCLUDES 
// DEFINES 
#define LOG(logger, lvl) BOOST_LOG_CHANNEL_SEV(logger, "event", lvl) 
#define LOG_TRACE(logger) BOOST_LOG_CHANNEL_SEV(logger, "event", trivial::trace) 
#define LOG_DEBUG(logger) BOOST_LOG_CHANNEL_SEV(logger, "event", trivial::debug) 
#define LOG_INFO(logger) BOOST_LOG_CHANNEL_SEV(logger, "event", trivial::info) 
#define LOG_WARNING(logger) BOOST_LOG_CHANNEL_SEV(logger, "event", trivial::warning) 
#define LOG_ERROR(logger) BOOST_LOG_CHANNEL_SEV(logger, "event", trivial::error) 
#define LOG_FATAL(logger) BOOST_LOG_CHANNEL_SEV(logger, "event", trivial::fatal) 

// MACROS 
// EXTERNAL FUNCTIONS 
extern bool gVerboseMode; 

// EXTERNAL VARIABLES 
// CONSTANTS 
// STRUCTS 
// TYPEDEFS 
// FORWARD DECLARATIONS 

class Logger 
{ 
public: 
    using SEVChannelLoggerMT = boost::log::sources::severity_channel_logger_mt< 
     boost::log::trivial::severity_level>; 
    /** 
    * singleton pattern implementation 
    * 
    * @return singleton instance 
    */ 
    static Logger* getInstance(); 

    // destructor 
    virtual ~Logger() = default; 

    /** define a log filter associated with a channel attribute */ 
    enum class LogDest { 
     EventLog, StatusLog 
    }; 

    /** 
    * log the message to a specified log<p> 
    * 
    * @param logDest [in] filter used to route the log message to 
    *     the correct logging sink. 
    * @param rMessage [in] message to log 
    */ 
    void logMessage(
     const LogDest logDest, 
     const boost::log::trivial::severity_level& severity, 
     const std::string& rMessage); 

    /** 
    * Returns logger associated with the specified log destination.<p> 
    * 
    * @param logDest [in] filter used to route the log message to 
    *     the correct logging sink. 
    * @return logger of the appropriate type 
    */ 
    SEVChannelLoggerMT& getLoggerRef(const LogDest logDest); 

    /** 
    * Custom reusable formatter which we can attach to all sinks 
    * for a uniform formatting of log messages 
    * 
    * @param rec [in] record contain the log details 
    * @param strm [in,out] logging stream 
    */ 
    static void customFormatter(
     boost::log::record_view const& rec, 
     boost::log::formatting_ostream& strm); 

    /** 
    * Initialize the logging framework.<p> 
    * Initializes the Boost logging framework by setting up the 
    * following log files<p>. 
    * Under the covers the Boost Logging framework initializes two 
    * distinct log files. 
    * <ul> 
    *  <li>Error/Event log - this contains everything</li> 
    *  <li>rStatusPath - high level log file which is also 
    *  displayed on the iPad</li> 
    * </ul> 
    * 
    * @param rErrEvtPath 
    *    [in] fully qualified path to 
    *    DlfLogBuffer[num].txt log file. This log 
    *    file will be created as necessary or 
    *    reinitialized to empty (truncated) if it 
    *    already exists. 
    * @param rStatusPath 
    *    [in] fully qualified path to 
    *    DlfStatusBuffer[num].txt log file. This log 
    *    file will be created as necessary or 
    *    reinitialized to empty (truncated) if it 
    *    already exists. 
    */ 
    static void init(
     const boost::filesystem::path& rErrEvtPath, 
     const boost::filesystem::path& rStatusPath); 
private: 
    // severity channel loggers - one for the error event log 
    SEVChannelLoggerMT m_event_logger, m_status_logger; 

    /** 
    * Constructor - initialize each channel logger with a named 
    * channel attribute which will be used by filtering to route 
    * logging records to the appropriate sink. 
    */ 
    Logger(); 
    // singleton and locking support 
    static std::mutex gMutexGuard; 
    static Logger* gpInstance; 
}; 

#endif // _logger_h_ 

回答

2

您可能想要向上遊報告(或手動調試)。

更新這個問題已經被報告給升壓登錄開發者,他們有固定的(感謝@ johnco3)

下面是在Debian一樣的:

Live On Coliru (Debian)

#define BOOST_LOG_DYN_LINK 1 

#include <boost/filesystem.hpp> 
#include <boost/log/attributes/scoped_attribute.hpp> 
#include <boost/log/core.hpp> 
#include <boost/log/expressions.hpp> 
#include <boost/log/expressions/formatters/date_time.hpp> 
#include <boost/log/sinks/sync_frontend.hpp> 
#include <boost/log/sinks/text_ostream_backend.hpp> 
#include <boost/log/sources/severity_channel_logger.hpp> 
#include <boost/log/sources/channel_logger.hpp> 
#include <boost/log/sources/global_logger_storage.hpp> 
#include <boost/log/keywords/channel.hpp> 
#include <boost/log/keywords/severity.hpp> 
#include <boost/log/support/date_time.hpp> 
#include <boost/log/trivial.hpp> 
#include <boost/log/utility/manipulators/add_value.hpp> 
#include <boost/log/utility/setup/common_attributes.hpp> 
#include <boost/log/utility/setup/console.hpp> 
#include <fstream> 

#include <boost/log/sources/logger.hpp> 
#include <boost/log/sources/record_ostream.hpp> 
#include <boost/log/sources/global_logger_storage.hpp> 
#include <boost/log/utility/setup/file.hpp> 
#include <boost/log/utility/setup/common_attributes.hpp> 

namespace fs  = boost::filesystem; 
namespace logging = boost::log; 
namespace src  = boost::log::sources; 
namespace expr  = boost::log::expressions; 
namespace sinks = boost::log::sinks; 
namespace attrs = boost::log::attributes; 
namespace keywords = boost::log::keywords; 
namespace trivial = boost::log::trivial; 

struct Logger { 
    void init(const fs::path &rErrEvtPath, const fs::path &rStatusPath) { 
     // register common attributes - ThreadID, LineID, TimeStamp etc. 
     logging::add_common_attributes(); 

     // Construct the sink for the "event_log" channel 
     typedef sinks::synchronous_sink<sinks::text_ostream_backend> text_sink; 
     auto sink = boost::make_shared<text_sink>(); 
     sink->locked_backend()->auto_flush(true); 
     sink->locked_backend()->add_stream(boost::make_shared<std::ofstream>(rErrEvtPath.c_str())); 
     sink->set_formatter(expr::format("%1% [%2%] tid[%3%] %4%") % 
          expr::format_date_time<boost::posix_time::ptime>("TimeStamp", "%H:%M:%S.%f") % 
          logging::trivial::severity % expr::attr<attrs::current_thread_id::value_type>("ThreadID") % 
          expr::smessage); 
     sink->set_filter(expr::attr<std::string>("Channel") == "event"); 
     logging::core::get()->add_sink(sink); 

     // Construct the sink for the "status_log" channel 
     sink = boost::make_shared<text_sink>(); 
     sink->locked_backend()->auto_flush(true); 
     sink->locked_backend()->add_stream(boost::make_shared<std::ofstream>(rStatusPath.c_str())); 
     sink->set_formatter(expr::format("%1% [%2%] tid[%3%] %4%") % 
          expr::format_date_time<boost::posix_time::ptime>("TimeStamp", "%H:%M:%S.%f") % 
          logging::trivial::severity % expr::attr<attrs::current_thread_id::value_type>("ThreadID") % 
          expr::smessage); 
     sink->set_filter(expr::attr<std::string>("Channel") == "status"); 
     logging::core::get()->add_sink(sink); 
    } 
}; 

BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(statuc_lg, 
     src::severity_channel_logger_mt< >, (keywords::severity = trivial::error)(keywords::channel = "status")) 
BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(event_lg, 
     src::severity_channel_logger_mt< >, (keywords::severity = trivial::error)(keywords::channel = "event")) 

#include <boost/thread.hpp> 

int main() 
{ 
    Logger l; 
    l.init("test.1", "test.2"); 

    boost::thread_group tg; 
    tg.create_thread([]{ 
      BOOST_LOG(statuc_lg::get()) << "this is a status update"; 
      BOOST_LOG(event_lg::get()) << "this is an event"; }); 
    tg.create_thread([]{ 
      BOOST_LOG(statuc_lg::get()) << "this is a status update"; 
      BOOST_LOG(event_lg::get()) << "this is an event"; }); 

    tg.join_all(); 
} 

結果:

==> test.1 <== 
23:55:58.635779 [] tid[0x00007f26d9a65700] this is an event 
23:55:58.635832 [] tid[0x00007f26d9264700] this is an event 

==> test.2 <== 
23:55:58.635367 [] tid[0x00007f26d9a65700] this is a status update 
23:55:58.635540 [] tid[0x00007f26d9264700] this is a status update 
+0

感謝您的詳細示例和現場Coliru示例。直到星期一我纔有機會在我的目標平臺上測試這一點。你知道我的實現有什麼問題嗎?我在Windows上工作,但不在我的PowerPC嵌入式目標平臺上工作。也有一點相關,但是你知道如果無論如何強迫接收器在使用LF的平臺上生成CRLF行結束符,用戶希望使用記事本查看這些日誌文件,並且我寧願不必在日誌文件上運行dos2unix在他們被生成之後。 – johnco3 2014-11-15 22:15:27

+0

@ johnco3我不知道什麼是錯的。我真的認爲我的示例可能會顯示相同的行爲,在這種情況下,它只是/錯誤報告:)我會教用戶使用理智的編輯器(Notepad ++和其他許多免費的)。總是有'wordpad.exe'。最後,我不認爲在Boost /標準庫中有一種方法可以使行結束行爲非本地行爲 – sehe 2014-11-15 22:32:48

+0

感謝詳細的答案和註釋響應,我會在週一告訴您關於日誌記錄線程ID的信息,以及如果它解決了問題,我會檢查答案框 - 手指交叉! – johnco3 2014-11-16 01:19:27