铸造一个boost ::登录::前pressions :: ATTR<标准::字符串>为std :: string的 [英] Cast a boost::log::expressions::attr< std::string > to std::string

查看:220
本文介绍了铸造一个boost ::登录::前pressions :: ATTR<标准::字符串>为std :: string的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用Boost.Log,我想保持我的时间戳格式,如:

While using Boost.Log, I am trying to keep my TimeStamp formatter such as:

  logging::add_file_log
    (
     keywords::file_name = "my.log",
     keywords::format =
     (
      expr::stream
      << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
      << "," << expr::attr< int >("Line")
      << " " << expr::attr< std::string >("File")
      << " " << logging::trivial::severity
      << " - " << expr::smessage
     )
    );

有人说,我不能使用格式化的其他形式的,因为我有很多的困难转向时间戳进入我的自定义格式为:

It is said that I cannot use the other form of formatter since I'll have much difficulties turning "TimeStamp" into my custom format:

static void my_formatter(logging::record_view const& rec, logging::formatting_ostream& strm)
{
  strm << logging::extract< boost::posix_time::ptime >("TimeStamp", rec);

将输出类似: 2015年 - 07月01 16:06:31.514053 ,而我只关心:%Y-% M-%D%H:%M:%S。然而,第一种形式是非常难用,比如我不能够施展的 EXPR :: ATTR&LT;标准::字符串&GT; 来一个简单的的std ::字符串例如:

will output something like: 2015-Jul-01 16:06:31.514053, while I am only interested in: "%Y-%m-%d %H:%M:%S". However the first form is extremely hard to use, for instance I am not able to cast an expr::attr< std::string > to a simple std::string for instance:

  logging::add_file_log
    (
     keywords::file_name = "my.log",
     keywords::format =
     (
      expr::stream
      << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
      << "," << expr::attr< int >("Line")
      << " " << boost::filesystem::path(expr::attr< std::string >("File"))
        .filename().string()
      << " " << logging::trivial::severity
      << " - " << expr::smessage
     )
    );

以上code甚至不进行编译。

The above code does not even compile.

有没有一种简单的方法,以两个打印时间戳使用我的自定义格式,并在同一时间使用自定义强制转换为字符串,可以使用的boost ::文件系统::路径::文件名()

Is there an easy way to both print TimeStamp using my custom format and at the same time use a custom cast to string to be able to use boost::filesystem::path::filename() ?

推荐答案

有多种方法来实现你想要的。关键的一点理解的是,Boost.Log格式化前pressions(以及过滤器的方式)是Boost.Phoenix lambda函数。因此,你可以使用Boost.Phoenix构造,如的boost ::凤凰::绑定中注入他们自己的函数。看一个例子<一个href=\"http://www.boost.org/doc/libs/1_58_0/libs/log/doc/html/log/extension.html#log.extension.sinks.formatting_sink_backend\"相对=nofollow>这里,例如。您code会是这个样子:

There are multiple ways to achieve what you want. The key point to understand is that Boost.Log formatting expressions (as well as filters, by the way) are Boost.Phoenix lambda functions. As such you can inject your own functions in them using Boost.Phoenix constructs such as boost::phoenix::bind. See an example here, for instance. Your code would look something like this:

std::string file_basename(logging::value_ref< std::string > const& filename)
{
  // Check to see if the attribute value has been found
  if (filename)
    return boost::filesystem::path(filename.get()).filename().string();
  else
    return std::string();
}

// ...

logging::add_file_log
(
  keywords::file_name = "my.log",
  keywords::format =
  (
    expr::stream
      << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S")
      << "," << expr::attr< int >("Line")
      << " " << boost::phoenix::bind(&file_basename, expr::attr< std::string >("File"))
      << " " << logging::trivial::severity
      << " - " << expr::smessage
  )
);

另一种方法是使用属性关键字和定义一个运营商的LT;&LT; 具体的文件属性。你可以找到一个例子<一个href=\"http://www.boost.org/doc/libs/1_58_0/libs/log/doc/html/log/detailed/ex$p$pssions.html#log.detailed.ex$p$pssions.attr.tags\"相对=nofollow>这里。

Another way to do that is to use attribute keywords and define an operator<< specific for the File attribute. You can find an example here.

BOOST_LOG_ATTRIBUTE_KEYWORD(a_timestamp, "TimeStamp", boost::posix_time::ptime)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_line, "Line", int)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_file, "File", std::string)

namespace std {

logging::formatting_ostream& operator<<
(
  logging::formatting_ostream& strm,
  logging::to_log_manip< std::string, tag::a_file > const& manip
)
{
  strm << boost::filesystem::path(manip.get()).filename().string();
  return strm;
}

} // namespace std

// ...

logging::add_file_log
(
  keywords::file_name = "my.log",
  keywords::format =
  (
    expr::stream
      << expr::format_date_time(a_timestamp, "%Y-%m-%d %H:%M:%S")
      << "," << a_line
      << " " << a_file
      << " " << logging::trivial::severity
      << " - " << expr::smessage
  )
);

注意属性关键字显著简化前pressions。

Notice that attribute keywords simplify expressions significantly.

最后,您可以使用<一个href=\"http://www.boost.org/doc/libs/1_58_0/libs/log/doc/html/boost/log/ex$p$pssions/wrap_formatter_idp48923680.html\"相对=nofollow> wrap_formatter 注入自己的函数到流前pression。当涉及到格式, wrap_formatter 调用你的函数为其提供格式化的日志记录和格式流。当你的函数返回包装自动返回参考格式流,使得格式化前pression的其余部分可以继续进行。

Lastly, you can use wrap_formatter to inject your own function into the streaming expression. When it comes to formatting, wrap_formatter invokes your function providing it with the log record being formatted and the formatting stream. When your function returns the wrapper automatically returns the reference to the formatting stream so that the rest of the formatting expression can proceed.

BOOST_LOG_ATTRIBUTE_KEYWORD(a_timestamp, "TimeStamp", boost::posix_time::ptime)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_line, "Line", int)
BOOST_LOG_ATTRIBUTE_KEYWORD(a_file, "File", std::string)

void file_basename(logging::record_view const& record, logging::formatting_ostream& strm)
{
  // Check to see if the attribute value has been found
  logging::value_ref< std::string, tag::a_file > filename = record[a_file];
  if (filename)
    strm << boost::filesystem::path(filename.get()).filename().string();
}

// ...

logging::add_file_log
(
  keywords::file_name = "my.log",
  keywords::format =
  (
    expr::stream
      << expr::format_date_time(a_timestamp, "%Y-%m-%d %H:%M:%S")
      << "," << a_line
      << " " << expr::wrap_formatter(&file_basename)
      << " " << logging::trivial::severity
      << " - " << expr::smessage
  )
);

以上是类似于使用的boost ::凤凰::绑定第一变量,但允许在 file_basename 实施

The above is similar to the first variant with boost::phoenix::bind but allows for more flexibility in the file_basename implementation.

这篇关于铸造一个boost ::登录::前pressions :: ATTR&LT;标准::字符串&GT;为std :: string的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