微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Boost.Log,在文件名或配置文件的目标值中使用自定义属性

如何解决Boost.Log,在文件名或配置文件的目标值中使用自定义属性

我在 C++ 中使用 Boost.Log 来记录日志,并使用配置文件。我添加了一些自定义属性并在配置文件中使用它们。下面是C++中属性注册

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;

attr1 myProcessID("");
attr2 myThreadID("");
attr3 myThreadindex("")
attr4 theCorrelationId("");
attr5 theMiscInfos("");

slg_mt::get().add_attribute("Process_ID",myProcessID);
slg_mt::get().add_attribute("Thread_ID",myThreadID);
slg_mt::get().add_attribute("Thread_Index",myThreadindex);
slg_mt::get().add_attribute("Correlation_ID",theCorrelationId);
slg_mt::get().add_attribute("MiscInfos",theMiscInfos);

我定义了一个配置文件,并使用 boost::log::init_from_stream 以正常方式初始化配置文件

如果我使用以下配置,它运行良好:

[Sinks.TRACE]
Destination="TextFile"

Asynchronous="true"
AutoFlush="true"
Format="[TimeStamp %TimeStamp(format=\"%Y-%m-%d %H:%M:%s.%f\")%][UpTime 
%Uptime(format=\"%O:%M:%s.%f\")%][ProcessID: %Process_ID%][ThreadID: %Thread_ID% %Thread_Index%] %Message%"
Target="C:\BoostLogTrace"
FileName="C:\BoostLogTrace\REST_%N.log"
RotationSize="10485760"
ScanForFiles="Matching"
Filter="%severity% = trace" 

一切正常。除了我想不仅在日志条目中,而且在日志目标和文件名中使用我的自定义属性

当我尝试使用以下文件名时,它不起作用:

FileName="C:\BoostLogTrace\REST_%THREAD_ID%.log"

有没有办法使用自定义属性更改目标和文件名,属性值从一个日志条目更改为另一个

从更高的角度来看,我需要在不同的日志文件中记录每个单独的用户会话。如何使用 Boost.log 执行此操作?

谢谢!

解决方法

您可以使用 multi-file sink backend 登录到单独的文件。该后端支持从附加到日志记录的属性生成文件名。

但是,默认情况下不支持从配置文件进行初始化。您必须为此接收器后端 register a factory 并从解析的 settings 实施配置此接收器。您可以重用过滤器和格式化程序解析器,也可以使用格式化程序解析器构建文件名生成器。

class multifile_factory :
    public logging::sink_factory< char >
{
public:
    // Creates the sink with the provided parameters
    boost::shared_ptr< sinks::sink > create_sink(settings_section const& settings)
    {
        boost::shared_ptr< sinks::text_multifile_backend > backend =
            boost::make_shared< sinks::text_multifile_backend >();

        // Read sink parameters
        if (boost::optional< std::string > param = settings["FileName"])
        {
            backend->set_file_name_composer(sinks::file::as_file_name_composer(
                logging::parse_formatter(*param)));
        }
        else
            throw std::runtime_error("No target file name specified in settings");

        typedef sinks::synchronous_sink< sinks::text_multifile_backend > sink_t;
        boost::shared_ptr< sink_t > sink = boost::make_shared< sink_t >(backend);

        if (boost::optional< std::string > param = settings["Filter"])
            sink->set_filter(logging::parse_filter(*param));

        if (boost::optional< std::string > param = settings["Format"])
            sink->set_formatter(logging::parse_formatter(*param));

        return sink;
    }
};

logging::register_sink_factory("TextMultifile",boost::make_shared< multifile_factory >());

然后您可以使用“TextMultifile”作为配置文件中的“Destination”参数值。您可以像以前一样解析配置文件,通过调用 init_from_streaminit_from_settings,初始化例程将调用工厂来创建和配置接收器。

请注意,text_multifile_backend 不支持日志文件轮换,因为它不跟踪它生成的单个文件。如果您仍然需要文件轮换和管理轮换的文件,那么您还必须实现自己的接收器后端。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?