#include "glogger.hpp" #include #include #include #include // Создаем потоки для файлов, которые будут жить в течение всей программы std::ofstream general_log_file("general.log"); std::ofstream critical_errors_file("critical.log"); std::ofstream network_log_file("network.log"); void worker_thread_func(int thread_id) { LOG_INFO("General", "Worker thread %1% started.", thread_id); std::this_thread::sleep_for(std::chrono::milliseconds(10)); LOG_DEBUG("Network", "heartbeat from thread %1%", thread_id); if (thread_id % 2 == 0) { LOG_ERROR("General", "Simulated failure in even thread %1%", thread_id); } LOG_INFO("General", "Worker thread %1% finished.", thread_id); } int main() { // --- 1. Настройка маршрутизации и форматов --- // Глобальное правило по умолчанию: все, что не подошло под другие правила, // идет в консоль в простом формате. DaemonLogger::setGlobalOutputStream(std::cout); DaemonLogger::setGlobalFormat("[{severity}] {cat}: {umsg}"); // Правило для категории "General": пишем в файл general.log с полным форматом. DaemonLogger::setCategoryOutputStream("General", general_log_file); DaemonLogger::setCategoryFormat("General", "{date} [{severity}] <{loc}> {umsg}"); // Правило для категории "Network": пишем в свой файл network.log. // Формат очень короткий, т.к. предполагается большой объем логов. DaemonLogger::setCategoryOutputStream("Network", network_log_file); DaemonLogger::setCategoryFormat("Network", "{date} -> {umsg}"); // Самое специфичное правило: ошибки из категории "General" дублируются // в отдельный файл critical.log с особым, кричащим форматом. DaemonLogger::setSeverityOutputStream("General", DaemonLogger::Severity::Error, critical_errors_file); DaemonLogger::setSeverityFormat("General", DaemonLogger::Severity::Error, "!!! CRITICAL [{cat}] {date} !!! {umsg} @ {loc}"); // --- 2. Тестирование одиночных логов --- LOG_INFO("Main", "Система логирования настроена. Запускаем тесты."); // Попадет в std::cout LOG_DEBUG("General", "Это отладочное сообщение для general.log"); // Попадет в general.log LOG_WARNING("General", "Это предупреждение для general.log"); // Попадет в general.log LOG_ERROR("General", "Критическая ошибка, которая пойдет в critical.log"); // Попадет в critical.log LOG_INFO("Network", "New connection from 192.168.1.100"); // Попадет в network.log LOG_INFO("Network", "Packet loss detected: 5%%"); // Попадет в network.log // --- 3. Тестирование изменения настроек на лету --- LOG_INFO("Main", "Меняем уровень логирования для 'Network' на Warning"); DaemonLogger::get("Network").setMinSeverity(DaemonLogger::Severity::Warning); LOG_INFO("Network", "Эта запись НЕ должна появиться в network.log"); LOG_WARNING("Network", "А эта запись-предупреждение ДОЛЖНА появиться."); // Возвращаем обратно для многопоточного теста DaemonLogger::get("Network").setMinSeverity(DaemonLogger::Severity::Debug); // --- 4. Тестирование многопоточной записи --- LOG_INFO("Main", "Запускаем 5 потоков для стресс-теста..."); std::vector threads; for (int i = 0; i < 5; ++i) { threads.emplace_back(worker_thread_func, i + 1); } for (auto& t : threads) { t.join(); } LOG_INFO("Main", "Все потоки завершили работу. Проверьте файлы general.log, critical.log и network.log"); return 0; }