Close loggers and notify opers if they throw any exceptions.

This commit is contained in:
Sadie Powell 2024-08-23 19:10:34 +01:00
parent 448c3342d9
commit d2b09b931d
2 changed files with 43 additions and 5 deletions

View File

@ -191,6 +191,9 @@ private:
/** Whether the logger was read from the server config. */
bool config;
/** Whether this logger is dead and is awaiting removal. */
bool dead = false;
/** The minimum log level that this logger accepts. */
Level level;
@ -204,6 +207,12 @@ private:
const Engine* engine;
Info(Level l, TokenList t, MethodPtr m, bool c, const Engine* e) ATTR_NOT_NULL(6);
/** Determines whether a message of the specified level and type should be written to this logger.
* @param l The level to check
* @param t The type to check.
*/
bool Suitable(Level l, const std::string& t) const;
};
/** The log messages we have cached for modules. */

View File

@ -181,6 +181,11 @@ Log::Manager::Info::Info(Level l, TokenList t, MethodPtr m, bool c, const Engine
{
}
bool Log::Manager::Info::Suitable(Level l, const std::string& t) const
{
return level >= l && types.Contains(t) && !dead;
}
Log::Manager::Manager()
: filelog(nullptr)
, stderrlog(nullptr, "stderr", stderr)
@ -262,15 +267,27 @@ void Log::Manager::OpenLogs(bool requiremethods)
if (requiremethods && caching)
{
// The server has finished starting up so we can write out any cached log messages.
for (const auto& logger : loggers)
for (auto& logger : loggers)
{
if (!logger.method->AcceptsCachedMessages())
if (logger.dead || !logger.method->AcceptsCachedMessages())
continue; // Does not support logging.
for (const auto& message : cache)
{
if (logger.level >= message.level && logger.types.Contains(message.type))
if (!logger.Suitable(message.level, message.type))
continue;
try
{
logger.method->OnLog(message.time, message.level, message.type, message.message);
}
catch (const CoreException& err)
{
logger.dead = true;
logger.method.reset();
ServerInstance->SNO.WriteGlobalSno('a', "A logger threw an exception: {}", err.GetReason());
break;
}
}
}
@ -308,10 +325,22 @@ void Log::Manager::Write(Level level, const std::string& type, const std::string
logging = true;
time_t time = ServerInstance->Time();
for (const auto& logger : loggers)
for (auto& logger : loggers)
{
if (logger.level >= level && logger.types.Contains(type))
if (!logger.Suitable(level, type))
continue;
try
{
logger.method->OnLog(time, level, type, message);
}
catch (const CoreException& err)
{
logger.dead = true;
logger.method.reset();
ServerInstance->SNO.WriteGlobalSno('a', "A logger threw an exception: {}", err.GetReason());
break;
}
}
if (caching)