2024-06-14 13:11:40 +03:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <shared_mutex>
|
2025-12-18 17:23:24 +00:00
|
|
|
#include <unordered_map>
|
|
|
|
|
#include <format>
|
|
|
|
|
#include <vector>
|
2024-06-14 13:11:40 +03:00
|
|
|
|
2025-12-18 17:23:24 +00:00
|
|
|
namespace Log {
|
2024-12-07 18:51:18 +01:00
|
|
|
struct SRollingLogFollow {
|
2025-04-21 20:42:02 +02:00
|
|
|
std::unordered_map<int, std::string> m_socketToRollingLogFollowQueue;
|
|
|
|
|
std::shared_mutex m_mutex;
|
|
|
|
|
bool m_running = false;
|
2024-06-14 13:11:40 +03:00
|
|
|
static constexpr size_t ROLLING_LOG_FOLLOW_TOO_BIG = 8192;
|
|
|
|
|
|
|
|
|
|
// Returns true if the queue is empty for the given socket
|
|
|
|
|
bool isEmpty(int socket) {
|
2025-04-21 20:42:02 +02:00
|
|
|
std::shared_lock<std::shared_mutex> r(m_mutex);
|
|
|
|
|
return m_socketToRollingLogFollowQueue[socket].empty();
|
2024-06-14 13:11:40 +03:00
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
std::string debugInfo() {
|
2025-04-21 20:42:02 +02:00
|
|
|
std::shared_lock<std::shared_mutex> r(m_mutex);
|
|
|
|
|
return std::format("RollingLogFollow, got {} connections", m_socketToRollingLogFollowQueue.size());
|
2024-06-14 13:11:40 +03:00
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
std::string getLog(int socket) {
|
2025-04-21 20:42:02 +02:00
|
|
|
std::unique_lock<std::shared_mutex> w(m_mutex);
|
2024-06-14 13:11:40 +03:00
|
|
|
|
2025-04-21 20:42:02 +02:00
|
|
|
const std::string ret = m_socketToRollingLogFollowQueue[socket];
|
|
|
|
|
m_socketToRollingLogFollowQueue[socket] = "";
|
2024-06-14 13:11:40 +03:00
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-18 17:23:24 +00:00
|
|
|
void addLog(const std::string_view& log) {
|
2025-04-21 20:42:02 +02:00
|
|
|
std::unique_lock<std::shared_mutex> w(m_mutex);
|
|
|
|
|
m_running = true;
|
2024-06-14 13:11:40 +03:00
|
|
|
std::vector<int> to_erase;
|
2025-12-18 17:23:24 +00:00
|
|
|
for (const auto& p : m_socketToRollingLogFollowQueue) {
|
|
|
|
|
m_socketToRollingLogFollowQueue[p.first] += log;
|
|
|
|
|
m_socketToRollingLogFollowQueue[p.first] += "\n";
|
|
|
|
|
}
|
2024-06-14 13:11:40 +03:00
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
bool isRunning() {
|
2025-04-21 20:42:02 +02:00
|
|
|
std::shared_lock<std::shared_mutex> r(m_mutex);
|
|
|
|
|
return m_running;
|
2024-06-14 13:11:40 +03:00
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
void stopFor(int socket) {
|
2025-04-21 20:42:02 +02:00
|
|
|
std::unique_lock<std::shared_mutex> w(m_mutex);
|
|
|
|
|
m_socketToRollingLogFollowQueue.erase(socket);
|
|
|
|
|
if (m_socketToRollingLogFollowQueue.empty())
|
|
|
|
|
m_running = false;
|
2024-06-14 13:11:40 +03:00
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
void startFor(int socket) {
|
2025-04-21 20:42:02 +02:00
|
|
|
std::unique_lock<std::shared_mutex> w(m_mutex);
|
|
|
|
|
m_socketToRollingLogFollowQueue[socket] = std::format("[LOG] Following log to socket: {} started\n", socket);
|
|
|
|
|
m_running = true;
|
2024-06-14 13:11:40 +03:00
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
static SRollingLogFollow& get() {
|
|
|
|
|
static SRollingLogFollow instance;
|
2024-06-14 13:11:40 +03:00
|
|
|
static std::mutex gm;
|
|
|
|
|
std::lock_guard<std::mutex> lock(gm);
|
|
|
|
|
return instance;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}
|