如何为提升日志设置文本过滤器?
How to set a text filter for boost log?
从具有单个日志文件的日志设置开始,应添加第二个日志文件,其中仅包含消息中具有特定文本的行。
示例:
在单个日志文件中:
- “用户已登录”
- “用户 b 已登录”
- “用户 a 已注销”
在第二个日志文件中,只应包含用户 b 的消息:
- “用户 b 已登录”
创建日志记录的代码不受影响,示例:
BOOST_LOG_TRIVIAL(debug) << "user " << user << " logged in";
我正在寻找一种解决方案,可以过滤日志中的消息 class。
我已经开始工作了,但是我没有成功地使用参数进行工作。
// Main logging file
g_file_sink = logging::add_file_log
(
keywords::file_name = "General.%3N",
keywords::format = "[%TimeStamp%] [%Severity%] %Message%",
keywords::open_mode = (std::ios::out | std::ios::app),
keywords::auto_flush = true,
keywords::rotation_size = 1024,
);
// Second logging file
std::string text = "user a";
// define the filter
logging::filter flt =
[]
(std::string text)
{
std::stringstream ss;
ss << expr::smessage;
std::string message = ss.str();
return (message.find(text) == std::string::npos);
};
g_file1_sink = logging::add_file_log
(
keywords::file_name = test + ".%3N",
keywords::format = "[%TimeStamp%] [%Severity%] %Message%",
keywords::open_mode = (std::ios::out | std::ios::app),
keywords::auto_flush = true,
keywords::filter = flt,
keywords::rotation_size = 1024,
);
// Main filter
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::warning
);
logging::add_common_attributes();
当我对“文本”进行硬编码时
// define the filter
logging::filter flt =
[]
()
{
std::stringstream ss;
ss << expr::smessage;
std::string message = ss.str();
return (message.find("user a") == std::string::npos);
};
一切正常,我一添加变量文本,就在界面上遇到编译器错误。
有没有办法不用改调用码?
您不能将过滤器应用于日志记录消息文本,因为消息文本是在过滤完成后组成的。这是有意为之的,因为这样可以避免在无论如何要丢弃日志记录的情况下编写文本。
如果要过滤属于特定用户的日志记录,方法是使用属性。例如,您可以将用户名放在常量属性中,然后对该属性应用过滤器。根据您的代码设计,该属性可以添加到记录器或当前线程(例如,当 user-specific activity 被限制在一组固定的线程中时)。如果 user-specific activity 仅在给定范围内执行,您也可以使用 scoped attributes。
// Define attribute keyword
BOOST_LOG_ATTRIBUTE_KEYWORD(a_username, "Username", std::string)
void init_logging()
{
// Main logging file
g_file_sink = logging::add_file_log
(
keywords::file_name = "General.%3N",
keywords::format = "[%TimeStamp%] [%Severity%] %Message%",
keywords::open_mode = (std::ios::out | std::ios::app),
keywords::auto_flush = true,
keywords::rotation_size = 1024
);
// Second logging file
g_file1_sink = logging::add_file_log
(
keywords::file_name = "A.%3N",
keywords::filter = a_username == "A",
keywords::format = "[%TimeStamp%] [%Severity%] %Message%",
keywords::open_mode = (std::ios::out | std::ios::app),
keywords::auto_flush = true,
keywords::rotation_size = 1024
);
// Main filter
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::warning
);
logging::add_common_attributes();
}
int main()
{
init_logging();
// Create a logger that will emit log records not related to any specific user
boost::log::severity_logger< boost::log::trivial::severity_level > lg;
BOOST_LOG_SEV(lg, boost::log::trivial::warning)
<< "Log record with no username";
// Create a logger that will emit log records pertaining to user A
boost::log::severity_logger< boost::log::trivial::severity_level > lg_a;
lg_a.add_attribute(a_username.get_name(),
boost::log::attributes::make_constant(std::string("A")));
BOOST_LOG_SEV(lg_a, boost::log::trivial::warning)
<< "Log record related to user A";
}
请注意,您也可以在格式化程序中使用属性。这样您就可以在输出中标记与给定用户关联的所有记录。
从具有单个日志文件的日志设置开始,应添加第二个日志文件,其中仅包含消息中具有特定文本的行。
示例:
在单个日志文件中:
- “用户已登录”
- “用户 b 已登录”
- “用户 a 已注销”
在第二个日志文件中,只应包含用户 b 的消息:
- “用户 b 已登录”
创建日志记录的代码不受影响,示例:
BOOST_LOG_TRIVIAL(debug) << "user " << user << " logged in";
我正在寻找一种解决方案,可以过滤日志中的消息 class。
我已经开始工作了,但是我没有成功地使用参数进行工作。
// Main logging file
g_file_sink = logging::add_file_log
(
keywords::file_name = "General.%3N",
keywords::format = "[%TimeStamp%] [%Severity%] %Message%",
keywords::open_mode = (std::ios::out | std::ios::app),
keywords::auto_flush = true,
keywords::rotation_size = 1024,
);
// Second logging file
std::string text = "user a";
// define the filter
logging::filter flt =
[]
(std::string text)
{
std::stringstream ss;
ss << expr::smessage;
std::string message = ss.str();
return (message.find(text) == std::string::npos);
};
g_file1_sink = logging::add_file_log
(
keywords::file_name = test + ".%3N",
keywords::format = "[%TimeStamp%] [%Severity%] %Message%",
keywords::open_mode = (std::ios::out | std::ios::app),
keywords::auto_flush = true,
keywords::filter = flt,
keywords::rotation_size = 1024,
);
// Main filter
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::warning
);
logging::add_common_attributes();
当我对“文本”进行硬编码时
// define the filter
logging::filter flt =
[]
()
{
std::stringstream ss;
ss << expr::smessage;
std::string message = ss.str();
return (message.find("user a") == std::string::npos);
};
一切正常,我一添加变量文本,就在界面上遇到编译器错误。
有没有办法不用改调用码?
您不能将过滤器应用于日志记录消息文本,因为消息文本是在过滤完成后组成的。这是有意为之的,因为这样可以避免在无论如何要丢弃日志记录的情况下编写文本。
如果要过滤属于特定用户的日志记录,方法是使用属性。例如,您可以将用户名放在常量属性中,然后对该属性应用过滤器。根据您的代码设计,该属性可以添加到记录器或当前线程(例如,当 user-specific activity 被限制在一组固定的线程中时)。如果 user-specific activity 仅在给定范围内执行,您也可以使用 scoped attributes。
// Define attribute keyword
BOOST_LOG_ATTRIBUTE_KEYWORD(a_username, "Username", std::string)
void init_logging()
{
// Main logging file
g_file_sink = logging::add_file_log
(
keywords::file_name = "General.%3N",
keywords::format = "[%TimeStamp%] [%Severity%] %Message%",
keywords::open_mode = (std::ios::out | std::ios::app),
keywords::auto_flush = true,
keywords::rotation_size = 1024
);
// Second logging file
g_file1_sink = logging::add_file_log
(
keywords::file_name = "A.%3N",
keywords::filter = a_username == "A",
keywords::format = "[%TimeStamp%] [%Severity%] %Message%",
keywords::open_mode = (std::ios::out | std::ios::app),
keywords::auto_flush = true,
keywords::rotation_size = 1024
);
// Main filter
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::warning
);
logging::add_common_attributes();
}
int main()
{
init_logging();
// Create a logger that will emit log records not related to any specific user
boost::log::severity_logger< boost::log::trivial::severity_level > lg;
BOOST_LOG_SEV(lg, boost::log::trivial::warning)
<< "Log record with no username";
// Create a logger that will emit log records pertaining to user A
boost::log::severity_logger< boost::log::trivial::severity_level > lg_a;
lg_a.add_attribute(a_username.get_name(),
boost::log::attributes::make_constant(std::string("A")));
BOOST_LOG_SEV(lg_a, boost::log::trivial::warning)
<< "Log record related to user A";
}
请注意,您也可以在格式化程序中使用属性。这样您就可以在输出中标记与给定用户关联的所有记录。