Reading List

The Selfish Gene
The Psychopath Test: A Journey Through the Madness Industry
Bad Science
The Feynman Lectures on Physics
The Theory of Everything: The Origin and Fate of the Universe


ifknot's favorite books »

Sunday, 9 March 2014

Simplification of logging services.

As Thoreau said: "Simplify, simplify, simplify..."

The trouble with writing something in an hour or two that works is that you then have find your subconscious mind is chewing it over all the time that you're working on something else.

So it is whilst working on message_queue I couldn't resist fiddling with the logging services:
  • the io namespace is gone
  • serializor_policy is gone
  • only the null_serializor remains renamed null_log
  • ready for asycn_log
  • logger now takes an output stream policy and is, consequently, more flexible
  • works directly with any ostream decendent
  • logger template overloads operator() 
  • logger doesn't need a stringstream any longer 
  • I've left the stamps alone, for now... 

So now the logger is easier to use and more flexible:
log::logger<std::ostream> clog(std::cout, { new log::line_number_stamp(),
new log::line_number_stamp(10),
new log::unix_time_stamp()});
std::ofstream file("test.log");
log::logger<std::ofstream> flog(file, { new log::line_number_stamp(),
new log::line_number_stamp(10),
new log::unix_time_stamp()});
log::null_log black_hole;
log::logger<log::null_log> nlog(black_hole);
for (int i = 0; i < 10; ++i) {
clog("hello ", "world ", 1,1,1);
flog("hello ", "file " "world ", 1,2,3);
nlog("hello ", "null " "world ", 1,2,3);
}
view raw test.cpp hosted with ❤ by GitHub

It is a smaller, more coherent and more pleasing piece of code:
namespace log {
template<typename T>
class logger {
using initializer_list = std::initializer_list<stamp_policy*>;
public:
logger(T& _stream): stream(_stream) {}
logger(T& _stream, initializer_list _stamps):
stream(_stream),
stamps(_stamps) {}
template<typename...Args>
void operator() (Args...args) {
for(auto stamp: stamps)
stream << stamp->str();
do_write(args...);
}
virtual ~logger() {
for (auto stamp: stamps)
delete(stamp);
}
private:
void do_write() {
stream << "\n";
}
template<typename First, typename...Next>
void do_write(First first, Next...next) {
stream << first;
do_write(next...);
}
initializer_list stamps;
T& stream;
};
}
view raw logger.cpp hosted with ❤ by GitHub

Subsequent log streams will be much more easily implemented as can be seen from null_log:
namespace log {
struct null_log {
template<typename T>
const null_log& operator << (const T& t) const {
return *this;
}
};
}
view raw null_log.cpp hosted with ❤ by GitHub
Ok, now where was I?

No comments:

Post a Comment