diff --git a/Bot.cpp b/Bot.cpp index 710cc11..1b454d5 100644 --- a/Bot.cpp +++ b/Bot.cpp @@ -1,5 +1,7 @@ #include "Bot.h" +#include "Logger.h" + #include #include @@ -28,9 +30,9 @@ void Bot::setupCommands() [](banana::expected result) { if (result) - fmt::print("commands set up successfully\n"); + LOG(bot, "commands set up successfully"); else - fmt::print(stderr, "failed to set up commands\n"); + LOGE(bot, "failed to set up commands"); }); } @@ -66,7 +68,7 @@ void Bot::getUpdates() getUpdates(); } else - fmt::print(stderr, "failed to get updates: {}\n", updates.error()); + LOG(bot, "failed to get updates: {}", updates.error()); }; banana::api::get_updates(agent_, {.offset = updatesOffset_, .timeout = 50}, std::move(handler)); @@ -78,7 +80,7 @@ void Bot::processUpdate(const banana::api::update_t& update) { if (update.message->text) { - fmt::print("rx: {}\n", *update.message->text); + LOG(bot, "rx: {}\n", *update.message->text); if (*update.message->text == "/start") processStartCommand(*update.message); else if (*update.message->text == "/subscribe_case") @@ -89,10 +91,10 @@ void Bot::processUpdate(const banana::api::update_t& update) } } else - fmt::print("skip message without text"); // TODO ответить + LOG(bot, "skip message without text"); // TODO ответить } else - fmt::print("skip unknown update type"); + LOGE(bot, "skip unknown update type"); } void Bot::processStartCommand(const banana::api::message_t& message) diff --git a/CMakeLists.txt b/CMakeLists.txt index e7925a4..416fe7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ add_subdirectory(external) add_executable(court_monitor Bot.cpp CourtApi.cpp + Logger.cpp Storage.cpp main.cpp ) diff --git a/Logger.cpp b/Logger.cpp new file mode 100644 index 0000000..37e895b --- /dev/null +++ b/Logger.cpp @@ -0,0 +1,12 @@ +#include "Logger.h" + +void vlog(std::FILE* stream, const char* category, fmt::string_view format, fmt::format_args args) +{ + log(stream, category, fmt::vformat(format, args)); +} + +void log(std::FILE* stream, const char* category, const std::string_view& message) +{ + auto formattedCategory = fmt::format("({})", category); + fmt::print(stream, "{: >16} {}\n", formattedCategory, message); +} diff --git a/Logger.h b/Logger.h new file mode 100644 index 0000000..7073bbd --- /dev/null +++ b/Logger.h @@ -0,0 +1,31 @@ +#ifndef COURT_MONITOR_LOGGER_H +#define COURT_MONITOR_LOGGER_H + +#include + +// clang-format off + +#define _CAT(a, b) a ## b +#define _SELECT(PREFIX, _10, _9, _8, _7, _6, _5, _4, _3, _2, _1, SUFFIX, ...) PREFIX##_##SUFFIX + +#define _LOG_1(stream, category, text) log(stream, category, text) +#define _LOG_N(stream, category, format, ...) log(stream, category, format, __VA_ARGS__) + +#define _LOG(stream, category, ...) _CAT(_SELECT(_LOG, __VA_ARGS__, N, N, N, N, N, N, N, N, N, 1,)(stream, category, __VA_ARGS__),) + +#define LOG(category, ...) _LOG(stdout, #category, __VA_ARGS__) +#define LOGE(category, ...) _LOG(stderr, #category, __VA_ARGS__) + +// clang-format on + +void log(std::FILE* stream, const char* category, const std::string_view& message); + +void vlog(std::FILE* stream, const char* category, fmt::string_view format, fmt::format_args args); + +template +void log(std::FILE* stream, const char* category, fmt::format_string format, T&&... args) +{ + vlog(stream, category, format, fmt::make_format_args(args...)); +} + +#endif // COURT_MONITOR_LOGGER_H diff --git a/main.cpp b/main.cpp index c68afcd..3db82e0 100644 --- a/main.cpp +++ b/main.cpp @@ -1,10 +1,10 @@ #include "Bot.h" #include "CourtApi.h" +#include "Logger.h" #include "Storage.h" #include #include -#include #include #include @@ -23,12 +23,12 @@ void processAllSubscriptions(LocalStorage& storage, Bot& bot) { try { - fmt::print("* Processing subscriptions for user {}\n", subscription.userId); + LOG(main, "* Processing subscriptions for user {}", subscription.userId); for (auto& counter : subscription.counters) { - fmt::print("** Processing case {}\n", counter.caseNumber); + LOG(main, "** Processing case {}", counter.caseNumber); auto details = getCaseDetails(asioContext, counter.courtId, counter.caseNumber); - fmt::print("{}\n", details.dump()); + LOG(main, details.dump()); auto url = details["url"].get(); auto history = parseHistory(details); @@ -39,7 +39,7 @@ void processAllSubscriptions(LocalStorage& storage, Bot& bot) } catch (const std::exception& e) { - fmt::print(stderr, "{}\n", e.what()); + LOG(main, e.what()); continue; } } @@ -60,7 +60,7 @@ bool terminate = false; void handleSignal(int) { - fmt::print("signal!\n"); + LOG(main, "signal!"); terminate = true; asioWork.reset(); asioContext.stop(); @@ -75,7 +75,7 @@ int main() // Загрузить данные из локального хранилища LocalStorage storage; loadStorage(storage); - fmt::print("Storage loaded\n"); + LOG(main, "Storage loaded"); // Создать бота Bot bot(asioContext, storage, terminate); @@ -100,13 +100,13 @@ int main() asioContext.run(); // Сохранить данные в локальное хранилище - fmt::print("Saving storage\n"); + LOG(main, "Saving storage"); saveStorage(storage); return 0; } catch (const std::exception& e) { - fmt::print(stderr, "{}\n", e.what()); + LOG(stderr, "{}\n", e.what()); return 1; } }