mirror of https://github.com/Icinga/icinga2.git
Merge pull request #7127 from Icinga/bugfix/replay-log
ApiListener#RotateLogFile(): don't overwrite previous log
This commit is contained in:
commit
20d51d21dc
|
@ -33,6 +33,7 @@
|
||||||
#include <openssl/tls1.h>
|
#include <openssl/tls1.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
@ -229,7 +230,6 @@ void ApiListener::Start(bool runtimeCreated)
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_LogLock);
|
boost::mutex::scoped_lock lock(m_LogLock);
|
||||||
RotateLogFile();
|
|
||||||
OpenLogFile();
|
OpenLogFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,6 +280,7 @@ void ApiListener::Stop(bool runtimeDeleted)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_LogLock);
|
boost::mutex::scoped_lock lock(m_LogLock);
|
||||||
CloseLogFile();
|
CloseLogFile();
|
||||||
|
RotateLogFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveStatusFile();
|
RemoveStatusFile();
|
||||||
|
@ -1156,13 +1157,11 @@ void ApiListener::RotateLogFile()
|
||||||
String oldpath = GetApiDir() + "log/current";
|
String oldpath = GetApiDir() + "log/current";
|
||||||
String newpath = GetApiDir() + "log/" + Convert::ToString(static_cast<int>(ts)+1);
|
String newpath = GetApiDir() + "log/" + Convert::ToString(static_cast<int>(ts)+1);
|
||||||
|
|
||||||
|
// If the log is being rotated more than once per second,
|
||||||
#ifdef _WIN32
|
// don't overwrite the previous one, but silently deny rotation.
|
||||||
_unlink(newpath.CStr());
|
if (!Utility::PathExists(newpath)) {
|
||||||
#endif /* _WIN32 */
|
(void) rename(oldpath.CStr(), newpath.CStr());
|
||||||
|
}
|
||||||
|
|
||||||
(void) rename(oldpath.CStr(), newpath.CStr());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiListener::LogGlobHandler(std::vector<int>& files, const String& file)
|
void ApiListener::LogGlobHandler(std::vector<int>& files, const String& file)
|
||||||
|
@ -1215,7 +1214,6 @@ void ApiListener::ReplayLog(const JsonRpcConnection::Ptr& client)
|
||||||
boost::mutex::scoped_lock lock(m_LogLock);
|
boost::mutex::scoped_lock lock(m_LogLock);
|
||||||
|
|
||||||
CloseLogFile();
|
CloseLogFile();
|
||||||
RotateLogFile();
|
|
||||||
|
|
||||||
if (count == -1 || count > 50000) {
|
if (count == -1 || count > 50000) {
|
||||||
OpenLogFile();
|
OpenLogFile();
|
||||||
|
@ -1230,16 +1228,21 @@ void ApiListener::ReplayLog(const JsonRpcConnection::Ptr& client)
|
||||||
Utility::Glob(GetApiDir() + "log/*", std::bind(&ApiListener::LogGlobHandler, std::ref(files), _1), GlobFile);
|
Utility::Glob(GetApiDir() + "log/*", std::bind(&ApiListener::LogGlobHandler, std::ref(files), _1), GlobFile);
|
||||||
std::sort(files.begin(), files.end());
|
std::sort(files.begin(), files.end());
|
||||||
|
|
||||||
|
std::vector<std::pair<int, String>> allFiles;
|
||||||
|
|
||||||
for (int ts : files) {
|
for (int ts : files) {
|
||||||
String path = GetApiDir() + "log/" + Convert::ToString(ts);
|
if (ts >= peer_ts) {
|
||||||
|
allFiles.emplace_back(ts, GetApiDir() + "log/" + Convert::ToString(ts));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ts < peer_ts)
|
allFiles.emplace_back(Utility::GetTime() + 1, GetApiDir() + "log/current");
|
||||||
continue;
|
|
||||||
|
|
||||||
|
for (auto& file : allFiles) {
|
||||||
Log(LogNotice, "ApiListener")
|
Log(LogNotice, "ApiListener")
|
||||||
<< "Replaying log: " << path;
|
<< "Replaying log: " << file.second;
|
||||||
|
|
||||||
auto *fp = new std::fstream(path.CStr(), std::fstream::in | std::fstream::binary);
|
auto *fp = new std::fstream(file.second.CStr(), std::fstream::in | std::fstream::binary);
|
||||||
StdioStream::Ptr logStream = new StdioStream(fp, true);
|
StdioStream::Ptr logStream = new StdioStream(fp, true);
|
||||||
|
|
||||||
String message;
|
String message;
|
||||||
|
@ -1259,7 +1262,7 @@ void ApiListener::ReplayLog(const JsonRpcConnection::Ptr& client)
|
||||||
pmessage = JsonDecode(message);
|
pmessage = JsonDecode(message);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
Log(LogWarning, "ApiListener")
|
Log(LogWarning, "ApiListener")
|
||||||
<< "Unexpected end-of-file for cluster log: " << path;
|
<< "Unexpected end-of-file for cluster log: " << file.second;
|
||||||
|
|
||||||
/* Log files may be incomplete or corrupted. This is perfectly OK. */
|
/* Log files may be incomplete or corrupted. This is perfectly OK. */
|
||||||
break;
|
break;
|
||||||
|
@ -1295,8 +1298,8 @@ void ApiListener::ReplayLog(const JsonRpcConnection::Ptr& client)
|
||||||
|
|
||||||
peer_ts = pmessage->Get("timestamp");
|
peer_ts = pmessage->Get("timestamp");
|
||||||
|
|
||||||
if (ts > logpos_ts + 10) {
|
if (file.first > logpos_ts + 10) {
|
||||||
logpos_ts = ts;
|
logpos_ts = file.first;
|
||||||
|
|
||||||
Dictionary::Ptr lmessage = new Dictionary({
|
Dictionary::Ptr lmessage = new Dictionary({
|
||||||
{ "jsonrpc", "2.0" },
|
{ "jsonrpc", "2.0" },
|
||||||
|
|
Loading…
Reference in New Issue