日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

boost log使用

發布時間:2023/12/20 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 boost log使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.目標

程序日志輸出改進目標:

1. 用顏色區分錯誤和警告

2. 日志文件中用"warning"文本代替數字表示severity,便于日志中搜索

3. 合并log_setting.ini配置文件(到程序json配置文件,不使用init_from_stream)

4. 可同時輸出到console和文件

?

資料未整理完,以后再補充對程序的說明。

?

2.實現

log.h

enum SeverityLevel {SL_TRACE = 0,SL_DEBUG,SL_INFO,SL_WARNING,SL_ERROR,SL_CRITICAL };class Log { public:static void init_log(); private:static void init_logfile();static void init_console(); };boost::log::sources::severity_logger<SeverityLevel>* get_glog();

?

log.cpp

#include "log.h"#include<ios> #include <boost/ref.hpp> #include <boost/bind.hpp> #include <boost/log/core.hpp> #include <boost/log/common.hpp> #include <boost/log/attributes.hpp> #include <boost/log/core/record.hpp> #include <boost/log/utility/setup/common_attributes.hpp> #include <boost/log/expressions.hpp> #include <boost/log/sinks/text_ostream_backend.hpp> #include <boost/log/support/date_time.hpp> #include <boost/log/utility/setup/file.hpp> #include <boost/core/null_deleter.hpp>namespace logging = boost::log; namespace attrs = boost::log::attributes; namespace src = boost::log::sources; namespace sinks = boost::log::sinks; namespace expr = boost::log::expressions; namespace keywords = boost::log::keywords;/* Define place holder attributes */ BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int) BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime) //BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity_level) //BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity ) #include <boost/phoenix.hpp> BOOST_LOG_ATTRIBUTE_KEYWORD(process_id, "ProcessID", attrs::current_process_id::value_type ) BOOST_LOG_ATTRIBUTE_KEYWORD(thread_id, "ThreadID", attrs::current_thread_id::value_type )// Get Process native ID attrs::current_process_id::value_type::native_type get_native_process_id(logging::value_ref<attrs::current_process_id::value_type,tag::process_id> const& pid) {if (pid)return pid->native_id();return 0; }// Get Thread native ID attrs::current_thread_id::value_type::native_type get_native_thread_id(logging::value_ref<attrs::current_thread_id::value_type,tag::thread_id> const& tid) {if (tid)return tid->native_id();return 0; }typedef SeverityLevel severity_level; const char *get_severity_tag(severity_level level) {static const char* strings[] = {"trace","debug","info","waring","error","critical"};return static_cast< std::size_t >(level) < sizeof(strings) / sizeof(*strings) ? strings[level] : std::to_string(level).c_str(); }void coloring_formatter(logging::record_view const& rec, logging::formatting_ostream& strm) {logging::value_ref< severity_level > level = logging::extract< severity_level >("Severity", rec);switch(level.get()) {case crush::common::SL_TRACE:case crush::common::SL_DEBUG:case crush::common::SL_INFO:strm << "\033[32m";break;case crush::common::SL_WARNING:strm << "\033[33m";break;case crush::common::SL_ERROR:case crush::common::SL_CRITICAL:strm << "\033[31m";break;default:break;}strm << logging::extract< unsigned int >("LineID", rec) << "|";auto date_time_formatter = expr::stream << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S.%f");date_time_formatter(rec, strm);strm <<"|";strm<< std::dec<< logging::extract< attrs::current_process_id::value_type >("ProcessID", rec);strm << "|";strm<< std::dec<< logging::extract< attrs::current_thread_id::value_type >("ThreadID", rec);strm << "|";strm<< get_severity_tag(level.get());strm<< "|";strm<<"--";strm << rec[logging::expressions::smessage];// Restore the default colorstrm << "\033[0m"; }struct severity_tag; logging::formatting_ostream& operator<< (logging::formatting_ostream& strm,logging::to_log_manip< severity_level, severity_tag > const& manip ) {severity_level level = manip.get();strm << get_severity_tag(level);return strm; }BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(glog, boost::log::sources::severity_logger<SeverityLevel>);void Log::init_console() {typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink;boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();boost::shared_ptr< std::ostream > stream(&std::clog, boost::null_deleter());sink->locked_backend()->add_stream(stream);sink->set_formatter(&coloring_formatter);logging::core::get()->add_sink(sink); }void Log::init_logfile() {logging::add_file_log(keywords::file_name = "%Y-%m-%d_%5N.log",keywords::rotation_size = 10 * 1024 * 1024,keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),keywords::auto_flush = true,keywords::open_mode = std::ios::out | std::ios::app,keywords::format =(expr::stream<< expr::attr< unsigned int >("LineID")<<"|"<< expr::format_date_time(expr::attr< boost::posix_time::ptime >("TimeStamp"), "%Y-%m-%d, %H:%M:%S.%f") << "|"<< boost::phoenix::bind(&get_native_process_id, process_id.or_none()) << ":"<< boost::phoenix::bind(&get_native_thread_id, thread_id.or_none()) << "|"<< "[" << expr::attr< severity_level, severity_tag >("Severity")<< "] " << expr::smessage)); } void Log::init_log() {logging::core::get()->set_filter([](const logging::attribute_value_set& attr_set) {return attr_set["Severity"].extract<severity_level>() >= SL_WARNING;});init_logfile();init_console();logging::add_common_attributes(); }boost::log::sources::severity_logger<SeverityLevel>* get_glog() {return &(glog::get()); }

