최신 버전의 부스트 1.57로 파일에 로그 문자열을 보내려고하고 있고, 리눅스에서 어떤 이유로 스레드 ID가 항상 0으로 설정되어 있습니다. 나는 그것이 부스트 쓰레드 대신 네이티브 쓰레드를 사용하는 것과 관련이 있다고 생각하지만, 왜 그것이 윈도우 환경에서 작동하는지 설명하지 못한다. 어떤 도움을 주시면 감사하겠습니다.부스트 로깅이 리눅스 스레드 ID를 모두 0으로 표시합니다.
다음은 logger.cpp 파일의 초기화 코드입니다.
편집 : 아래 그림은 나 또한 내가 사용하는 로거의 유형을 보여 내 Logger.h 포함했다 - 효과적으로
향상에 로그인 할 BOOST_LOG_CHANNEL_SEV 매크로를 사용하여 :: 로그인 :: 소스 : :
,369 즉 잘 윈도우 디스플레이에 < 부스트 severity_channel_logger_mt :: 로그인 :: 사소한 :: 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);
}
로그 다음과 같이 부스트 1.57.0의 동일한 버전을 사용하는 리눅스 (PPC)에 그러나 1,363,210
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"
로그입니다
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<]
편집 : 완성도 - 나는
#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_
자세한 예제 및 라이브 Coliru 예를 들어 주셔서 감사합니다. 나는 월요일까지 나의 목표 플랫폼에서 이것을 시험 할 기회를 얻지 못할 것이다. 내 구현에 어떤 문제가 있었는지 아십니까? 광산은 Windows에서 작동했지만 내 PowerPC 임베디드 대상 플랫폼에서는 작동하지 않았습니다. 또한 약간 관련이 있지만 싱크대가 LF를 사용하는 플랫폼에서 CRLF 줄 끝을 생성하도록 강제하는 경우 사용자가 메모장을 사용하여 이러한 로그 파일을보고 싶습니다. 로그 파일에서 dos2unix를 실행하지 않아도됩니다. 생성 된 후에 – johnco3
@ johnco3 무엇이 잘못되었는지 나는 모른다. 나는 실제로 내 견본이 아마도 같은 행동을 보여줄 것이라고 생각한다. 그 경우는/그냥/버그 보고서이다. 나는 사용자가 정상적인 편집기 (메모장 ++ 및 많은 다른 것들은 무료)를 사용하도록 가르 칠 것이다. 항상'wordpad.exe '가 있습니다. 그리고 마지막으로, 부스트/표준 라이브러리에서 라인 끝이 비 - 네이티브로 동작하도록하는 방법이 없다고 생각합니다. – sehe
자세한 답변과 주석 응답을 주셔서 감사합니다. 월요일에 로깅 스레드 ID에 대해 알려 드리겠습니다. 그것이 문제를 해결하면 나는 대답 한 상자를 점검 할 것이다. – johnco3