123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- //local
- #include "logger_impl.h"
- //stl
- #include <fstream>
- #include <random>
- #include <fmt/format.h>
- //boost
- #include <boost/algorithm/string.hpp>
- namespace robotics::v3 {
- logger_impl::~logger_impl() {
- thread_pool_.join();
- }
- void logger_impl::write(int color, std::string const& type, std::string const& time, std::string const& file, std::string const& func, int line, std::thread::id thread_id, std::string const& text) {
- if (!thread_pool_.executor().running_in_this_thread()) {
- asio::post(thread_pool_, std::bind(&logger_impl::write, this, color, type, time, file, func, line, thread_id, text));
- return;
- }
- static time_t g_remove_ergodic = 0;
- union __thread_id__ {
- __thread_id__(std::thread::id d) :
- id(d) {
- }
- std::thread::id id;
- unsigned int iid;
- };
- __thread_id__ th_id = thread_id;
- if (save_.find(type) == save_.end()) {
- std::cout << fmt::format("\033[{}m{} [{}] [{}#{}#{}#{}] ==>>\033[0m{}", color, time, type, file, func, line, th_id.iid, text) << std::endl;
- }
- else {
- if (!std::filesystem::is_directory("log")) {
- std::filesystem::create_directory("log");
- }
- std::string log_text = fmt::format("{} [{}] [{}#{}#{}#{}] ==>>{}", time, type, file, func, line, th_id.iid, text);
- std::string log_filename = fmt::format("log/{}_{}.log", type, datetime::current_datetime().to_string("yyyy-MM-dd"));
- std::fstream fs(log_filename, std::ios::out | std::ios::app);
- if (fs.is_open()) {
- fs << log_text;
- fs << std::endl;
- fs.close();
- backup(log_filename);
- time_t current_time = datetime::current_time_stamp();
- if (g_remove_ergodic == 0 || g_remove_ergodic + 43200000 < current_time) {
- g_remove_ergodic = current_time;
- remove();
- }
- }
- }
- }
- logger_impl& logger_impl::instance() {
- static logger_impl g_instance;
- return g_instance;
- }
- void logger_impl::install(std::string const& filename) {
- instance().max_time_ = config::read<int>("LOGGER", "TIME", 30);
- instance().max_size_ = config::read<int>("LOGGER", "SIZE", 10);
- auto type = config::read<std::string>("LOGGER", "TYPE", "info,debug,warn,error");
- std::vector<std::string> types;
- boost::split(types, type, boost::is_any_of(","));
- for (auto& it : types) {
- if (it.empty())
- continue;
- instance().save_.insert(it);
- }
- }
- logger_impl::logger_impl() :
- thread_pool_(1) {
- }
- void logger_impl::backup(std::string const& filename) {
- if (!std::filesystem::exists(filename) || std::filesystem::file_size(filename) <= max_size_ * 1024 * 1024)
- return;
- for (int i = 0; i < 10; i++) {
- std::string backup_filename = filename;
- std::random_device r;
- std::default_random_engine e1(r());
- std::uniform_int_distribution<int> uniform_dist(10000, 99999);
- std::string mean = "__" + std::to_string(uniform_dist(e1));
- backup_filename.insert(backup_filename.begin() + backup_filename.size() - 4, mean.begin(), mean.end());
- if (std::filesystem::exists(backup_filename))
- continue;
- std::filesystem::copy(filename, backup_filename);
- std::fstream fout(filename, std::ios::out | std::ios::trunc);
- fout.close();
- break;
- }
- }
- void logger_impl::remove() {
- datetime remove_time = datetime::current_datetime();
- remove_time.add_day(-this->max_time_);
- const std::filesystem::path path_to_directory = "log";
- try {
- if (std::filesystem::exists(path_to_directory) && std::filesystem::is_directory(path_to_directory)) {
- for (const auto& entry : std::filesystem::recursive_directory_iterator(path_to_directory)) {
- const auto& path = entry.path();
- if (std::filesystem::is_regular_file(path)) {
- auto create_time = std::filesystem::last_write_time(path);
- time_t elapse = std::chrono::duration_cast<std::chrono::milliseconds>(std::filesystem::file_time_type::clock::now().time_since_epoch() - std::chrono::system_clock::now().time_since_epoch()).count();
- std::chrono::milliseconds secs = std::chrono::duration_cast<std::chrono::milliseconds>(create_time.time_since_epoch());
- v3::datetime time = (secs.count() - elapse);
- if (remove_time > time) {
- std::filesystem::remove(path);
- }
- }
- }
- }
- }
- catch (...) {}
- }
- logger_stream::logger_stream(
- int color,
- std::string const& type,
- std::string const& time,
- std::string const& file,
- std::string const& func,
- int line,
- std::thread::id thread_id) :
- color_(color),
- type_(type),
- time_(time),
- file_(file),
- func_(func),
- line_(line),
- thread_id_(thread_id) {
- }
- logger_stream::~logger_stream() {
- std::string text = stream.str();
- if (!text.empty())
- logger_impl::instance().write(color_, type_, time_, file_, func_, line_, thread_id_, text);
- }
- }
|