3.使用

#include "log.h"void test_log() {Log::init();BOOST_LOG_SEV(*(crush::common::get_glog()), SL_TRACE) << "A trace severity message";BOOST_LOG_SEV(*(crush::common::get_glog()), SL_DEBUG) << "A debug severity message";BOOST_LOG_SEV(*(crush::common::get_glog()), SL_INFO) << "An informational severity message";BOOST_LOG_SEV(*(crush::common::get_glog()), SL_WARNING) << "A warning severity message";BOOST_LOG_SEV(*(crush::common::get_glog()), SL_ERROR) << "An error severity message";BOOST_LOG_SEV(*(crush::common::get_glog()), SL_CRITICAL) << "A fatal severity message";LOG_TRACE<<"this a trace";LOG_ERROR<<"this a error";return; }

4.資料

4.1Howto

How to add color coding to boost::log console output?
https://stackoverflow.com/questions/38309479/how-to-add-color-coding-to-boostlog-console-output

A simple, customized logger, based on Boost.Log v2
http://gernotklingler.com/blog/simple-customized-logger-based-boost-log-v2/

how to print ProcessID and ThreadID in dec-format with boost.log
https://stackoverflow.com/questions/27597196/how-to-print-processid-and-threadid-in-dec-format-with-boost-log

how to customize “TimeStamp” format of Boost.Log
https://stackoverflow.com/questions/5947018/how-to-customize-timestamp-format-of-boost-log

How to use boost::log::expressions::format_date_time in a custom formatting function?
https://stackoverflow.com/questions/24287547/how-to-use-boostlogexpressionsformat-date-time-in-a-custom-formatting-func

boost log, why not print threadid and processid
https://stackoverflow.com/questions/46337337/boost-log-why-not-print-threadid-and-processid

Boost set_filter is not working
https://stackoverflow.com/questions/29707017/boost-set-filter-is-not-working

boost.log : using c++11 lambda expression to filter severity level
https://stackoverflow.com/questions/32399608/boost-log-using-c11-lambda-expression-to-filter-severity-level

Boost log and severity / local attributes

https://stackoverflow.com/questions/35895199/boost-log-and-severity-local-attributes

支持__FILE__,__LINE__

boost.log要點筆記

https://www.cnblogs.com/liaocheng/p/4222885.html

?

4.2官方文檔

Setting up sinks
https://www.boost.org/doc/libs/1_67_0/libs/log/doc/html/log/tutorial/sinks.html

Adding more information to log: Attributes
https://www.boost.org/doc/libs/1_67_0/libs/log/doc/html/log/tutorial/attributes.html
https://www.boost.org/doc/libs/1_67_0/libs/log/doc/html/log/detailed/expressions.html#log.detailed.expressions.attr

Sink backends
https://www.boost.org/doc/libs/master/libs/log/doc/html/log/detailed/sink_backends.html
Filters
http://boost-log.sourceforge.net/libs/log1/doc/html/log/detailed/filters.html

Log record formatting

https://www.boost.org/doc/libs/1_67_0/libs/log/doc/html/log/tutorial/formatters.html

logging::init_from_settings,

https://www.boost.org/doc/libs/1_67_0/libs/log/doc/html/log/detailed/utilities.html#log.detailed.utilities.setup.filter_formatter

?

5.經驗

5.1使用logging::formatter_factory

#日志輸出格式
Format=[%TimeStamp% PID:%ProcessID% ThreadID:%ThreadID%] [%Severity%] %MyScopes% %Message%"

注意%MyScopes%

