Use a circular buffer to store only the last 250 log messages

This commit is contained in:
Thomas Goyne 2013-01-23 10:41:28 -08:00
parent c6005be4a1
commit a942687050
3 changed files with 21 additions and 43 deletions

View file

@ -30,7 +30,6 @@
#include <boost/filesystem/fstream.hpp>
#include <boost/range/algorithm.hpp>
#include <cstring>
#include <fstream>
#include <functional>
namespace agi {
@ -43,30 +42,17 @@ LogSink *log;
/// Keep this ordered the same as Severity
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() {
// 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);
util::delete_clear(sink);
}
void LogSink::log(SinkMessage *sm) {
sink.push_back(sm);
boost::for_each(emitters, [=](Emitter *em) { em->log(sm); });
void LogSink::Log(SinkMessage const& sm) {
messages.push_back(sm);
boost::for_each(emitters, [=](Emitter *em) { em->log(&messages.back()); });
}
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)
: 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() {
sm->message = std::string(msg.str(), (std::string::size_type)msg.pcount());
agi::log::log->log(sm);
sm.message = std::string(msg.str(), (std::string::size_type)msg.pcount());
agi::log::log->Log(sm);
msg.freeze(false);
}

View file

@ -20,7 +20,7 @@
#include <libaegisub/time.h>
#include <ctime>
#include <deque>
#include <boost/circular_buffer.hpp>
#include <iosfwd>
#include <memory>
#include <vector>
@ -68,15 +68,6 @@ extern LogSink *log;
/// Container to hold a single message
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
Severity severity; ///< Severity
const char *file; ///< Source file
@ -88,23 +79,19 @@ struct SinkMessage {
class Emitter;
/// Message sink for holding all messages
typedef std::deque<SinkMessage*> Sink;
/// Log sink, single destination for all messages
class LogSink {
/// Log sink
Sink sink;
boost::circular_buffer<SinkMessage> messages;
/// List of pointers to emitters
std::vector<Emitter*> emitters;
public:
/// Destructor
LogSink() : messages(250) { }
~LogSink();
/// Insert a message into the sink.
void log(SinkMessage *sm);
void Log(SinkMessage const& sm);
/// @brief Subscribe an emitter
/// @param em Emitter to add
@ -118,7 +105,7 @@ public:
/// @brief @get the complete (current) log.
/// @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.
@ -150,7 +137,7 @@ public:
/// Generates a message and submits it to the log sink.
class Message {
std::ostrstream msg;
SinkMessage *sm;
SinkMessage sm;
public:
Message(const char *section, Severity severity, const char *file, const char *func, int line);

View file

@ -57,15 +57,15 @@ public:
EmitLog(wxTextCtrl *t)
: text_ctrl(t)
{
const agi::log::Sink *sink = agi::log::log->GetSink();
for_each(sink->begin(), sink->end(), std::bind(&EmitLog::log, this, std::placeholders::_1));
for (auto sm : agi::log::log->GetSink())
log(&sm);
}
void log(agi::log::SinkMessage *sm) {
#ifndef _WIN32
tm 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],
(int)tmtime.tm_hour,
(int)tmtime.tm_min,
@ -77,7 +77,7 @@ public:
sm->line,
to_wx(sm->message));
#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],
sm->tv.tv_usec,
sm->section,