Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <thread>
- #include <atomic>
- #include <boost/log/core.hpp>
- #include <boost/log/sources/logger.hpp>
- #include <boost/log/attributes/attribute.hpp>
- #include <boost/log/attributes/attribute_cast.hpp>
- #include <boost/log/attributes/attribute_value.hpp>
- #include <boost/log/sinks/sync_frontend.hpp>
- #include <boost/log/sinks/text_ostream_backend.hpp>
- #include <boost/log/core.hpp>
- #include <boost/log/trivial.hpp>
- #include <boost/log/expressions.hpp>
- #include <boost/log/sinks/text_file_backend.hpp>
- #include <boost/log/utility/setup/file.hpp>
- #include <boost/log/utility/setup/common_attributes.hpp>
- #include <boost/log/sources/severity_logger.hpp>
- #include <boost/log/sources/record_ostream.hpp>
- #include <boost/stacktrace.hpp>
- namespace logging = boost::log;
- namespace sinks = boost::log::sinks;
- namespace src = boost::log::sources;
- namespace expr = boost::log::expressions;
- namespace attrs = boost::log::attributes;
- namespace sinks = boost::log::sinks;
- namespace keywords = boost::log::keywords;
- class Logger {
- private:
- src::logger_mt logger;
- public:
- enum struct severity_level {
- DEBUG,
- INFO,
- WARNING,
- ERROR,
- CRITICAL
- };
- static std::string get_date(size_t timestamp);
- /*
- usually: filename = symbol name (without .log)
- need_timestamp: if true -> log file name will be without timestamp. Only filename.log
- */
- Logger(std::string filename, bool need_timestamp = true, std::string logdir_path = "logs/") {
- std::string log_name = logdir_path + filename;
- if (need_timestamp) {
- log_name += "-" + get_date(std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::system_clock::now().time_since_epoch()).count()
- );
- }
- log_name += ".log";
- logging::add_common_attributes();
- logging::add_file_log(
- keywords::file_name = log_name,
- keywords::rotation_size = 100 * 1024 * 1024, // TODO
- keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
- keywords::format = "[%TimeStamp%]: %Message%"
- );
- }
- void WriteLog(Logger::severity_level severity_level, std::string message) {
- if (logging::record rec = logger.open_record()) {
- logging::record_ostream strm(rec);
- strm << severity_level << message << '\n';
- if (severity_level == Logger::severity_level::ERROR || severity_level == Logger::severity_level::CRITICAL) {
- strm << boost::stacktrace::stacktrace() << '\n';
- }
- strm.flush();
- logger.push_record(boost::move(rec));
- }
- }
- };
- std::ostream& operator<<(std::ostream& os, Logger::severity_level level) {
- os << " <";
- switch(level) {
- case Logger::severity_level::DEBUG:
- os << "DEBUG";
- break;
- case Logger::severity_level::INFO:
- os << "INFO";
- break;
- case Logger::severity_level::WARNING:
- os << "WARNING";
- break;
- case Logger::severity_level::ERROR:
- os << "ERROR";
- break;
- case Logger::severity_level::CRITICAL:
- os << "CRITICAL";
- break;
- default:
- os << "UNKNOWN";
- }
- os << "> ";
- return os;
- }
- std::string Logger::get_date(size_t timestamp) {
- size_t y, m, d, hh, mm, ss;
- size_t cs = 0, lv = 0;
- for (y = 1970; cs <= timestamp; ++y) {
- size_t ydc = 365 + (y % 400 == 0 || (y % 100 && y % 4 == 0));
- lv = (ydc > 365);
- ydc *= 24 * 60 * 60 * 1000;
- if (cs + ydc > timestamp) {
- break;
- }
- cs += ydc;
- }
- timestamp -= cs;
- cs = 0;
- for (m = 1; cs <= timestamp; ++m) {
- size_t add = 0;
- if ((m % 2 && m < 8) || (m % 2 == 0 && m >= 8)) {
- add = 31;
- } else if (m == 2) {
- add = 28 + lv;
- } else {
- add = 30;
- }
- add *= 24 * 60 * 60 * 1000;
- if (cs + add > timestamp) {
- break;
- }
- cs += add;
- }
- timestamp -= cs;
- d = timestamp / (24 * 60 * 60 * 1000) + 1;
- timestamp %= (24 * 60 * 60 * 1000);
- hh = timestamp / (60 * 60 * 1000);
- timestamp %= (60 * 60 * 1000);
- mm = timestamp / (60 * 1000);
- timestamp %= (60 * 1000);
- ss = timestamp / 1000;
- std::string ys = std::to_string(y);
- std::string ms = std::to_string(m);
- if (ms.size() == 1) {
- ms = "0" + ms;
- }
- std::string ds = std::to_string(d);
- if (ds.size() == 1) {
- ds = "0" + ds;
- }
- std::string hhs = std::to_string(hh);
- if (hhs.size() == 1) {
- hhs = "0" + hhs;
- }
- std::string mms = std::to_string(mm);
- if (mms.size() == 1) {
- mms = "0" + mms;
- }
- std::string sss = std::to_string(ss);
- if (sss.size() == 1) {
- sss = "0" + sss;
- }
- return ys + "-" + ms + "-" + ds + "-" + hhs + "-" + mms + "-" + sss;
- }
- /*
- int main() {
- Logger lg("TEST", false);
- std::atomic<int> threads_counter = 0;
- for (int i = 0; i < 30000; ++i) {
- std::thread{[=, &lg, &threads_counter](){
- auto sev_lvl = Logger::severity_level::INFO;
- if (i % 500 == 0) {
- sev_lvl = Logger::severity_level::ERROR;
- }
- lg.WriteLog(sev_lvl, "This message was created to test correct concurrent execution of logger");
- threads_counter.fetch_add(1);
- }}.detach();
- }
- while(threads_counter.load() != 30000) {
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
- }
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement