1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
#include "Logger.hpp"
#include "QueueItem.hpp"
#include <iostream>
// Initialize static members
std::unique_ptr<Logger> Logger::s_instance = nullptr;
std::mutex Logger::s_instanceMutex;
Logger &Logger::getInstance()
{
std::lock_guard<std::mutex> lock(s_instanceMutex);
if (s_instance == nullptr)
{
s_instance.reset(new Logger());
}
return *s_instance;
}
Logger::Logger()
: m_logQueue(nullptr),
m_appendTimeout(std::chrono::milliseconds::max()),
m_initialized(false)
{
}
Logger::~Logger()
{
if (m_initialized)
{
reset();
}
}
bool Logger::initialize(std::shared_ptr<BufferQueue> queue,
std::chrono::milliseconds appendTimeout)
{
if (m_initialized)
{
reportError("Logger already initialized");
return false;
}
if (!queue)
{
reportError("Cannot initialize with a null queue");
return false;
}
m_logQueue = std::move(queue);
m_appendTimeout = appendTimeout;
m_initialized = true;
return true;
}
BufferQueue::ProducerToken Logger::createProducerToken()
{
if (!m_initialized)
{
reportError("Logger not initialized");
throw std::runtime_error("Logger not initialized");
}
return m_logQueue->createProducerToken();
}
bool Logger::append(LogEntry entry,
BufferQueue::ProducerToken &token,
const std::optional<std::string> &filename)
{
if (!m_initialized)
{
reportError("Logger not initialized");
return false;
}
QueueItem item{std::move(entry), filename};
return m_logQueue->enqueueBlocking(std::move(item), token, m_appendTimeout);
}
bool Logger::appendBatch(std::vector<LogEntry> entries,
BufferQueue::ProducerToken &token,
const std::optional<std::string> &filename)
{
if (!m_initialized)
{
reportError("Logger not initialized");
return false;
}
if (entries.empty())
{
return true;
}
std::vector<QueueItem> batch;
batch.reserve(entries.size());
for (auto &entry : entries)
{
batch.emplace_back(std::move(entry), filename);
}
return m_logQueue->enqueueBatchBlocking(std::move(batch), token, m_appendTimeout);
}
bool Logger::reset()
{
if (!m_initialized)
{
return false;
}
// Reset state
m_initialized = false;
m_logQueue.reset();
return true;
}
bool Logger::exportLogs(
const std::string &outputPath,
std::chrono::system_clock::time_point fromTimestamp,
std::chrono::system_clock::time_point toTimestamp)
{
if (!m_initialized)
{
reportError("Logger not initialized");
return false;
}
// This functionality would typically be handled by a separate component,
// such as a log storage or retrieval system
reportError("Export logs functionality not implemented in Logger");
return false;
}
void Logger::reportError(const std::string &message)
{
std::cerr << "Logger Error: " << message << std::endl;
}
|