Advertisement
den4ik2003

Untitled

Feb 27th, 2024
967
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.65 KB | None | 0 0
  1. #include <thread>
  2. #include <atomic>
  3.  
  4. #include <boost/log/core.hpp>
  5. #include <boost/log/sources/logger.hpp>
  6. #include <boost/log/attributes/attribute.hpp>
  7. #include <boost/log/attributes/attribute_cast.hpp>
  8. #include <boost/log/attributes/attribute_value.hpp>
  9. #include <boost/log/sinks/sync_frontend.hpp>
  10. #include <boost/log/sinks/text_ostream_backend.hpp>
  11. #include <boost/log/core.hpp>
  12. #include <boost/log/trivial.hpp>
  13. #include <boost/log/expressions.hpp>
  14. #include <boost/log/sinks/text_file_backend.hpp>
  15. #include <boost/log/utility/setup/file.hpp>
  16. #include <boost/log/utility/setup/common_attributes.hpp>
  17. #include <boost/log/sources/severity_logger.hpp>
  18. #include <boost/log/sources/record_ostream.hpp>
  19. #include <boost/stacktrace.hpp>
  20.  
  21. namespace logging = boost::log;
  22. namespace sinks = boost::log::sinks;
  23. namespace src = boost::log::sources;
  24. namespace expr = boost::log::expressions;
  25. namespace attrs = boost::log::attributes;
  26. namespace sinks = boost::log::sinks;
  27. namespace keywords = boost::log::keywords;
  28.  
  29. class Logger {
  30. private:
  31.     src::logger_mt logger;
  32.  
  33. public:
  34.     enum struct severity_level {
  35.         DEBUG,
  36.         INFO,
  37.         WARNING,
  38.         ERROR,
  39.         CRITICAL
  40.     };
  41.  
  42.     static std::string get_date(size_t timestamp);
  43.  
  44.     /*
  45.         usually: filename = symbol name (without .log)
  46.         need_timestamp: if true -> log file name will be without timestamp. Only filename.log
  47.     */
  48.     Logger(std::string filename, bool need_timestamp = true, std::string logdir_path = "logs/") {
  49.         std::string log_name = logdir_path + filename;
  50.         if (need_timestamp) {
  51.             log_name += "-" + get_date(std::chrono::duration_cast<std::chrono::milliseconds>(
  52.                 std::chrono::system_clock::now().time_since_epoch()).count()
  53.             );
  54.         }
  55.         log_name += ".log";
  56.        
  57.         logging::add_common_attributes();
  58.        
  59.         logging::add_file_log(
  60.             keywords::file_name = log_name,
  61.             keywords::rotation_size = 100 * 1024 * 1024, // TODO
  62.             keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
  63.             keywords::format = "[%TimeStamp%]: %Message%"
  64.         );
  65.     }
  66.  
  67.     void WriteLog(Logger::severity_level severity_level, std::string message) {
  68.         if (logging::record rec = logger.open_record()) {
  69.             logging::record_ostream strm(rec);
  70.             strm << severity_level << message << '\n';
  71.             if (severity_level == Logger::severity_level::ERROR || severity_level == Logger::severity_level::CRITICAL) {
  72.                 strm << boost::stacktrace::stacktrace() << '\n';
  73.             }
  74.             strm.flush();
  75.             logger.push_record(boost::move(rec));
  76.         }
  77.     }
  78. };
  79.  
  80. std::ostream& operator<<(std::ostream& os, Logger::severity_level level) {
  81.     os << " <";
  82.     switch(level) {
  83.     case Logger::severity_level::DEBUG:
  84.         os << "DEBUG";
  85.         break;
  86.     case Logger::severity_level::INFO:
  87.         os << "INFO";
  88.         break;
  89.     case Logger::severity_level::WARNING:
  90.         os << "WARNING";
  91.         break;
  92.     case Logger::severity_level::ERROR:
  93.         os << "ERROR";
  94.         break;
  95.     case Logger::severity_level::CRITICAL:
  96.         os << "CRITICAL";
  97.         break;
  98.     default:
  99.         os << "UNKNOWN";
  100.     }
  101.     os << "> ";
  102.     return os;
  103. }
  104.  
  105. std::string Logger::get_date(size_t timestamp) {
  106.     size_t y, m, d, hh, mm, ss;
  107.     size_t cs = 0, lv = 0;
  108.     for (y = 1970; cs <= timestamp; ++y) {
  109.          size_t ydc = 365 + (y % 400 == 0 || (y % 100 && y % 4 == 0));
  110.          lv = (ydc > 365);
  111.          ydc *= 24 * 60 * 60 * 1000;
  112.          if (cs + ydc > timestamp) {
  113.              break;
  114.          }
  115.          cs += ydc;
  116.     }
  117.     timestamp -= cs;
  118.     cs = 0;
  119.     for (m = 1; cs <= timestamp; ++m) {
  120.         size_t add = 0;
  121.         if ((m % 2 && m < 8) || (m % 2 == 0 && m >= 8)) {
  122.             add = 31;
  123.         } else if (m == 2) {
  124.             add = 28 + lv;
  125.         } else {
  126.             add = 30;
  127.         }
  128.         add *= 24 * 60 * 60 * 1000;
  129.         if (cs + add > timestamp) {
  130.             break;
  131.         }
  132.         cs += add;
  133.     }
  134.     timestamp -= cs;
  135.     d = timestamp / (24 * 60 * 60 * 1000) + 1;
  136.     timestamp %= (24 * 60 * 60 * 1000);
  137.     hh = timestamp / (60 * 60 * 1000);
  138.     timestamp %= (60 * 60 * 1000);
  139.     mm = timestamp / (60 * 1000);
  140.     timestamp %= (60 * 1000);
  141.     ss = timestamp / 1000;
  142.     std::string ys = std::to_string(y);
  143.     std::string ms = std::to_string(m);
  144.     if (ms.size() == 1) {
  145.         ms = "0" + ms;
  146.     }
  147.     std::string ds = std::to_string(d);
  148.     if (ds.size() == 1) {
  149.         ds = "0" + ds;
  150.     }
  151.     std::string hhs = std::to_string(hh);
  152.     if (hhs.size() == 1) {
  153.         hhs = "0" + hhs;
  154.     }
  155.     std::string mms = std::to_string(mm);
  156.     if (mms.size() == 1) {
  157.         mms = "0" + mms;
  158.     }
  159.     std::string sss = std::to_string(ss);
  160.     if (sss.size() == 1) {
  161.         sss = "0" + sss;
  162.     }
  163.     return ys + "-" + ms + "-" + ds + "-" + hhs + "-" + mms + "-" + sss;
  164. }
  165.  
  166. /*
  167. int main() {
  168.     Logger lg("TEST", false);
  169.     std::atomic<int> threads_counter = 0;
  170.     for (int i = 0; i < 30000; ++i) {
  171.  
  172.         std::thread{[=, &lg, &threads_counter](){
  173.             auto sev_lvl = Logger::severity_level::INFO;
  174.             if (i % 500 == 0) {
  175.                 sev_lvl = Logger::severity_level::ERROR;
  176.             }
  177.             lg.WriteLog(sev_lvl, "This message was created to test correct concurrent execution of logger");
  178.             threads_counter.fetch_add(1);
  179.         }}.detach();
  180.     }
  181.  
  182.     while(threads_counter.load() != 30000) {
  183.         std::this_thread::sleep_for(std::chrono::milliseconds(100));
  184.     }
  185. }
  186. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement