forked from mia/Aegisub
Use a circular buffer to store only the last 250 log messages
This commit is contained in:
parent
c6005be4a1
commit
a942687050
3 changed files with 21 additions and 43 deletions
|
@ -30,7 +30,6 @@
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#include <boost/range/algorithm.hpp>
|
#include <boost/range/algorithm.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace agi {
|
namespace agi {
|
||||||
|
@ -43,30 +42,17 @@ LogSink *log;
|
||||||
/// Keep this ordered the same as Severity
|
/// Keep this ordered the same as Severity
|
||||||
const char *Severity_ID = "EAWID";
|
const char *Severity_ID = "EAWID";
|
||||||
|
|
||||||
SinkMessage::SinkMessage(const char *section, Severity severity, const char *file, const char *func, int line, timeval tv)
|
|
||||||
: section(section)
|
|
||||||
, severity(severity)
|
|
||||||
, file(file)
|
|
||||||
, func(func)
|
|
||||||
, line(line)
|
|
||||||
, tv(tv)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @todo The log files need to be trimmed after N amount.
|
|
||||||
LogSink::~LogSink() {
|
LogSink::~LogSink() {
|
||||||
// The destructor for emitters may try to log messages, so disable all the
|
// The destructor for emitters may try to log messages, so disable all the
|
||||||
// emitters before destructing any
|
// emitters before destructing any
|
||||||
std::vector<Emitter*> emitters_temp;
|
std::vector<Emitter*> emitters_temp;
|
||||||
swap(emitters_temp, emitters);
|
swap(emitters_temp, emitters);
|
||||||
util::delete_clear(emitters_temp);
|
util::delete_clear(emitters_temp);
|
||||||
|
|
||||||
util::delete_clear(sink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogSink::log(SinkMessage *sm) {
|
void LogSink::Log(SinkMessage const& sm) {
|
||||||
sink.push_back(sm);
|
messages.push_back(sm);
|
||||||
boost::for_each(emitters, [=](Emitter *em) { em->log(sm); });
|
boost::for_each(emitters, [=](Emitter *em) { em->log(&messages.back()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogSink::Subscribe(Emitter *em) {
|
void LogSink::Subscribe(Emitter *em) {
|
||||||
|
@ -83,12 +69,17 @@ void LogSink::Unsubscribe(Emitter *em) {
|
||||||
Message::Message(const char *section, Severity severity, const char *file, const char *func, int line)
|
Message::Message(const char *section, Severity severity, const char *file, const char *func, int line)
|
||||||
: msg(nullptr, 1024)
|
: msg(nullptr, 1024)
|
||||||
{
|
{
|
||||||
sm = new SinkMessage(section, severity, file, func, line, util::time_log());
|
sm.section = section;
|
||||||
|
sm.severity = severity;
|
||||||
|
sm.file = file;
|
||||||
|
sm.func = func;
|
||||||
|
sm.line = line;
|
||||||
|
sm.tv = util::time_log();
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::~Message() {
|
Message::~Message() {
|
||||||
sm->message = std::string(msg.str(), (std::string::size_type)msg.pcount());
|
sm.message = std::string(msg.str(), (std::string::size_type)msg.pcount());
|
||||||
agi::log::log->log(sm);
|
agi::log::log->Log(sm);
|
||||||
msg.freeze(false);
|
msg.freeze(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <libaegisub/time.h>
|
#include <libaegisub/time.h>
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <deque>
|
#include <boost/circular_buffer.hpp>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -68,15 +68,6 @@ extern LogSink *log;
|
||||||
|
|
||||||
/// Container to hold a single message
|
/// Container to hold a single message
|
||||||
struct SinkMessage {
|
struct SinkMessage {
|
||||||
/// @brief Constructor
|
|
||||||
/// @param section Section info
|
|
||||||
/// @param severity Severity
|
|
||||||
/// @param file File name
|
|
||||||
/// @param func Function name
|
|
||||||
/// @param line Source line
|
|
||||||
/// @param tv Log time
|
|
||||||
SinkMessage(const char *section, Severity severity, const char *file, const char *func, int line, timeval tv);
|
|
||||||
|
|
||||||
const char *section; ///< Section info eg "video/open" "video/seek" etc
|
const char *section; ///< Section info eg "video/open" "video/seek" etc
|
||||||
Severity severity; ///< Severity
|
Severity severity; ///< Severity
|
||||||
const char *file; ///< Source file
|
const char *file; ///< Source file
|
||||||
|
@ -88,23 +79,19 @@ struct SinkMessage {
|
||||||
|
|
||||||
class Emitter;
|
class Emitter;
|
||||||
|
|
||||||
/// Message sink for holding all messages
|
|
||||||
typedef std::deque<SinkMessage*> Sink;
|
|
||||||
|
|
||||||
/// Log sink, single destination for all messages
|
/// Log sink, single destination for all messages
|
||||||
class LogSink {
|
class LogSink {
|
||||||
/// Log sink
|
boost::circular_buffer<SinkMessage> messages;
|
||||||
Sink sink;
|
|
||||||
|
|
||||||
/// List of pointers to emitters
|
/// List of pointers to emitters
|
||||||
std::vector<Emitter*> emitters;
|
std::vector<Emitter*> emitters;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Destructor
|
LogSink() : messages(250) { }
|
||||||
~LogSink();
|
~LogSink();
|
||||||
|
|
||||||
/// Insert a message into the sink.
|
/// Insert a message into the sink.
|
||||||
void log(SinkMessage *sm);
|
void Log(SinkMessage const& sm);
|
||||||
|
|
||||||
/// @brief Subscribe an emitter
|
/// @brief Subscribe an emitter
|
||||||
/// @param em Emitter to add
|
/// @param em Emitter to add
|
||||||
|
@ -118,7 +105,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() const { return &sink; }
|
decltype(messages) const& GetSink() const { return messages; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An emitter to produce human readable output for a log sink.
|
/// An emitter to produce human readable output for a log sink.
|
||||||
|
@ -150,7 +137,7 @@ public:
|
||||||
/// Generates a message and submits it to the log sink.
|
/// Generates a message and submits it to the log sink.
|
||||||
class Message {
|
class Message {
|
||||||
std::ostrstream msg;
|
std::ostrstream msg;
|
||||||
SinkMessage *sm;
|
SinkMessage sm;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Message(const char *section, Severity severity, const char *file, const char *func, int line);
|
Message(const char *section, Severity severity, const char *file, const char *func, int line);
|
||||||
|
|
|
@ -57,15 +57,15 @@ public:
|
||||||
EmitLog(wxTextCtrl *t)
|
EmitLog(wxTextCtrl *t)
|
||||||
: text_ctrl(t)
|
: text_ctrl(t)
|
||||||
{
|
{
|
||||||
const agi::log::Sink *sink = agi::log::log->GetSink();
|
for (auto sm : agi::log::log->GetSink())
|
||||||
for_each(sink->begin(), sink->end(), std::bind(&EmitLog::log, this, std::placeholders::_1));
|
log(&sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void log(agi::log::SinkMessage *sm) {
|
void log(agi::log::SinkMessage *sm) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
tm tmtime;
|
tm tmtime;
|
||||||
localtime_r(&sm->tv.tv_sec, &tmtime);
|
localtime_r(&sm->tv.tv_sec, &tmtime);
|
||||||
wxString log = wxString::Format("%c %02d:%02d:%02d %-6ld <%-25s> [%s:%s:%d] %s\n",
|
auto log = wxString::Format("%c %02d:%02d:%02d %-6ld <%-25s> [%s:%s:%d] %s\n",
|
||||||
agi::log::Severity_ID[sm->severity],
|
agi::log::Severity_ID[sm->severity],
|
||||||
(int)tmtime.tm_hour,
|
(int)tmtime.tm_hour,
|
||||||
(int)tmtime.tm_min,
|
(int)tmtime.tm_min,
|
||||||
|
@ -77,7 +77,7 @@ public:
|
||||||
sm->line,
|
sm->line,
|
||||||
to_wx(sm->message));
|
to_wx(sm->message));
|
||||||
#else
|
#else
|
||||||
wxString log = wxString::Format("%c %-6ld <%-25s> [%s:%s:%d] %s\n",
|
auto log = wxString::Format("%c %-6ld <%-25s> [%s:%s:%d] %s\n",
|
||||||
agi::log::Severity_ID[sm->severity],
|
agi::log::Severity_ID[sm->severity],
|
||||||
sm->tv.tv_usec,
|
sm->tv.tv_usec,
|
||||||
sm->section,
|
sm->section,
|
||||||
|
|
Loading…
Reference in a new issue