Add logger.hpp

This commit is contained in:
quqiOnfree 2025-02-23 00:24:58 +08:00
parent c188a824ad
commit e3aedd510f
3 changed files with 165 additions and 38 deletions

103
src/include/logger.hpp Normal file
View File

@ -0,0 +1,103 @@
#pragma once
#include <iostream>
#include <condition_variable>
#include <thread>
#include <mutex>
#include <queue>
#include <chrono>
#include <atomic>
#include <string>
#include <functional>
namespace cxxlog
{
class Logger
{
public:
Logger():
is_running_(true)
{
thread_ = std::thread([&]() {
while (true)
{
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [&](){ return !is_running_ || !msg_queue_.empty(); });
if (!is_running_ && msg_queue_.empty())
return;
else if (msg_queue_.empty())
continue;
std::function<void()> func = std::move(msg_queue_.front());
msg_queue_.pop();
lock.unlock();
std::invoke(func);
}
});
}
~Logger()
{
if (is_running_)
join();
}
template<typename... Args>
void cerr(Args... args)
{
std::unique_lock<std::mutex> lock(mutex_);
msg_queue_.push(std::bind([](auto... args) {
std::cerr << generateTimeFormatString();
((std::cerr << args), ...);
std::cerr << std::endl;
}, std::move(args)...));
lock.unlock();
cv_.notify_all();
}
template<typename... Args>
void cout(Args... args)
{
std::unique_lock<std::mutex> lock(mutex_);
msg_queue_.push(std::bind([](auto... args) {
std::cout << generateTimeFormatString();
((std::cout << args), ...);
std::cout << std::endl;
}, std::move(args)...));
lock.unlock();
cv_.notify_all();
}
void join()
{
is_running_ = false;
cv_.notify_all();
if (thread_.joinable())
thread_.join();
}
bool joinable()
{
return is_running_;
}
protected:
static std::string generateTimeFormatString()
{
auto t = std::chrono::system_clock::to_time_t(
std::chrono::system_clock::now());
std::stringstream ss;
ss << std::put_time(std::localtime(&t), "[%H:%M:%S]");
return ss.str();
}
private:
std::condition_variable cv_;
std::mutex mutex_;
std::atomic<bool> is_running_;
std::queue<std::function<void()>> msg_queue_;
std::thread thread_;
};
} // namespace cxxlog

View File

@ -41,6 +41,21 @@ public:
}
~ThreadPool() noexcept
{
if (is_running_)
join();
}
template<class Func, class... Args>
void submit(Func&& func, Args&&... args)
{
std::unique_lock<std::mutex> lock(mutex_);
queue_.push(std::bind(func, std::forward<Args>(args)...));
lock.unlock();
cv_.notify_one();
}
void join()
{
is_running_ = false;
cv_.notify_all();
@ -52,13 +67,9 @@ public:
}
}
template<class Func, class... Args>
void submit(Func&& func, Args&&... args)
bool joinable()
{
std::unique_lock<std::mutex> lock(mutex_);
queue_.push(std::bind(func, std::forward<Args>(args)...));
lock.unlock();
cv_.notify_one();
return is_running_;
}
private:

View File

@ -4,6 +4,7 @@
#include <stdexcept>
#include <vector>
#include <filesystem>
#include <memory>
#if defined(_WIN32)
#include "platform.h"
@ -13,45 +14,48 @@
#include "version.h"
#include "cxxopts.hpp"
#include "thread_pool.hpp"
#include "logger.hpp"
namespace fs = std::filesystem;
cxxpool::ThreadPool thread_pool;
cxxlog::Logger logger;
void processFileTask(fs::path filePath, fs::path outputFolder)
{
if (fs::exists(filePath) == false)
{
logger.cerr(BOLDRED, "[Error] ", RESET, "file '", filePath.u8string(), "' does not exist.");
return;
}
// skip if not ending with ".ncm"
if (!filePath.has_extension() || filePath.extension().u8string() != ".ncm")
{
return;
}
try
{
NeteaseCrypt crypt(filePath.u8string());
crypt.Dump(outputFolder.u8string());
crypt.FixMetadata();
logger.cout(BOLDGREEN, "[Done] ", RESET, "'", filePath.u8string(), "' -> '", crypt.dumpFilepath().u8string(), "'");
}
catch (const std::invalid_argument &e)
{
logger.cerr(BOLDRED, "[Exception] ", RESET, RED, e.what(), RESET, " '", filePath.u8string(), "'");
}
catch (...)
{
logger.cerr(BOLDRED, "[Error] Unexpected exception while processing file: ", RESET, filePath.u8string());
}
}
void processFile(const fs::path &filePath, const fs::path &outputFolder)
{
auto work_func = [](fs::path filePath, fs::path outputFolder) {
if (fs::exists(filePath) == false)
{
std::cerr << BOLDRED << "[Error] " << RESET << "file '" << filePath.u8string() << "' does not exist." << std::endl;
return;
}
// skip if not ending with ".ncm"
if (!filePath.has_extension() || filePath.extension().u8string() != ".ncm")
{
return;
}
try
{
NeteaseCrypt crypt(filePath.u8string());
crypt.Dump(outputFolder.u8string());
crypt.FixMetadata();
std::cout << BOLDGREEN << "[Done] " << RESET << "'" << filePath.u8string() << "' -> '" << crypt.dumpFilepath().u8string() << "'" << std::endl;
}
catch (const std::invalid_argument &e)
{
std::cerr << BOLDRED << "[Exception] " << RESET << RED << e.what() << RESET << " '" << filePath.u8string() << "'" << std::endl;
}
catch (...)
{
std::cerr << BOLDRED << "[Error] Unexpected exception while processing file: " << RESET << filePath.u8string() << std::endl;
}
};
thread_pool.submit(work_func, filePath, outputFolder);
thread_pool.submit(processFileTask, filePath, outputFolder);
}
int main(int argc, char **argv)
@ -194,6 +198,10 @@ int main(int argc, char **argv)
}
}
}
if (thread_pool.joinable())
thread_pool.join();
if (logger.joinable())
logger.join();
return 0;
}
@ -218,6 +226,11 @@ int main(int argc, char **argv)
processFile(filePathU8, "");
}
}
if (thread_pool.joinable())
thread_pool.join();
if (logger.joinable())
logger.join();
return 0;
}
return 0;
}