29 Aralık 2017 Cuma

log core Sınıfı

Giriş
Şu satırı dahil ederiz.
#include <boost/log/core.hpp>
add_global_attribute metodu
Şu satırı dahil ederiz.
#include <boost/log/attributes.hpp>
Şöyle yaparız.
core->add_global_attribute("UTCTimeStamp",boost::log::attributes::utc_clock());
Şöyle yaparız.
logging::core::get()->add_global_attribute("TimeStamp", attrs::local_clock());
add_sink metodu
Şöyle yaparız.
auto sink = ...;
core->add_sink(sink);
get metodu
Şöyle yaparız.
auto core = boost::log::core::get();
remove_sink metodu
Örnek
Şöyle yaparız. add_file_log() çağrısı ile eklenen sink'i siler.
typedef sinks::synchronous_sink< sinks::text_file_backend > sink_t;
boost::shared_ptr< sink_t > g_file_sink;

void Init() {
  // ...
  g_file_sink = logging::add_file_log
  (
    keywords::file_name     = logfile + "_%N.log",
    keywords::rotation_size = 1024 * 1024 * 50, // 50MB log file max
    keywords::format        = "%Message% #[%TimeStamp%]"
  );

  // ...
}

void StopFileLogging() {
  logging::core::get()->remove_sink(g_file_sink);
  g_file_sink.reset();
}
Örnek
Şöyle yaparız. Bu sefer kaldırılan sink flush() edilerek boşaltılıyor.
boost::log::core::get()-> remove_sink(sinkptr);

sinkptr->flush();

sinkptr.reset();
set_flter metodu ve evaluation
Şöyle yaparız.
#include <chrono>
#include <thread>

#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/trivial.hpp>

std::string time_costly_function(
  const std::chrono::seconds seconds = std::chrono::seconds{1}) {
  std::this_thread::sleep_for(seconds);
  return "DONE with time_costly_function";
}


boost::log::core::get()->set_filter(boost::log::trivial::severity >=
                                    boost::log::trivial::warning);
BOOST_LOG_TRIVIAL(warning) << "This is evaluated: " << time_costly_function();
BOOST_LOG_TRIVIAL(info) << "This is NOT evaluated: "<< time_costly_function();
Çıktı olarak sadece birinci log'u alırız. Sebebi ise BOOSt_LOG_TRIVIAL macrosunun şuna benzemesi. Yani önce filter kontrol edilir. Eğer true ise ikinci metod çağrılır.
#define FW_LOG(logger, level, message) \
  do { if (logger.check_level(level)) logger.log(message); while (false)
set_filter metodu - filter
Açıklaması şöyle.
The first argument in the filter expression is a keyword and also a Boost.Phoenix terminal
It makes the filter expression build a Boost.Phoenix function object instead of evaluating
the comparison immediately.
Global bir filtre oluşturur. Global filtre yerine tek bir sink'e de filtre atanabilir.
filter tipinden bir nesnesi alır. Şöyle yaparız.
core->set_filter (
  boost::log::trivial::severity >= boost::log::trivial::warning
);
Şöyle yaparız
core->set_filter (
  boost::log::trivial::severity >= boost::log::trivial::info
);
Şöyle yaparız.
logging::core::get()->set_filter (
  //Write all records with "info" severity or higher
  expr::attr<SeverityLevel>("Severity").or_default(SeverityLevel::INFO)
    >= SeverityLevel::INFO
);
set_filter - metod
Eğer nesne değil de metod kullanmak istersek şöyle yaparız.
// Define your severity levels
enum severity_level
{
    debug, normal, error, fatal
};

// Define an attribute keyword for severity level
BOOST_LOG_ATTRIBUTE_KEYWORD(a_severity, "Severity", severity_level)

// Define a logger type that uses your severity levels
typedef boost::log::sources::severity_logger< severity_level > logger;

// Define a filter that will check the severity
bool abort_filter(
    boost::log::value_ref< severity_level, tag::a_severity > const& level)
{
    // Don't forget to check if the record has a severity level at all
    if (level && level.get() >= error)
        std::abort();

    // Pass all log records that didn't trigger the abort
    return true;
}
Şöyle yaparız.
// Set global filter
boost::log::core::get()->set_filter(
  boost::phoenix::bind(&abort_filter, a_severity.or_none()));


28 Aralık 2017 Perşembe

phoenix

Giriş
Şu satırı dahil ederiz.
#include <boost/phoenix.hpp>
Kolay kullanım için şu satırları dahil ederiz.
namespace phx = boost::phoenix;
using boost::phoenix::placeholders::arg1;
using boost::phoenix::local_names::_a;
std::place_holders::_1, _2 yerine boost::phoenix::arg_names::arg1, arg2 kullanılır.

for_each metodu
Şöyle yaparız.
std::vector<int> const small_ints {1, 2, 3, 4, 5};
std::vector<int> const big_ints {11, 12, 13, 14, 15};

namespace phx = boost::phoenix;
using boost::phoenix::placeholders::arg1;
using boost::phoenix::local_names::_a;

std::vector<int>::const_iterator big_ints_it;
std::for_each(small_ints.cbegin(), small_ints.cend(),
  phx::for_each(phx::cref(big_ints),phx::lambda(...)[...])
);
function Sınıfı
Şöyle yaparız.
struct MyType {
  MyType()
    : complete_(complete_f { this }) 
  { }

  void doSomething() { }

private:    
  struct complete_f {
    MyType* _this;
    void operator()() const {
      // do something with _this, e.g
      this->doSomething();
    }
  };

  boost::phoenix::function<complete_f> complete_;
};
ref metodu
lambda üretir.

Örnek
Şöyle yaparız.
namespace phx = boost::phoenix;

boost::mutex mx;
boost::condition_variable cv;
boost::unique_lock<boost::mutex> lk(mx);
cv.wait(lk, phx::ref(m_queue_size) > 0);
Örnek
Şöyle yaparız
using boost::phoenix::placeholders::arg1;
using boost::phoenix::local_names::_a;

phx::lambda(_a=arg1)[phx::ref(std::cout) << '(' << _a << ", " << arg1 << "), "]