#pragma once #include "foundation/result.h" #include #include #include #include namespace pp::foundation { enum class LogLevel : std::uint8_t { trace, debug, info, warning, error, }; struct LogRecord { LogLevel level = LogLevel::info; std::string component; std::string message; std::uint64_t frame_id = 0; std::uint64_t stroke_id = 0; std::uint64_t thread_id = 0; }; class ILogSink { public: virtual ~ILogSink() = default; virtual void write(const LogRecord& record) noexcept = 0; }; class Logger { public: explicit Logger(ILogSink& sink) noexcept; void set_min_level(LogLevel level) noexcept; [[nodiscard]] LogLevel min_level() const noexcept; [[nodiscard]] Status write( LogLevel level, std::string_view component, std::string_view message, std::uint64_t frame_id = 0, std::uint64_t stroke_id = 0, std::uint64_t thread_id = 0) noexcept; private: ILogSink* sink_ = nullptr; LogLevel min_level_ = LogLevel::trace; }; class MemoryLogSink final : public ILogSink { public: void write(const LogRecord& record) noexcept override; [[nodiscard]] const std::vector& records() const noexcept; void clear() noexcept; private: std::vector records_; }; [[nodiscard]] const char* log_level_name(LogLevel level) noexcept; }