// // Logging.hpp // AwesomeAttractorND // // Created by Joshua Moerman on 11/2/11. // Copyright 2011 Vadovas. All rights reserved. // #ifndef AwesomeAttractorND_Logging_hpp #define AwesomeAttractorND_Logging_hpp #pragma once #include #include #include #include #include #include #define INFORMATION __FILE__ << ":" << __LINE__ << "(" << __FUNCTION__ << ")" #define COUT std::cout << INFORMATION << "\n" #define CERR std::cerr << INFORMATION << "\n" #define VCOUT if(verbose) COUT #define VCERR if(verbose) CERR /* Usage: When timing anything: Before starting the task: start("with a string"); When the task is done: stop(); The shorthand for that is { start("foo"); foo(); stop(); } Note that a call to stop without parameters, stops the last started event. This works like a stack: { start("Task of several small tasks"); start("Small task 1"); small_task_1(); stop(); start("Small task 2"); small_task_2(); stop(); stop(); // Stops "Task of several small tasks" } The indenting is, of course, only to help you understand what's going on. 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 + ": "; } } }; #endif