forked from mia/Aegisub
Write log files incrementally so that they actually exist for crashes
This commit is contained in:
parent
101721863a
commit
c6005be4a1
4 changed files with 35 additions and 47 deletions
|
@ -26,6 +26,8 @@
|
||||||
#include "libaegisub/util.h"
|
#include "libaegisub/util.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#include <boost/range/algorithm.hpp>
|
#include <boost/range/algorithm.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -90,43 +92,37 @@ Message::~Message() {
|
||||||
msg.freeze(false);
|
msg.freeze(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonEmitter::JsonEmitter(agi::fs::path const& directory, const agi::log::LogSink *log_sink)
|
JsonEmitter::JsonEmitter(fs::path const& directory)
|
||||||
: time_start(util::time_log())
|
: fp(new boost::filesystem::ofstream(unique_path(directory/util::strftime("%Y-%m-%d-%H-%M-%S-%%%%%%%%.json"))))
|
||||||
, directory(directory)
|
|
||||||
, log_sink(log_sink)
|
|
||||||
{
|
{
|
||||||
|
WriteTime("open");
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonEmitter::~JsonEmitter() {
|
JsonEmitter::~JsonEmitter() {
|
||||||
json::Object root;
|
WriteTime("close");
|
||||||
json::Array &array = root["log"];
|
}
|
||||||
|
|
||||||
auto time_close = util::time_log();
|
void JsonEmitter::log(SinkMessage *sm) {
|
||||||
|
json::Object entry;
|
||||||
|
entry["sec"] = (int64_t)sm->tv.tv_sec;
|
||||||
|
entry["usec"] = (int64_t)sm->tv.tv_usec;
|
||||||
|
entry["severity"] = sm->severity;
|
||||||
|
entry["section"] = sm->section;
|
||||||
|
entry["file"] = sm->file;
|
||||||
|
entry["func"] = sm->func;
|
||||||
|
entry["line"] = sm->line;
|
||||||
|
entry["message"] = sm->message;
|
||||||
|
json::Writer::Write(entry, *fp);
|
||||||
|
fp->flush();
|
||||||
|
}
|
||||||
|
|
||||||
Sink const& sink = *log_sink->GetSink();
|
void JsonEmitter::WriteTime(const char *key) {
|
||||||
for (unsigned int i=0; i < sink.size(); i++) {
|
auto time = util::time_log();
|
||||||
json::Object entry;
|
json::Object obj;
|
||||||
entry["sec"] = (int64_t)sink[i]->tv.tv_sec;
|
json::Array &timeval = obj[key];
|
||||||
entry["usec"] = (int64_t)sink[i]->tv.tv_usec;
|
timeval.push_back((int64_t)time.tv_sec);
|
||||||
entry["severity"] = sink[i]->severity;
|
timeval.push_back((int64_t)time.tv_usec);
|
||||||
entry["section"] = sink[i]->section;
|
json::Writer::Write(obj, *fp);
|
||||||
entry["file"] = sink[i]->file;
|
|
||||||
entry["func"] = sink[i]->func;
|
|
||||||
entry["line"] = sink[i]->line;
|
|
||||||
entry["message"] = sink[i]->message;
|
|
||||||
|
|
||||||
array.push_back(std::move(entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
json::Array &timeval_open = root["timeval"]["open"];
|
|
||||||
timeval_open.push_back((int64_t)time_start.tv_sec);
|
|
||||||
timeval_open.push_back((int64_t)time_start.tv_usec);
|
|
||||||
|
|
||||||
json::Array &timeval_close = root["timeval"]["close"];
|
|
||||||
timeval_close.push_back((int64_t)time_close.tv_sec);
|
|
||||||
timeval_close.push_back((int64_t)time_close.tv_usec);
|
|
||||||
|
|
||||||
json::Writer::Write(root, io::Save(directory/(std::to_string(time_start.tv_sec) + ".json")).Get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace log
|
} // namespace log
|
||||||
|
|
|
@ -19,11 +19,9 @@
|
||||||
#include <libaegisub/fs_fwd.h>
|
#include <libaegisub/fs_fwd.h>
|
||||||
#include <libaegisub/time.h>
|
#include <libaegisub/time.h>
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <iosfwd>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -133,26 +131,20 @@ public:
|
||||||
virtual void log(SinkMessage *sm)=0;
|
virtual void log(SinkMessage *sm)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A simple emitter which writes the log to a file in json format when it's destroyed
|
/// A simple emitter which writes the log to a file in json format
|
||||||
class JsonEmitter : public Emitter {
|
class JsonEmitter : public Emitter {
|
||||||
/// Init time
|
std::unique_ptr<std::ostream> fp;
|
||||||
timeval time_start;
|
|
||||||
|
|
||||||
/// Directory to write the log file in
|
void WriteTime(const char *key);
|
||||||
const agi::fs::path directory;
|
|
||||||
|
|
||||||
/// Parent sink to get messages from
|
|
||||||
const agi::log::LogSink *log_sink;
|
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param directory Directory to write the log file in
|
/// @param directory Directory to write the log file in
|
||||||
/// @param log_sink Parent sink to get messages from
|
JsonEmitter(fs::path const& directory);
|
||||||
JsonEmitter(agi::fs::path const& directory, const agi::log::LogSink *log_sink);
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~JsonEmitter();
|
~JsonEmitter();
|
||||||
|
|
||||||
/// No-op log function as everything is done in the destructor
|
void log(SinkMessage *);
|
||||||
void log(SinkMessage *) { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Generates a message and submits it to the log sink.
|
/// Generates a message and submits it to the log sink.
|
||||||
|
|
|
@ -180,7 +180,7 @@ bool AegisubApp::OnInit() {
|
||||||
StartupLog("Create log writer");
|
StartupLog("Create log writer");
|
||||||
auto path_log = StandardPaths::DecodePath("?user/log/");
|
auto path_log = StandardPaths::DecodePath("?user/log/");
|
||||||
agi::fs::CreateDirectory(path_log);
|
agi::fs::CreateDirectory(path_log);
|
||||||
agi::log::log->Subscribe(new agi::log::JsonEmitter(path_log, agi::log::log));
|
agi::log::log->Subscribe(new agi::log::JsonEmitter(path_log));
|
||||||
CleanCache(path_log, "*.json", 10, 100);
|
CleanCache(path_log, "*.json", 10, 100);
|
||||||
|
|
||||||
StartupLog("Load user configuration");
|
StartupLog("Load user configuration");
|
||||||
|
|
|
@ -23,7 +23,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
int retval;
|
int retval;
|
||||||
agi::log::log = new agi::log::LogSink;
|
agi::log::log = new agi::log::LogSink;
|
||||||
agi::log::log->Subscribe(new agi::log::JsonEmitter("./", agi::log::log));
|
agi::log::log->Subscribe(new agi::log::JsonEmitter("./"));
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
|
||||||
retval = RUN_ALL_TESTS();
|
retval = RUN_ALL_TESTS();
|
||||||
|
|
Loading…
Reference in a new issue