Split the json log writing into a seperate class from LogSink

Originally committed to SVN as r6248.
This commit is contained in:
Thomas Goyne 2012-01-08 01:36:23 +00:00
parent 59ce8bf414
commit e2d31b708e
5 changed files with 76 additions and 52 deletions

View File

@ -64,49 +64,17 @@ SinkMessage::~SinkMessage() {
delete message; 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. /// @todo The log files need to be trimmed after N amount.
LogSink::~LogSink() { LogSink::~LogSink() {
json::Object root; // The destructor for emitters may try to log messages, so disable all the
json::Array &array = root["log"]; // emitters before destructing any
std::vector<Emitter*> emitters_temp;
swap(emitters_temp, emitters);
util::delete_clear(emitters_temp);
agi_timeval time_close; util::delete_clear(sink);
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);
} }
void LogSink::log(SinkMessage *sm) { void LogSink::log(SinkMessage *sm) {
sink.push_back(sm); sink.push_back(sm);
@ -147,5 +115,47 @@ Message::~Message() {
agi::log::log->log(sm); 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 log
} // namespace agi } // namespace agi

View File

@ -110,17 +110,7 @@ class LogSink {
/// List of pointers to emitters /// List of pointers to emitters
std::vector<Emitter*> 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: public:
/// Constructor
/// @param dir_log Directory to place log files.
LogSink(const std::string &dir_log);
/// Destructor /// Destructor
~LogSink(); ~LogSink();
@ -139,7 +129,7 @@ public:
/// @brief @get the complete (current) log. /// @brief @get the complete (current) log.
/// @return Const pointer to internal sink. /// @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. /// An emitter to produce human readable output for a log sink.
@ -152,6 +142,28 @@ 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
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. /// Generates a message and submits it to the log sink.
class Message { class Message {
const int len; const int len;

View File

@ -43,7 +43,7 @@ bool Reporter::OnInit() {
const std::string path_log(util::config_path() + "log/"); const std::string path_log(util::config_path() + "log/");
wxFileName::Mkdir(path_log, 0777, wxPATH_MKDIR_FULL); 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() ) // if ( !wxApp::OnInit() )
// return false; // return false;

View File

@ -144,7 +144,8 @@ bool AegisubApp::OnInit() {
// logging. // logging.
wxString path_log = StandardPaths::DecodePath("?user/log/"); wxString path_log = StandardPaths::DecodePath("?user/log/");
wxFileName::Mkdir(path_log, 0777, wxPATH_MKDIR_FULL); 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 #ifdef _DEBUG
agi::log::log->Subscribe(new agi::log::EmitSTDOUT()); agi::log::log->Subscribe(new agi::log::EmitSTDOUT());

View File

@ -24,7 +24,8 @@
int main(int argc, char **argv) { 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));
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
retval = RUN_ALL_TESTS(); retval = RUN_ALL_TESTS();