|
|
#include "glogger.hpp"
|
|
|
#include <thread>
|
|
|
#include <vector>
|
|
|
#include <fstream>
|
|
|
#include <chrono>
|
|
|
|
|
|
// Создаем потоки для файлов, которые будут жить в течение всей программы
|
|
|
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<std::thread> 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;
|
|
|
}
|