void stereoview::save_image(logger& l, const image_id_type& id, const QString& filepath, int quality) const { const option<QSize>& rs = rescale(); const auto stimg = access_stored_image(id).atomic(); const auto&& qimg = stimg->image(rs); l.msg(nfmt<5>("saving image ID:%1 with quality %2 at %3x%4 to file %5...") (id) (quality) (qimg.width()) (qimg.height()) (filepath)); if (!qimg.save(filepath, NULL, quality)) l.msg(nfmt<0>("ERROR: cannot save image to disk.")); }
void stereoview::parse_siftpp_keyfile(logger& l, progress_tracker&&, const image_id_type& id, const QString& filepath, const std::function<float(float)>& adapt_scale, const std::function<float(float)>& adapt_rot, const std::function<float(unsigned int)>& adapt_descr) { QString&& ins = read_file_for_parsing(filepath); QTextStream s(&ins); l.msg(nfmt<1>("parsing SIFT++ keyfile '%1' with 128-dimesional descriptor...") (filepath)); auto sl = access_stored_image(id).atomic(); auto& stimg = *sl; // get the number of features unsigned int n_keyp = 0; { std::ifstream siftfile(filepath.toStdString().c_str()); std::string dump; while(getline(siftfile,dump)) { ++n_keyp; } siftfile.close(); } // parse the .sift file stimg.keypoints.clear(); for (size_t cnt = 0; cnt < n_keyp; ++cnt) { if (is_parse_stream_past_end(s, filepath)) { l.msg(HERE(nfmt<2>("end of stream reached while parsing '%1': %2 keypoints stored") (filepath) (cnt))); return; } keypoint128 kp; float scale, rot; s >> kp.x >> kp.y >> scale >> rot; kp.scale = adapt_scale(scale); kp.rotation = adapt_rot(rot); for (size_t di = 0; di < 128; ++di) { unsigned int x; s >> x; kp.descriptor[di] = adapt_descr(x); } stimg.keypoints.append(kp); } // next feature }
scope_logger(log_domain const &domain, const char* str) : ticks_(0), output_(NULL), str_() { if (!debug.dont_log(domain)) do_log_entry(domain, str); }
node::node(logger &l, const std::string &config_path) : m_node(NULL), m_log(NULL) { struct dnet_config cfg; memset(&cfg, 0, sizeof(struct dnet_config)); cfg.sock_type = SOCK_STREAM; cfg.proto = IPPROTO_TCP; m_log = reinterpret_cast<logger *>(l.clone()); cfg.log = m_log->get_dnet_log(); std::list<addr_tuple> remotes; std::vector<int> groups; parse_config(config_path, cfg, remotes, groups, cfg.log->log_level); m_node = dnet_node_create(&cfg); if (!m_node) { delete m_log; throw std::bad_alloc(); } add_groups(groups); for (std::list<addr_tuple>::iterator it = remotes.begin(); it != remotes.end(); ++it) { try { add_remote(it->host.c_str(), it->port, it->family); } catch (...) { continue; } } }
int main() { // tell the logger to output all messages dlog.set_level(LALL); // Create an instance of our multi-threaded object. my_object t; dlib::sleep(3000); // Tell the multi-threaded object to pause its threads. This causes the // threads to block on their next calls to should_stop(). t.pause(); dlog << LINFO << "paused threads"; dlib::sleep(3000); dlog << LINFO << "starting threads back up from paused state"; // Tell the threads to unpause themselves. This causes should_stop() to unblock // and to let the threads continue. t.start(); dlib::sleep(3000); // Let the program end. When t is destructed it will gracefully terminate your // threads because we have set the destructor up to do so. }
int main() { // Every logger has a logging level (given by dlog.level()). Each log message is tagged with a // level and only levels equal to or higher than dlog.level() will be printed. By default all // loggers start with level() == LERROR. In this case I'm going to set the lowest level LALL // which means that dlog will print all logging messages it gets. dlog.set_level(LALL); // print our first message. It will go to cout because that is the default. dlog << LINFO << "This is an informational message."; // now print a debug message. int variable = 8; dlog << LDEBUG << "The integer variable is set to " << variable; // the logger can be used pretty much like any ostream object. But you have to give a logging // level first. But after that you can chain << operators like normal. if (variable > 4) dlog << LWARN << "The variable is bigger than 4! Its value is " << variable; dlog << LINFO << "we are going to sleep for half a second."; // sleep for half a second dlib::sleep(500); dlog << LINFO << "we just woke up"; dlog << LINFO << "program ending"; }
scope_logger(log_domain const &domain, const std::string& str) : ticks_(0), output_(0), str_() { if (!debug.dont_log(domain)) do_log_entry(domain, str); }
void runner::run(const test &t, logger &lgr) { try { lgr.record("pre_test", data("name", t.name)("line", t.line)("file", t.file)("time", t.time)("date", t.date)); t.function(lgr); lgr.record("post_test", data("result", "ok")); } catch (const data &dat) { lgr.record("post_test", dat); } catch (...) { lgr.record("post_test", data("result", "aborted")("reason", "an uncaught exception ended the test")); } }
static option<float> extract_focal_length_from_image(logger& l, const QString& path, float ccd_width) { //return some((3310.4 + 3325.5) / 2.); // dino ring return some(810.); // stereo experiments (ueye 640x512) float r; const auto&& c = extract_focal_length(path.toStdString().c_str(), &r, ccd_width); switch (c) { case FOCAL_LENGTH_OK: l.msg(nfmt<3>("EXIF chunk specifies focal length = %2 / CCD width = %3 for image file '%1'") (path) (r) (ccd_width)); return some(r); case FOCAL_LENGTH_INVALID_EXIF: l.critical(nfmt<1>("invalid EXIF chunk in image file '%1'") (path)); return none; case FOCAL_LENGTH_NO_CCD_DATA: l.critical(nfmt<1>("cannot find CCD data in image '%1'") (path)); return none; default: l.unexpected_error(HERE(nfmt<1>("unknown return code %1") (c))); return none; } }
void AgentConfiguration::configureLogger() { // Load logger configuration set_all_logging_levels(LINFO); set_all_logging_headers((dlib::logger::print_header_type) print_ts_logger_header); configure_loggers_from_file(mConfigFile.c_str()); if (mIsDebug) { set_all_logging_output_streams(cout); set_all_logging_levels(LDEBUG); } else if (mIsService && sLogger.output_streambuf() == cout.rdbuf()) { ostream *file = new std::ofstream("agent.log"); set_all_logging_output_streams(*file); } }
void stereoview::parse_keyfile(logger& l, progress_tracker&& prog, const image_id_type& id, const QString& filepath, const std::function<float(float)>& adapt_scale, const std::function<float(float)>& adapt_rot, const std::function<float(float)>& adapt_descr) { QString&& ins = read_file_for_parsing(filepath); QTextStream s(&ins); unsigned int expected_keypoints, descr_dim; s >> expected_keypoints >> descr_dim; check_parse_stream_not_past_end(s, filepath); if (descr_dim != keypoint128::descriptor_dim) throw localized_runtime_error(HERE(nfmt<2>("descriptor dimension in keyfile '%1' is %2 while 128 was expected") (filepath) (descr_dim))); l.msg(nfmt<3>("parsing keyfile '%1': %2 keypoints with %3-dimesional descriptor...") (filepath) (expected_keypoints) (descr_dim)); { auto sl = access_stored_image(id).atomic(); auto& stimg = *sl; stimg.keypoints.clear(); auto stepper = prog.section(expected_keypoints); for (size_t i = 0; i < expected_keypoints; ++i) { keypoint128 kp; float scale, rot; s >> kp.y >> kp.x >> scale >> rot; kp.scale = adapt_scale(scale); kp.rotation = adapt_rot(rot); for (size_t di = 0; di < descr_dim; ++di) { float x; s >> x; kp.descriptor[di] = adapt_descr(x); } check_parse_stream_not_past_end(s, filepath); stimg.keypoints.append(kp); ++stepper; } } }
node::node(logger &l, struct dnet_config &cfg) : m_node(NULL), m_log(NULL) { cfg.sock_type = SOCK_STREAM; cfg.proto = IPPROTO_TCP; m_log = reinterpret_cast<logger *>(l.clone()); cfg.log = m_log->get_dnet_log(); snprintf(cfg.addr, sizeof(cfg.addr), "0.0.0.0"); snprintf(cfg.port, sizeof(cfg.port), "0"); m_node = dnet_node_create(&cfg); if (!m_node) { delete m_log; throw std::bad_alloc(); } }
void stereoview::generate_keyfiles(logger& l, progress_tracker&& prog, const QVector<image_id_type>& imgids, const QDir& outdir, const QString& listfilepath, const std::function<QString(float)>& pretty_descr) const { QFile listf(listfilepath); if (!listf.open(QFile::WriteOnly | QIODevice::Text | QFile::Truncate)) throw localized_runtime_error(HERE(nfmt<1>("cannot open keyfile list file for writing: %1") (QFileInfo(listf).absoluteFilePath()))); QTextStream ls(&listf); auto imgstepper = prog.section(imgids.size()); foreach (const auto& id, imgids) { auto sl = access_stored_image(id).atomic(); const auto& kps = sl->keypoints; if (kps.isEmpty()) throw localized_invalid_argument(HERE(nfmt<1>("keypoints of image ID:%1 must be detected for tracking to make effect")(id))); const QString keyfilename = nfmt<1>("%1.key") (id); QFile f(outdir.absoluteFilePath(keyfilename)); if(!f.open(QFile::WriteOnly | QIODevice::Text | QFile::Truncate)) throw localized_runtime_error(HERE(nfmt<1>("cannot open keyfile for writing: %1") (QFileInfo(f).absoluteFilePath()))); l.msg(nfmt<2>("generating keyfile '%1' (%2 keypoints)...") (f.fileName()) (kps.size())); QTextStream s(&f); s << kps.size() << " " << keypoint128::descriptor_dim << uendl; auto kpstepper = imgstepper.sub().section(kps.size()); foreach (const auto& kp, kps) { s << kp.y << " " << kp.x << " " << kp.scale << " " << kp.rotation; for (size_t i = 0; i < keypoint128::descriptor_dim; ++i) { // follow indentation if (i % 20 == 0) s << uendl; s << " " << pretty_descr(kp.descriptor[i]); } s << uendl; ++kpstepper; }
namespace lg { /** * Helper class to redirect the output of the logger in a certain scope. * * The main usage of the redirection is for the unit tests to validate the * ourput on the logger with the expected output. */ class tredirect_output_setter { public: /** * Constructor. * * @param stream The stream to direct the output to. */ explicit tredirect_output_setter(std::ostream& stream); ~tredirect_output_setter(); private: /** * The previously set redirection. * * This value is stored here to be restored in this destructor. */ std::ostream* old_stream_; }; class logger; typedef std::pair<const std::string, int> logd; class log_domain { logd *domain_; public: log_domain(char const *name); friend class logger; }; bool set_log_domain_severity(std::string const &name, int severity); std::string list_logdomains(const std::string& filter); class logger { char const *name_; int severity_; public: logger(char const *name, int severity): name_(name), severity_(severity) {} std::ostream &operator()(log_domain const &domain, bool show_names = true, bool do_indent = false) const; bool dont_log(log_domain const &domain) const { return severity_ > domain.domain_->second; } }; void timestamps(bool); std::string get_timestamp(const time_t& t, const std::string& format="%Y%m%d %H:%M:%S "); extern logger err, warn, info, debug; extern log_domain general; class scope_logger { int ticks_; std::ostream *output_; std::string str_; public: scope_logger(log_domain const &domain, const char* str) : ticks_(0), output_(0), str_() { if (!debug.dont_log(domain)) do_log_entry(domain, str); } scope_logger(log_domain const &domain, const std::string& str) : ticks_(0), output_(0), str_() { if (!debug.dont_log(domain)) do_log_entry(domain, str); } ~scope_logger() { if (output_) do_log_exit(); } void do_indent() const; private: void do_log_entry(log_domain const &domain, const std::string& str); void do_log_exit(); }; /** * Use this logger to send errors due to deprecated WML. * The preferred format is: * xxx is deprecated, support will be removed in version X. or * xxx is deprecated, support has been removed in version X. * * After every wml-event the errors are shown to the user, * so they can inform the campaign maintainer. */ extern std::stringstream wml_error; } // namespace lg
namespace lg { class logger; typedef std::pair<const std::string, int> logd; class log_domain { logd *domain_; public: log_domain(char const *name); friend class logger; }; bool set_log_domain_severity(std::string const &name, int severity); std::string list_logdomains(); class logger { char const *name_; int severity_; public: logger(char const *name, int severity): name_(name), severity_(severity) {} std::ostream &operator()(log_domain const &domain, bool show_names = true, bool do_indent = false) const; bool dont_log(log_domain const &domain) const { return severity_ > domain.domain_->second; } }; void timestamps(bool); std::string get_timestamp(const time_t& t, const std::string& format="%Y%m%d %H:%M:%S "); extern logger err, warn, info, debug; extern log_domain general; class scope_logger { int ticks_; std::ostream *output_; std::string str_; public: scope_logger(log_domain const &domain, const char* str) : ticks_(0), output_(0), str_() { if (!debug.dont_log(domain)) do_log_entry(domain, str); } scope_logger(log_domain const &domain, const std::string& str) : ticks_(0), output_(0), str_() { if (!debug.dont_log(domain)) do_log_entry(domain, str); } ~scope_logger() { if (output_) do_log_exit(); } void do_indent() const; private: void do_log_entry(log_domain const &domain, const std::string& str); void do_log_exit(); }; /** * Use this logger to send errors due to deprecated WML. * The preferred format is: * xxx is deprecated, support will be removed in version X. or * xxx is deprecated, support has been removed in version X. * * After every wml-event the errors are shown to the user, * so they can inform the campaign maintainer. */ extern std::stringstream wml_error; } // namespace lg
int main() { // tell the logger to print out everything dlog.set_level(LALL); dlog << LINFO << "schedule a few tasks"; test mytask; // Schedule the thread pool to call mytask.task(). Note that all forms of add_task() // pass in the task object by reference. This means you must make sure, in this case, // that mytask isn't destructed until after the task has finished executing. tp.add_task(mytask, &test::task); // You can also pass task objects to a thread pool by value. So in this case we don't // have to worry about keeping our own instance of the task. Here we construct a temporary // add_value object and pass it right in and everything works like it should. future<int> num = 3; tp.add_task_by_value(add_value(7), num); // adds 7 to num int result = num.get(); dlog << LINFO << "result = " << result; // prints result = 10 // uncomment this line if your compiler supports the new C++0x lambda functions //#define COMPILER_SUPPORTS_CPP0X_LAMBDA_FUNCTIONS #ifdef COMPILER_SUPPORTS_CPP0X_LAMBDA_FUNCTIONS // In the above examples we had to explicitly create task objects which is // inconvenient. If you have a compiler which supports C++0x lambda functions // then you can use the following simpler method. // make a task which will just log a message tp.add_task_by_value([](){ dlog << LINFO << "A message from a lambda function running in another thread."; }); // Here we make 10 different tasks, each assigns a different value into // the elements of the vector vect. std::vector<int> vect(10); for (unsigned long i = 0; i < vect.size(); ++i) { // Make a lambda function which takes vect by reference and i by value. So what // will happen is each assignment statement will run in a thread in the thread_pool. tp.add_task_by_value([&vect,i](){ vect[i] = i; }); } // Wait for all tasks which were requested by the main thread to complete. tp.wait_for_all_tasks(); for (unsigned long i = 0; i < vect.size(); ++i) { dlog << LINFO << "vect["<<i<<"]: " << vect[i]; } #endif /* A possible run of this program might produce the following output (the first column is the time the log message occurred and the value in [] is the thread id for the thread that generated the log message): 1 INFO [0] main: schedule a few tasks 1 INFO [1] main: task start 1 INFO [0] main: result = 10 201 INFO [2] main: subtask end 201 INFO [1] main: var = 2 201 INFO [2] main: A message from a lambda function running in another thread. 301 INFO [3] main: subtask2 end 301 INFO [1] main: task end 301 INFO [0] main: vect[0]: 0 301 INFO [0] main: vect[1]: 1 301 INFO [0] main: vect[2]: 2 301 INFO [0] main: vect[3]: 3 301 INFO [0] main: vect[4]: 4 301 INFO [0] main: vect[5]: 5 301 INFO [0] main: vect[6]: 6 301 INFO [0] main: vect[7]: 7 301 INFO [0] main: vect[8]: 8 301 INFO [0] main: vect[9]: 9 */ }
void logger_log(logger &log, const char *msg, int level) { log.log(level, msg); }
bool set_log_domain_severity(const std::string& name, const logger &lg) { return set_log_domain_severity(name, lg.get_severity()); }
void set_strict_severity(const logger &lg) { set_strict_severity(lg.get_severity()); }
void print_line(const logger & log) { cout << "Session: " << log.last_line() << endl; }