#pragma once /////////////////////////////////////////////////////////////////////////////// // Logger.h - Template class logs messages using services of template policy // // // // Jim Fawcett, Solution second week Wednesday exercise // // Short Course, Summer 2016 // /////////////////////////////////////////////////////////////////////////////// /* * Note: * - Needed to use _CRT_SECURE_NO_WARNINGS; * in Project Properties > C/C++ > Preprocessor * due to use of localtime instead of localtime_s * which needs some rework to code in its vicinity * - sigh! */ #include #include #include #include #include #include #include #include ///////////////////////////////////////////////////////////////////////////// // Logger class logs messages using Write Policy class WP template class Logger { public: Logger(const std::string& userName) : name_(userName) {} void logTitle(const std::string& msg); // write title for batch of logs void log(const std::string& msg); // write log message WP& writer(); // provide access to writer private: // - needed to open and close file std::string name_; WP wp_; }; template WP& Logger::writer() { return wp_; } template void Logger::logTitle(const std::string& msg) { std::string logItem = "\n" + msg + "\n"; logItem += std::string(msg.size(), '-'); wp_.write(logItem); } std::string systemTime() { std::chrono::system_clock::time_point timestamp = std::chrono::system_clock::now(); std::time_t now_c = std::chrono::system_clock::to_time_t(timestamp); std::ostringstream out; out << std::put_time(std::localtime(&now_c), "%F %T"); return out.str(); } template void Logger::log(const std::string& msg) { std::string logItem = name_ + " " + systemTime() + "\n" + msg; wp_.write(logItem); } ///////////////////////////////////////////////////////////////////////////// // IWriter interface for Writer Policies struct IWriter { virtual void write(const std::string& msg) = 0; virtual ~IWriter() {} }; ///////////////////////////////////////////////////////////////////////////// // StdOutWriter class writes log messages to std::cout class StdOutWriter : public IWriter { public: virtual void write(const std::string& msg) { std::cout << "\n" << msg; } }; ///////////////////////////////////////////////////////////////////////////// // FileWriter class writes log messages to file class FileWriter : public IWriter { public: bool open(const std::string& filename) { out_.open(filename); if (!out_.good()) { std::cout << "\n\n can't open log file \"" << filename.c_str() << "\"\n\n"; return false; } return true; } void close() { out_.close(); } virtual void write(const std::string& msg) { out_ << "\n" << msg; } private: std::ofstream out_; };