Split the json log writing into a seperate class from LogSink
Originally committed to SVN as r6248.
This commit is contained in:
parent
59ce8bf414
commit
e2d31b708e
5 changed files with 76 additions and 52 deletions
|
@ -64,49 +64,17 @@ SinkMessage::~SinkMessage() {
|
|||
delete message;
|
||||
}
|
||||
|
||||
|
||||
LogSink::LogSink(const std::string& dir_log): dir_log(dir_log) {
|
||||
util::time_log(time_start);
|
||||
}
|
||||
|
||||
/// @todo The log files need to be trimmed after N amount.
|
||||
LogSink::~LogSink() {
|
||||
json::Object root;
|
||||
json::Array &array = root["log"];
|
||||
// The destructor for emitters may try to log messages, so disable all the
|
||||
// emitters before destructing any
|
||||
std::vector<Emitter*> emitters_temp;
|
||||
swap(emitters_temp, emitters);
|
||||
util::delete_clear(emitters_temp);
|
||||
|
||||
agi_timeval time_close;
|
||||
util::time_log(time_close);
|
||||
|
||||
for (unsigned int i=0; i < sink.size(); i++) {
|
||||
json::Object entry;
|
||||
entry["sec"] = sink[i]->tv.tv_sec;
|
||||
entry["usec"] = sink[i]->tv.tv_usec;
|
||||
entry["severity"] = sink[i]->severity,
|
||||
entry["section"] = sink[i]->section;
|
||||
entry["file"] = sink[i]->file;
|
||||
entry["func"] = sink[i]->func;
|
||||
entry["line"] = sink[i]->line;
|
||||
entry["message"] = std::string(sink[i]->message, sink[i]->len);
|
||||
|
||||
array.push_back(entry);
|
||||
}
|
||||
|
||||
json::Array &timeval_open = root["timeval"]["open"];
|
||||
timeval_open.push_back(time_start.tv_sec);
|
||||
timeval_open.push_back(time_start.tv_usec);
|
||||
|
||||
json::Array &timeval_close = root["timeval"]["close"];
|
||||
timeval_close.push_back(time_close.tv_sec);
|
||||
timeval_close.push_back(time_close.tv_usec);
|
||||
|
||||
std::stringstream str;
|
||||
str << dir_log << time_start.tv_sec << ".json";
|
||||
json::Writer::Write(root, io::Save(str.str()).Get());
|
||||
|
||||
agi::util::delete_clear(sink);
|
||||
util::delete_clear(sink);
|
||||
}
|
||||
|
||||
|
||||
void LogSink::log(SinkMessage *sm) {
|
||||
sink.push_back(sm);
|
||||
|
||||
|
@ -147,5 +115,47 @@ Message::~Message() {
|
|||
agi::log::log->log(sm);
|
||||
}
|
||||
|
||||
JsonEmitter::JsonEmitter(std::string const& directory, const agi::log::LogSink *log_sink)
|
||||
: directory(directory)
|
||||
, log_sink(log_sink)
|
||||
{
|
||||
util::time_log(time_start);
|
||||
}
|
||||
|
||||
JsonEmitter::~JsonEmitter() {
|
||||
json::Object root;
|
||||
json::Array &array = root["log"];
|
||||
|
||||
agi_timeval time_close;
|
||||
util::time_log(time_close);
|
||||
|
||||
Sink const& sink = *log_sink->GetSink();
|
||||
for (unsigned int i=0; i < sink.size(); i++) {
|
||||
json::Object entry;
|
||||
entry["sec"] = sink[i]->tv.tv_sec;
|
||||
entry["usec"] = sink[i]->tv.tv_usec;
|
||||
entry["severity"] = sink[i]->severity;
|
||||
entry["section"] = sink[i]->section;
|
||||
entry["file"] = sink[i]->file;
|
||||
entry["func"] = sink[i]->func;
|
||||
entry["line"] = sink[i]->line;
|
||||
entry["message"] = std::string(sink[i]->message, sink[i]->len);
|
||||
|
||||
array.push_back(entry);
|
||||
}
|
||||
|
||||
json::Array &timeval_open = root["timeval"]["open"];
|
||||
timeval_open.push_back(time_start.tv_sec);
|
||||
timeval_open.push_back(time_start.tv_usec);
|
||||
|
||||
json::Array &timeval_close = root["timeval"]["close"];
|
||||
timeval_close.push_back(time_close.tv_sec);
|
||||
timeval_close.push_back(time_close.tv_usec);
|
||||
|
||||
std::stringstream str;
|
||||
str << directory << time_start.tv_sec << ".json";
|
||||
json::Writer::Write(root, io::Save(str.str()).Get());
|
||||
}
|
||||
|
||||
} // namespace log
|
||||
} // namespace agi
|
||||
|
|
|
@ -110,17 +110,7 @@ class LogSink {
|
|||
/// List of pointers to emitters
|
||||
std::vector<Emitter*> emitters;
|
||||
|
||||
/// Init time for log writing purposes.
|
||||
agi_timeval time_start;
|
||||
|
||||
/// Directory to place logfiles.
|
||||
const std::string dir_log;
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param dir_log Directory to place log files.
|
||||
LogSink(const std::string &dir_log);
|
||||
|
||||
/// Destructor
|
||||
~LogSink();
|
||||
|
||||
|
@ -139,7 +129,7 @@ public:
|
|||
|
||||
/// @brief @get the complete (current) log.
|
||||
/// @return Const pointer to internal sink.
|
||||
const Sink* GetSink() { return &sink; }
|
||||
const Sink* GetSink() const { return &sink; }
|
||||
};
|
||||
|
||||
/// An emitter to produce human readable output for a log sink.
|
||||
|
@ -152,6 +142,28 @@ public:
|
|||
virtual void log(SinkMessage *sm)=0;
|
||||
};
|
||||
|
||||
/// A simple emitter which writes the log to a file in json format when it's destroyed
|
||||
class JsonEmitter : public Emitter {
|
||||
/// Init time
|
||||
agi_timeval time_start;
|
||||
|
||||
/// Directory to write the log file in
|
||||
std::string directory;
|
||||
|
||||
/// Parent sink to get messages from
|
||||
const agi::log::LogSink *log_sink;
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param directory Directory to write the log file in
|
||||
/// @param log_sink Parent sink to get messages from
|
||||
JsonEmitter(std::string const& directory, const agi::log::LogSink *log_sink);
|
||||
/// Destructor
|
||||
~JsonEmitter();
|
||||
|
||||
/// No-op log function as everything is done in the destructor
|
||||
void log(SinkMessage *) { }
|
||||
};
|
||||
|
||||
/// Generates a message and submits it to the log sink.
|
||||
class Message {
|
||||
const int len;
|
||||
|
|
|
@ -43,7 +43,7 @@ bool Reporter::OnInit() {
|
|||
|
||||
const std::string path_log(util::config_path() + "log/");
|
||||
wxFileName::Mkdir(path_log, 0777, wxPATH_MKDIR_FULL);
|
||||
agi::log::log = new agi::log::LogSink(path_log);
|
||||
agi::log::log = new agi::log::LogSink;
|
||||
// if ( !wxApp::OnInit() )
|
||||
// return false;
|
||||
|
||||
|
|
|
@ -144,7 +144,8 @@ bool AegisubApp::OnInit() {
|
|||
// logging.
|
||||
wxString path_log = StandardPaths::DecodePath("?user/log/");
|
||||
wxFileName::Mkdir(path_log, 0777, wxPATH_MKDIR_FULL);
|
||||
agi::log::log = new agi::log::LogSink(STD_STR(path_log));
|
||||
agi::log::log = new agi::log::LogSink;
|
||||
agi::log::log->Subscribe(new agi::log::JsonEmitter(STD_STR(path_log), agi::log::log));
|
||||
|
||||
#ifdef _DEBUG
|
||||
agi::log::log->Subscribe(new agi::log::EmitSTDOUT());
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
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));
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
retval = RUN_ALL_TESTS();
|
||||
|
|
Loading…
Reference in a new issue