Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log levels #1208

Merged
merged 5 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions loader/resources/mod.json.in
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,21 @@
],
"requires-restart": true
},
"console-log-level": {
"type": "string",
"default": "info",
"name": "Console Log Level",
"description": "Sets the log level for the <cb>platform console</c>.",
"platforms": ["win", "mac"],
"one-of": ["debug", "info", "warn", "error"]
},
"file-log-level": {
"type": "string",
"default": "info",
"name": "File Log Level",
"description": "Sets the log level for the <cb>log files</c>.",
"one-of": ["debug", "info", "warn", "error"]
},
"server-cache-size-limit": {
"type": "int",
"default": 20,
Expand Down
5 changes: 4 additions & 1 deletion loader/src/load.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ bool safeModeCheck() {
int geodeEntry(void* platformData) {
thread::setName("Main");

log::Logger::get()->setup();
console::setup();
if (LoaderImpl::get()->isForwardCompatMode()) {
console::openIfClosed();
Expand Down Expand Up @@ -152,6 +151,10 @@ int geodeEntry(void* platformData) {
}
}

// Setup logger here so that internal mod is setup and we can read log level
// Logging before this point does store the log, and everything gets logged in this setup call
log::Logger::get()->setup();

tryShowForwardCompat();

// open console
Expand Down
56 changes: 28 additions & 28 deletions loader/src/loader/LoaderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,28 +80,28 @@ Result<> Loader::Impl::setup() {
}

if (this->supportsLaunchArguments()) {
log::debug("Loading launch arguments");
log::info("Loading launch arguments");
log::NestScope nest;
this->initLaunchArguments();
}

// on some platforms, using the crash handler overrides more convenient native handlers
if (!this->getLaunchFlag("disable-crash-handler")) {
log::debug("Setting up crash handler");
log::info("Setting up crash handler");
log::NestScope nest;
if (!crashlog::setupPlatformHandler()) {
log::debug("Failed to set up crash handler");
}
} else {
log::debug("Crash handler setup skipped");
log::info("Crash handler setup skipped");
}

log::debug("Loading hooks");
log::info("Loading hooks");
if (log::NestScope nest; !this->loadHooks()) {
return Err("There were errors loading some hooks, see console for details");
}

log::debug("Setting up directories");
log::info("Setting up directories");
{
log::NestScope nest;
this->createDirectories();
Expand All @@ -112,6 +112,7 @@ Result<> Loader::Impl::setup() {
// this function is already on the gd thread, so this should be fine
ModStateEvent(Mod::get(), ModEventType::Loaded).post();

log::info("Refreshing mod graph");
this->refreshModGraph();

m_isSetup = true;
Expand Down Expand Up @@ -405,18 +406,18 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
}

if (node->hasUnresolvedDependencies()) {
log::debug("{} {} has unresolved dependencies", node->getID(), node->getVersion());
log::warn("{} {} has unresolved dependencies", node->getID(), node->getVersion());
return;
}
if (node->hasUnresolvedIncompatibilities()) {
log::debug("{} {} has unresolved incompatibilities", node->getID(), node->getVersion());
log::warn("{} {} has unresolved incompatibilities", node->getID(), node->getVersion());
return;
}

log::NestScope nest;

if (node->isEnabled()) {
log::warn("Mod {} already loaded, this should never happen", node->getID());
log::error("Mod {} already loaded, this should never happen", node->getID());
return;
}

Expand All @@ -426,16 +427,14 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
m_lateRefreshedModCount += early ? 0 : 1;

auto unzipFunction = [this, node]() {
log::debug("Unzip");
log::NestScope nest;
log::debug("Unzipping .geode file");
auto res = node->m_impl->unzipGeodeFile(node->getMetadata());
return res;
};

auto loadFunction = [this, node, early]() {
if (node->shouldLoad()) {
log::debug("Load");
log::NestScope nest;
log::debug("Loading binary");
auto res = node->m_impl->loadBinary();
if (!res) {
this->addProblem({
Expand Down Expand Up @@ -513,7 +512,7 @@ void Loader::Impl::findProblems() {
continue;
}
if (mod->targetsOutdatedVersion()) {
log::debug("{} is outdated", id);
log::warn("{} is outdated", id);
continue;
}
log::debug("{}", id);
Expand All @@ -536,7 +535,7 @@ void Loader::Impl::findProblems() {
log::info("{} suggests {} {}", id, dep.id, dep.version);
}
else {
log::info("{} suggests {} {}, but that suggestion was dismissed", id, dep.id, dep.version);
log::debug("{} suggests {} {}, but that suggestion was dismissed", id, dep.id, dep.version);
}
break;
case ModMetadata::Dependency::Importance::Recommended:
Expand All @@ -546,10 +545,10 @@ void Loader::Impl::findProblems() {
mod,
fmt::format("{} {}", dep.id, dep.version.toString())
});
log::warn("{} recommends {} {}", id, dep.id, dep.version);
log::info("{} recommends {} {}", id, dep.id, dep.version);
}
else {
log::warn("{} recommends {} {}, but that suggestion was dismissed", id, dep.id, dep.version);
log::debug("{} recommends {} {}, but that suggestion was dismissed", id, dep.id, dep.version);
}
break;
case ModMetadata::Dependency::Importance::Required:
Expand Down Expand Up @@ -648,7 +647,6 @@ void Loader::Impl::findProblems() {
}

void Loader::Impl::refreshModGraph() {
log::info("Refreshing mod graph");
log::NestScope nest;

if (m_isSetup) {
Expand All @@ -661,52 +659,54 @@ void Loader::Impl::refreshModGraph() {
m_problems.clear();

m_loadingState = LoadingState::Queue;
log::debug("Queueing mods");
log::info("Queueing mods");
std::vector<ModMetadata> modQueue;
{
log::NestScope nest;
this->queueMods(modQueue);
}

m_loadingState = LoadingState::List;
log::debug("Populating mod list");
log::info("Populating mod list");
{
log::NestScope nest;
this->populateModList(modQueue);
modQueue.clear();
}

m_loadingState = LoadingState::Graph;
log::debug("Building mod graph");
log::info("Building mod graph");
{
log::NestScope nest;
this->buildModGraph();
}

log::debug("Ordering mod stack");
log::info("Ordering mod stack");
{
log::NestScope nest;
this->orderModStack();
}

m_loadingState = LoadingState::EarlyMods;
log::debug("Loading early mods");
log::info("Loading early mods");
{
log::NestScope nest;
while (!m_modsToLoad.empty() && m_modsToLoad.front()->needsEarlyLoad()) {
auto mod = m_modsToLoad.front();
m_modsToLoad.pop_front();
log::info("Loading mod {} {}", mod->getID(), mod->getVersion());
this->loadModGraph(mod, true);
}
}

auto end = std::chrono::high_resolution_clock::now();
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
log::info("Took {}s. Continuing next frame...", static_cast<float>(time) / 1000.f);
log::debug("Took {}s. Continuing next frame...", static_cast<float>(time) / 1000.f);

m_loadingState = LoadingState::Mods;

queueInMainThread([this]() {
log::info("Loading non-early mods");
this->continueRefreshModGraph();
});
}
Expand Down Expand Up @@ -769,10 +769,10 @@ void Loader::Impl::continueRefreshModGraph() {
if (m_lateRefreshedModCount > 0) {
auto end = std::chrono::high_resolution_clock::now();
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - m_timerBegin).count();
log::info("Took {}s", static_cast<float>(time) / 1000.f);
log::debug("Took {}s", static_cast<float>(time) / 1000.f);
}

log::info("Continuing mod graph refresh...");
log::debug("Continuing mod graph refresh...");
log::NestScope nest;

m_timerBegin = std::chrono::high_resolution_clock::now();
Expand All @@ -782,14 +782,14 @@ void Loader::Impl::continueRefreshModGraph() {
if (!m_modsToLoad.empty()) {
auto mod = m_modsToLoad.front();
m_modsToLoad.pop_front();
log::debug("Loading mod {} {}", mod->getID(), mod->getVersion());
log::info("Loading mod {} {}", mod->getID(), mod->getVersion());
this->loadModGraph(mod, false);
break;
}
m_loadingState = LoadingState::Problems;
[[fallthrough]];
case LoadingState::Problems:
log::debug("Finding problems");
log::info("Finding problems");
{
log::NestScope nest;
this->findProblems();
Expand All @@ -798,7 +798,7 @@ void Loader::Impl::continueRefreshModGraph() {
{
auto end = std::chrono::high_resolution_clock::now();
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - m_timerBegin).count();
log::info("Took {}s", static_cast<float>(time) / 1000.f);
log::debug("Took {}s", static_cast<float>(time) / 1000.f);
}
break;
default:
Expand Down
64 changes: 62 additions & 2 deletions loader/src/loader/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
#include "LogImpl.hpp"

#include <Geode/loader/Dirs.hpp>
#include <Geode/loader/Loader.hpp>
#include <Geode/loader/Log.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/loader/Types.hpp>
#include <Geode/utils/casts.hpp>
#include <Geode/utils/general.hpp>
#include <fmt/chrono.h>
Expand Down Expand Up @@ -216,6 +218,10 @@ Logger* Logger::get() {
}

void Logger::setup() {
if (m_initialized) {
return;
}

auto logDir = dirs::getGeodeLogDir();

// on the first launch, this doesn't exist yet..
Expand All @@ -226,6 +232,19 @@ void Logger::setup() {

m_logPath = logDir / log::generateLogName();
m_logStream = std::ofstream(m_logPath);

// Logs can and will probably be added before setup() is called, so we'll write them now
for (Log const& log : m_logs) {
const std::string logStr = log.toString();
if (log.getSeverity() >= this->getConsoleLogLevel()) {
console::log(logStr, log.getSeverity());
}
if (log.getSeverity() >= this->getFileLogLevel()) {
m_logStream << logStr << std::endl;
}
}

m_initialized = true;
}

void Logger::deleteOldLogs(size_t maxAgeHours) {
Expand Down Expand Up @@ -260,16 +279,57 @@ std::mutex& getLogMutex() {
return mutex;
}

Severity Logger::getConsoleLogLevel() {
const std::string level = Mod::get()->getSettingValue<std::string>("console-log-level");
if (level == "debug") {
return Severity::Debug;
} else if (level == "info") {
return Severity::Info;
} else if (level == "warn") {
return Severity::Warning;
} else if (level == "error") {
return Severity::Error;
} else {
return Severity::Info;
}
}

Severity Logger::getFileLogLevel() {
const std::string level = Mod::get()->getSettingValue<std::string>("file-log-level");
if (level == "debug") {
return Severity::Debug;
} else if (level == "info") {
return Severity::Info;
} else if (level == "warn") {
return Severity::Warning;
} else if (level == "error") {
return Severity::Error;
} else {
return Severity::Info;
}
}


void Logger::push(Severity sev, std::string&& thread, std::string&& source, int32_t nestCount,
std::string&& content) {
std::lock_guard g(getLogMutex());

Log& log = m_logs.emplace_back(sev, std::move(thread), std::move(source), nestCount,
std::move(content));

// If logger is not initialized, store the log anyway. When the logger is initialized the pending logs will be logged.
if (!m_initialized) {
return;
}

auto const logStr = log.toString();
console::log(logStr, log.getSeverity());
m_logStream << logStr << std::endl;

if (sev >= this->getConsoleLogLevel()) {
console::log(logStr, log.getSeverity());
}
if (sev >= this->getFileLogLevel()) {
m_logStream << logStr << std::endl;
}
}

Nest::Nest(std::shared_ptr<Nest::Impl> impl) : m_impl(std::move(impl)) { }
Expand Down
4 changes: 4 additions & 0 deletions loader/src/loader/LogImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <Geode/DefaultInclude.hpp>
#include <Geode/loader/Log.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/loader/Types.hpp>
#include <vector>
#include <fstream>
#include <string>
Expand All @@ -29,6 +30,7 @@ namespace geode::log {

class Logger {
private:
bool m_initialized = false;
std::vector<Log> m_logs;
std::ofstream m_logStream;
std::filesystem::path m_logPath;
Expand All @@ -43,6 +45,8 @@ namespace geode::log {
std::string&& content);

std::vector<Log> const& list();
Severity getConsoleLogLevel();
Severity getFileLogLevel();
void clear();

std::filesystem::path const& getLogPath() const;
Expand Down
Loading
Loading