Added fetch_logs function

This commit is contained in:
Leon Etienne (ubuntu wsl) 2020-09-27 15:18:52 +02:00
parent feb2d92e38
commit 5982019351
9 changed files with 151 additions and 12 deletions

View File

@ -7,6 +7,7 @@
#include "FileSystem.h" #include "FileSystem.h"
#include "XGConfig.h" #include "XGConfig.h"
#include "Logger.h" #include "Logger.h"
#include "LogHistory.h"
namespace Downloader namespace Downloader
{ {

View File

@ -455,6 +455,35 @@ void JsonArray::Add(const std::vector<JsonBlock> data)
return; return;
} }
void JsonArray::Merge(const JsonArray& other)
{
// If merging into itself, we have to cache a copy of itself in the beginning state
if (this == &other)
{
JsonArray clonedOther;
clonedOther.CloneFrom(other);
for (std::size_t i = 0; i < clonedOther.Size(); i++)
{
JsonData jd;
jd.CloneFrom(clonedOther.At(i));
Add(jd);
}
}
else
{
// All ok, merging from a different array
for (std::size_t i = 0; i < other.Size(); i++)
{
JsonData jd;
jd.CloneFrom(other.At(i));
Add(jd);
}
}
return;
}
void JsonArray::InsertExistingtJsonData(const std::vector<JsonData*> data) void JsonArray::InsertExistingtJsonData(const std::vector<JsonData*> data)
{ {
for (std::size_t i = 0; i < data.size(); i++) for (std::size_t i = 0; i < data.size(); i++)

View File

@ -629,6 +629,12 @@ namespace JasonPP
/// <param name="data">To be added</param> /// <param name="data">To be added</param>
void Add(const std::vector<JsonBlock> data); void Add(const std::vector<JsonBlock> data);
/// <summary>
/// Will merge JsonArray other into this, deep-copying all values.
/// </summary>
/// <param name="other">Array to merge-copy from</param>
void Merge(const JsonArray& other);
/// <summary> /// <summary>
/// Will append the object given /// Will append the object given
/// </summary> /// </summary>
@ -2142,7 +2148,7 @@ namespace JasonPP
}; };
} }
#define JASONPP_VERSION (1.0215) #define JASONPP_VERSION (1.0216)
namespace JasonPP namespace JasonPP
{ {

View File

@ -42,12 +42,12 @@ void LogHistory::Update()
void LogHistory::Save() void LogHistory::Save()
{ {
std::stringstream textfile; std::stringstream textfile;
JasonPP::Json jsonFile = JasonPP::JsonArray(); JasonPP::Json newJsonLogs = JasonPP::JsonArray();
for (std::size_t i = 0; i < history->size(); i++) for (std::size_t i = 0; i < history->size(); i++)
{ {
textfile << history->at(i)->compiledMessage << std::endl; textfile << history->at(i)->compiledMessage << std::endl;
jsonFile.AsArray += history->at(i)->GetAsJson(); newJsonLogs.AsArray += history->at(i)->GetAsJson();
} }
std::ofstream ofs; std::ofstream ofs;
@ -55,9 +55,41 @@ void LogHistory::Save()
ofs << textfile.str(); ofs << textfile.str();
ofs.close(); ofs.close();
ofs.open(XGConfig::logging.logfile_json, std::ios::app); // You can't just append to a json array file...
ofs << jsonFile.Render(); // You have to first parse it, append to it, and then rewrite the complete file
ofs.close(); {
JasonPP::Json allLogs;
if (FileSystem::Exists(XGConfig::logging.logfile_json))
{
std::string fileContent = FileSystem::ReadFile(XGConfig::logging.logfile_json);
if (JasonPP::IsJsonValid(fileContent))
{
allLogs.Parse(fileContent);
if (allLogs.GetDataType() != JasonPP::JDType::ARRAY)
{
// Json file is fucked (wrong format). Reset to empty array
allLogs.SetArrayData(JasonPP::JsonArray());
}
}
else
{
// Json file is fucked (wrong syntax). Reset to empty array
allLogs.SetArrayData(JasonPP::JsonArray());
}
}
else
{
// Json file is fucked (doesn't exist). Reset to empty array
allLogs.SetArrayData(JasonPP::JsonArray());
}
allLogs.AsArray.Merge(newJsonLogs.AsArray);
ofs.open(XGConfig::logging.logfile_json);
ofs << allLogs.Render();
ofs.close();
}
lastSave = time(0); lastSave = time(0);
didHistoryChangeSinceLastSave = false; didHistoryChangeSinceLastSave = false;
@ -65,6 +97,57 @@ void LogHistory::Save()
return; return;
} }
JasonPP::JsonArray LogHistory::GetCompleteLogHistoryAsJson()
{
Save();
// Logfile does not exist, just return an empty array
if (!FileSystem::Exists(XGConfig::logging.logfile_json))
{
std::cout << "no log file" << std::endl;
return JasonPP::JsonArray();
}
else
{
// Logfile exists
std::string file_contents = FileSystem::ReadFile(XGConfig::logging.logfile_json);
if (JasonPP::IsJsonValid(file_contents))
{
JasonPP::Json logs;
logs.Parse(file_contents);
if (logs.GetDataType() == JasonPP::JDType::ARRAY)
{
logs.AsArray.Sort("timestamp", JasonPP::JSON_ARRAY_SORT_MODE::NUM_DESC);
return logs.AsArray;
}
else
{
std::cout << "invalid format log file" << std::endl;
ClearLogHistory(); // The json logfile is fucked
return JasonPP::JsonArray();
}
}
else
{
std::cout << "invalid syntax log file" << std::endl;
std::cout << file_contents << std::endl;
ClearLogHistory(); // The json logfile is fucked
return JasonPP::JsonArray();
}
}
}
bool LogHistory::ClearLogHistory()
{
FileSystem::Delete(XGConfig::logging.logfile_json);
FileSystem::Delete(XGConfig::logging.logfile_text);
Save();
return true;
}
void LogHistory::AddLogToHistory(LogEntry* newEntry) void LogHistory::AddLogToHistory(LogEntry* newEntry)
{ {
history->push_back(newEntry); history->push_back(newEntry);
@ -80,9 +163,10 @@ bool LogHistory::didHistoryChangeSinceLastSave;
JasonPP::JsonBlock LogEntry::GetAsJson() JasonPP::JsonBlock LogEntry::GetAsJson()
{ {
return JasonPP::JsonBlock({ return JasonPP::JsonBlock({
Ele("compiledMessage", message), Ele("compiledMessage", compiledMessage),
Ele("message", compiledMessage), Ele("message", message),
Ele("identifier", identifier), Ele("identifier", identifier),
Ele("additional_information", additional_information),
Ele("type", (int)type), Ele("type", (int)type),
Ele("timestamp", (long long int)timestamp), Ele("timestamp", (long long int)timestamp),
}); });

View File

@ -18,6 +18,7 @@ namespace Logging
std::string compiledMessage; std::string compiledMessage;
std::string message; std::string message;
std::string identifier; std::string identifier;
std::string additional_information;
LOG_TYPE type; LOG_TYPE type;
std::time_t timestamp; std::time_t timestamp;
@ -33,7 +34,13 @@ namespace Logging
static void Save(); static void Save();
static std::vector<LogEntry*>* GetLogHistory() { return history; } static std::vector<LogEntry*>* GetSessionLogHistory() { return history; }
static JasonPP::JsonArray GetCompleteLogHistoryAsJson();
/// <summary>
/// Will clear the log history
/// </summary>
static bool ClearLogHistory();
private: private:
static void AddLogToHistory(LogEntry* newEntry); static void AddLogToHistory(LogEntry* newEntry);

View File

@ -46,12 +46,13 @@ std::string Logger::Flush()
strftime(timeBuf, 100, "%d.%m.%Y - %T", &currTm); strftime(timeBuf, 100, "%d.%m.%Y - %T", &currTm);
std::stringstream bufOut; std::stringstream bufOut;
bufOut << "<" << timeBuf << "> [" << identifier << "]" << TypeToPrefix(type) << ((additionalInfo.length() > 0) ? " " : "") << additionalInfo << ": " << cout.str(); bufOut << "<" << timeBuf << "> [" << identifier << "]" << TypeToPrefix(type) << ((additional_information.length() > 0) ? " " : "") << additional_information << ": " << cout.str();
LogEntry* newEntry = new LogEntry; LogEntry* newEntry = new LogEntry;
newEntry->message = cout.str(); newEntry->message = cout.str();
newEntry->compiledMessage = bufOut.str(); newEntry->compiledMessage = bufOut.str();
newEntry->identifier = identifier; newEntry->identifier = identifier;
newEntry->additional_information = additional_information;
newEntry->timestamp = currTime; newEntry->timestamp = currTime;
newEntry->type = type; newEntry->type = type;
LogHistory::AddLogToHistory(newEntry); LogHistory::AddLogToHistory(newEntry);

View File

@ -21,7 +21,7 @@ namespace Logging
void Set(std::string str); void Set(std::string str);
//Sets additional information to be appended after the identifier //Sets additional information to be appended after the identifier
void SetAdditionalInformation(std::string str) { additionalInfo = str; }; void SetAdditionalInformation(std::string str) { additional_information = str; };
//Prints the buffered string to the console and clears it //Prints the buffered string to the console and clears it
std::string Flush(); std::string Flush();
@ -44,7 +44,7 @@ namespace Logging
bool IsInitializedSanityCheck(); bool IsInitializedSanityCheck();
std::string identifier; std::string identifier;
std::string additionalInfo = ""; std::string additional_information = "";
LOG_TYPE type = LOG_TYPE::LOG; LOG_TYPE type = LOG_TYPE::LOG;
bool isInitialized = false; bool isInitialized = false;

View File

@ -34,6 +34,7 @@ bool RestQueryHandler::ProcessQuery(const std::string clientAdress, const Json&
else if (requestName == "show_console") return ShowConsole(requestBody, responseBody, responseCode); else if (requestName == "show_console") return ShowConsole(requestBody, responseBody, responseCode);
else if (requestName == "hide_console") return HideConsole(requestBody, responseBody, responseCode); else if (requestName == "hide_console") return HideConsole(requestBody, responseBody, responseCode);
else if (requestName == "get_os_name") return GetOSName(requestBody, responseBody, responseCode); else if (requestName == "get_os_name") return GetOSName(requestBody, responseBody, responseCode);
else if (requestName == "fetch_logs") return FetchLogs(requestBody, responseBody, responseCode);
@ -208,7 +209,16 @@ bool RestQueryHandler::GetOSName(const JsonBlock& request, JsonBlock& responseBo
return true; return true;
} }
bool RestQueryHandler::FetchLogs(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
{
log->cout << "Fetching logs...";
log->Flush();
responseCode = OK;
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
responseBody.Set("logs") = LogHistory::GetCompleteLogHistoryAsJson();
return true;
}

View File

@ -26,6 +26,7 @@ namespace Rest
static bool HideConsole(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode); static bool HideConsole(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
static bool ShowConsole(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode); static bool ShowConsole(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
static bool GetOSName(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode); static bool GetOSName(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
static bool FetchLogs(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
static bool ValidateField(const std::string name, const JasonPP::JDType type, const JasonPP::Json& checkThat, JasonPP::JsonBlock& putErrorResponseHere); static bool ValidateField(const std::string name, const JasonPP::JDType type, const JasonPP::Json& checkThat, JasonPP::JsonBlock& putErrorResponseHere);