#ifndef LOGGER_HPP_INCLUDED #define LOGGER_HPP_INCLUDED #include #include #include #include #include #include extern int verbose; #define LogDebug(s, ...) \ if ( verbose >= 3 ) printf(s, ##__VA_ARGS__); #define LogMoreInfo(s, ...) \ if ( verbose >= 2 ) printf(s, ##__VA_ARGS__); #define LogInfo(s, ...) \ if ( verbose >= 1 ) printf(s, ##__VA_ARGS__); #define LogError(s, ...) \ if ( verbose >= 0 ) { printf("%s, %s(), %d: ", __FILE__, __func__, __LINE__); printf(s, ##__VA_ARGS__); } /* Imported from Astrant: Questions/Suggestions mail nick@astrant.net */ struct Logger { Logger(std::ostream& logging_stream_, std::string prefix_ = std::string("")) : logging_stream(&logging_stream_) , prefix(prefix_) {} void log(std::string what){ *logging_stream << get_prefix() << "(" << what << ") took place at (" << boost::posix_time::microsec_clock::local_time() << std::endl; } void start(std::string what){ Event e; e.start = boost::posix_time::microsec_clock::local_time(); e.name = what; EventMap::iterator it = event_map.find(what); if(it != event_map.end()){ *logging_stream << get_prefix() << "WARNING: Overwriting event(" << e.name << "), did you forget to call stop()?"; } else { event_name_stack.push(what); } event_map.insert(it, std::make_pair(what, e)); } void stop() { assert(!event_name_stack.empty()); stop(event_name_stack.top()); } private: void stop(std::string what){ EventMap::iterator it = event_map.find(what); if(it == event_map.end()){ *logging_stream << get_prefix() << "WARNING: No such, or already stopped, event(" << what << "), did you forget to call start()?"; } else { it->second.end = boost::posix_time::microsec_clock::local_time(); log_event(it->second); event_map.erase(it); } event_name_stack.pop(); } struct Event { boost::posix_time::ptime start; boost::posix_time::ptime end; std::string name; }; // A map containing strings -> Event, used by start() and stop() typedef std::map EventMap; EventMap event_map; // A stack used by 0-parameter stop() to stop the last start()ed event. std::stack event_name_stack; std::ostream* logging_stream; std::string prefix; void log_event(Event const& e){ *logging_stream << get_prefix() << "Event(" << e.name << ") started at (" << e.start << ") ended at (" << e.end << ") duration (" << e.end - e.start << " ms) " << std::endl; } std::string get_prefix() const { if(prefix == std::string("")){ return prefix; } else { return prefix + ": "; } } }; /* My progressbar class (as seen on github) */ struct Progressbar { Progressbar(std::ostream & out, std::string prefix = "", std::string begin = "", std::string end = "") : out(out) , begin(begin) , prefix(prefix) , end(end) { if (begin != "") { out << begin << std::endl; } show(0, 1, ' '); } ~Progressbar(){ show(1, 1, '='); if (end != "") { out << "\n" << end << std::endl; } else { out << std::endl; } } template void show(T const & progress, T const & max, char delim = '>'){ out << "\r"; size_t width = 80; // default terminal size :D width -= prefix.size(); width -= 3; // [, > and ] if (prefix != "") { width -= 1; out << prefix << ' '; } double ratio = (double) progress / (double) max; size_t length = width * ratio; std::string fill(length, '='); std::string empty(width - length, ' '); out << '[' << fill << delim << empty << ']' << std::flush; } private: std::ostream & out; std::string begin; std::string prefix; std::string end; }; #endif // LOGGER_HPP_INCLUDED