aboutsummaryrefslogtreecommitdiff
path: root/src/logging.cpp
diff options
context:
space:
mode:
authorGravatar Sadie Powell2024-08-23 19:10:34 +0100
committerGravatar Sadie Powell2024-08-23 19:47:58 +0100
commitd2b09b931d5c04251a5622b43666212a13232a0f (patch)
tree3f89a9f501d2fac4b4e209e2d21efda7c87f2c78 /src/logging.cpp
parentAllow building log_json against yyjson. (diff)
Close loggers and notify opers if they throw any exceptions.
Diffstat (limited to 'src/logging.cpp')
-rw-r--r--src/logging.cpp39
1 files changed, 34 insertions, 5 deletions
diff --git a/src/logging.cpp b/src/logging.cpp
index 15d81d2dd..da77af131 100644
--- a/src/logging.cpp
+++ b/src/logging.cpp
@@ -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)