Logging lightweight as paper
- Ideally source location
- Template log calls
- Backtrace logging
- Better consumer thread usage for logging to file (?)
- Print
\n
nicely - Ensure support for logging ustrings
- Flush needs to happen before crash (perhaps signal handler?, Less important)
- Support for logging things that are c# instances by logging pointer value then calling to string (in bs-hooks)
Paper makes use of fmt, which has many optional formatters and features that are supported out of the box.
By default, Paper will log write all logs in global context (which includes the global log file)
/sdcard/Android/data/com.beatgames.beatsaber/files/logs/paper/PaperLog.log
The basics are straightforward:
#include "paper/shared/logger.hpp"
Paper::Logger::fmtLog<Paper::LogLevel::INF>("hi! {}", 5); // hi 5
Paper::Logger::fmtLog<Paper::LogLevel::WRN>("Another log! {1} name {0}", "foo", "my"); // Another log! my name foo
Paper::Logger::fmtThrowError<std::runtime_error>("Some error {}", "bad data"); // Throws an exception and logs before
To tag your logs and have a filtered log file. The context can be stored in static memory; that is to say, outside a function and instance field declaration.
// by default, it creates a log file specific to `PaperFast` logs,
// named `PaperFast.log` in the same directory
auto fastContext = Paper::Logger::WithContext<"PaperFast">();
fastContext.fmtLog<Paper::LogLevel::INF>("Paper is so cool!");
auto noFileContext = Paper::Logger::WithContext<"NoFile", false>();
noFileContext.fmtLog<Paper::LogLevel::INF>("Only logs to logcat");
You can manually log a context or register a context to log to files with the following
Paper::Logger::RegisterFileContextId("context", "log file path relative to log folder")
Paper::Logger::fmtLogTag("log", "context", args...);
Paper::Logger::Backtrace(20);
myContext.Backtrace(20);
Paper includes a rudimentary basic profiler which you can use to measure the latency of certain areas of your program.
Paper::Profiler<std::chrono::nanoseconds> profiler;
profiler.suffix = "ns";
someExpensiveComputation();
profiler.mark("Expensive computation 1");
someExpensiveComputation2();
profiler.mark("Expensive computation 1");
profiler.printMarks();
Paper supports sinks. This one's for you Laurie
Paper::Logger::AddLogSink([](ThreadData const& data, std::string_view fmtMessage) {
});
Paperlog does not depend on Android or ARM to work, which means testing.
Tested on Linux Pop! OS 22.04 with clang-15
and libstdc++-12-dev
, use pwsh ./build_desktop.ps1