struct ScopeListFormatter {typedef attrs::named_scope::value_type scope_stack;explicit ScopeListFormatter(logging::attribute_name const &name) :name_(name) {}/// @notes/// rec.attribute_values()是attrs::named_scope::value_type嗎?/// 代碼的運行效果是:%MyScopes%處輸出有顏色的當前時間. /// ? 無法控制日志輸出的其它項,如%Message%void operator()(logging::record_view const &rec, logging::formatting_ostream &strm) const {// We need to acquire the attribute value from the log recordlogging::value_ref< severity_level > level = logging::extract< severity_level >("Severity", rec);if (level==SL_ERROR)strm<< "\033[31m";logging::visit<scope_stack>(name_,rec.attribute_values(),boost::bind(&ScopeListFormatter::format, _1, boost::ref(strm)));strm<<"\033[0m";}private://! This is where our custom formatting takes placestatic void format(scope_stack const &scopes, logging::formatting_ostream &strm) {using namespace std::chrono;system_clock::time_point time_now = system_clock::now();microseconds duration_in_mics = duration_cast<microseconds>(time_now.time_since_epoch());strm << "[" << duration_in_mics.count() << "]";scope_stack::const_iterator it = scopes.begin(), end = scopes.end();/// @notes /// .scopes是空的,怎么才能加入元素?/// . it->scope_name,it->file_name的含義和使用? for (; it != end; ++it) {strm << "\t" << it->scope_name << " [" << it->file_name << ":" << it->line << "]\n";}}private:logging::attribute_name name_; };class MyScopesFormatterFactory :public logging::formatter_factory<char> { public: // // * This function creates a formatter for the MyScopes attribute. // * It effectively associates the attribute with the scope_list_formatter class //formatter_type create_formatter(logging::attribute_name const &attr_name, args_map const &args) {return formatter_type(ScopeListFormatter(attr_name));} };

調用代碼:

logging::register_formatter_factory("MyScopes", boost::make_shared<MyScopesFormatterFactory>()); logging::core::get()->add_global_attribute("MyScopes", attrs::named_scope());

?

5.2使用logging::init_from_stream

[Core] #是否開啟Log DisableLogging=false[Sinks.TextFileSettings] #輸出到哪,支持TextFile Console Destination=Console#過濾日志等級 #trace = 0, debug = 1, info = 2, warning = 3, error = 4, critical = 5 Filter="%Severity% >= 0"#輸出的文件名 FileName="%Y-%m-%d_%5N.log"#單個log文件大小 RotationSize=204800000#產生新的log文件時間點 RotationTimePoint="00:00:00"#是否開啟追加 Append=true#是否自動刷新 AutoFlush=true#日志輸出格式 Format="[%TimeStamp% PID:%ProcessID% ThreadID:%ThreadID%] [%Severity%] %MyScopes% %Message%"#是否開啟異步 Asynchronous=false

使用代碼:

std::ifstream settings(filepath); logging::init_from_stream(settings);

5.3自定義severity

severity_level類型
不同的severity_level定義,coloring_formatter中level的內容不同.?? ??? ?

typedef int severity_level; ///level有內容,正確 typedef SeverityLevel severity_level; ///< level.get(),斷言拋出異常.void coloring_formatter(logging::record_view const& rec, logging::formatting_ostream& strm) {logging::value_ref< severity_level > level = logging::extract< severity_level >("Severity", rec);switch(level.get()) {

? 異常的原因是未指定?SeverityLevel參數

修改

boost::log::sources::severity_logger<>* get_glog(); BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(glog, boost::log::sources::severity_logger<>);??

?為:

boost::log::sources::severity_logger<SeverityLevel>* get_glog(); BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(glog, boost::log::sources::severity_logger<SeverityLevel>);?? ???

?

5.4 logging::formatter

console的格式化輸出的另外一種方式.?? ??? ??

void Log::init_console() {typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink;boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();boost::shared_ptr< std::ostream > stream(&std::clog, boost::null_deleter());sink->locked_backend()->add_stream(stream);// ? sink->set_formatter(&coloring_formatter);/// @note 是phoneix函數對象?logging::formatter formatter = expr::stream<< std::setw(7) << std::setfill('0') << line_id << std::setfill(' ') << " | "<< expr::format_date_time(timestamp, "%Y-%m-%d, %H:%M:%S.%f") << " "<< "[" << logging::trivial::severity << "]"<< " - " << expr::smessage;sink->set_formatter(formatter)logging::core::get()->add_sink(sink); }

boost 的函數式編程庫 Phoenix入門學習
https://blog.csdn.net/doon/article/details/9119601
?? ??? ?

5.5 BOOST_LOG_ATTRIBUTE_KEYWORD

查看宏展開代碼
創建test2.cpp,內容如下:

#include <boost/log/attributes.hpp> #include <boost/log/expressions.hpp>BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int) BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime)

編譯:

? g++ -std=c++11 -g -E -P ?-c ./test2.cpp > b.txt

查看b.txt內容:
line_id,timestamp展開后的定義:

namespace tag { struct line_id : public ::boost::log::expressions::keyword_descriptor {typedef unsigned int value_type;static ::boost::log::attribute_name get_name() {return ::boost::log::attribute_name("LineID");} }; }? typedef ::boost::log::expressions::attribute_keyword< tag::line_id > line_id_type;const line_id_type line_id = {};namespace tag { struct timestamp : public ::boost::log::expressions::keyword_descriptor {typedef boost::posix_time::ptime value_type;static ::boost::log::attribute_name get_name() {return ::boost::log::attribute_name("TimeStamp");} }; }?typedef ::boost::log::expressions::attribute_keyword< tag::timestamp > timestamp_type;? const timestamp_type timestamp = {};

相關宏:
文件:/usr/local/include/boost/log/expressions/keyword.hpp

#define BOOST_LOG_ATTRIBUTE_KEYWORD(keyword_, name_, value_type_)\BOOST_LOG_ATTRIBUTE_KEYWORD_IMPL(keyword_, name_, value_type_, tag)#define BOOST_LOG_ATTRIBUTE_KEYWORD_IMPL(keyword_, name_, value_type_, tag_ns_)\BOOST_LOG_ATTRIBUTE_KEYWORD_TYPE_IMPL(keyword_, name_, value_type_, tag_ns_)\const BOOST_PP_CAT(keyword_, _type) keyword_ = {};?? ?

默認屬性:?? ?

namespace boost { namespace log { inline namespace v2s_mt_posix { namespace aux { namespace default_attribute_names {attribute_name severity();attribute_name channel();attribute_name message();attribute_name line_id();attribute_name timestamp();attribute_name process_id();attribute_name thread_id(); } } }} }

5.6 keywords::format指定?? ?

void Log::init_logfile() {logging::add_file_log(keywords::file_name = "%Y-%m-%d_%5N.log",keywords::rotation_size = 10 * 1024 * 1024,keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),keywords::auto_flush = true,keywords::open_mode = ?std::ios::out | std::ios::app,/// @notes 屬性名稱方式// ? ? ? keywords::format = "[%TimeStamp% PID:%ProcessID% ThreadID:%ThreadID%] [%Severity%] ?%Message%"// @question 以下是lambda還是phoneix?keywords::format =(expr::stream<< expr::attr< unsigned int >("LineID")<<"|"<< expr::format_date_time(expr::attr< boost::posix_time::ptime >("TimeStamp"), "%Y-%m-%d, %H:%M:%S.%f") << "|"<< boost::phoenix::bind(&get_native_process_id, process_id.or_none()) << ":"<< boost::phoenix::bind(&get_native_thread_id, thread_id.or_none()) << "|"/// @question 以下2行代碼輸出的內容怎么是空的? // ? ? ?? ?<< logging::expressions::attr<logging::attributes::current_thread_id::value_type>("ThreadID") << ":" // ??? ?<< logging::expressions::attr<logging::attributes::current_process_id::value_type>("ProcessID") << ?"|"<< "[" << expr::attr< severity_level, severity_tag >("Severity")<< "] " << expr::smessage)); }?? ?

5.7add_global_attribute

? ? boost::shared_ptr< logging::core > core = logging::core::get();core->add_global_attribute("LineID", attrs::counter< unsigned int >(1));core->add_global_attribute("TimeStamp", attrs::local_clock());

5.8set_filter

方法1:

? logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info);

方法2:對于自定義severity級別 ?

? logging::core::get()->set_filter([](const logging::attribute_value_set& attr_set) {return attr_set["Severity"].extract<severity_level>() >= SL_WARNING;}) ?

5.9logging::init_from_settings

以下代碼未驗證

void init_logging() {logging::settings setts;setts["Core"]["Filter"] = "%Severity% >= warning";setts["Core"]["DisableLogging"] = false;// Subsections can be referred to with a single pathsetts["Sinks.Console"]["Destination"] = "Console";setts["Sinks.Console"]["Filter"] = "%Severity% >= fatal";setts["Sinks.Console"]["AutoFlush"] = true;// ...as well as the individual parameterssetts["Sinks.File.Destination"] = "TextFile";setts["Sinks.File.FileName"] = "MyApp_%3N.log";setts["Sinks.File.AutoFlush"] = true;setts["Sinks.File.RotationSize"] = 10 * 1024 * 1024; // 10 MiBlogging::init_from_settings(setts); }

?

總結

以上是生活随笔為你收集整理的boost log使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。