102 lines
2.3 KiB
C++
102 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <chrono>
|
|
#include <condition_variable>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <deque>
|
|
#include <fstream>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <thread>
|
|
|
|
namespace RenderCadenceCompositor
|
|
{
|
|
enum class LogLevel
|
|
{
|
|
Log,
|
|
Warning,
|
|
Error
|
|
};
|
|
|
|
struct LoggerConfig
|
|
{
|
|
LogLevel minimumLevel = LogLevel::Log;
|
|
bool writeToConsole = true;
|
|
bool writeToDebugOutput = true;
|
|
bool writeToFile = true;
|
|
std::string filePath = "logs/render-cadence-compositor.log";
|
|
std::size_t maxQueuedMessages = 1024;
|
|
};
|
|
|
|
struct LoggerCounters
|
|
{
|
|
uint64_t queued = 0;
|
|
uint64_t written = 0;
|
|
uint64_t dropped = 0;
|
|
};
|
|
|
|
const char* LogLevelName(LogLevel level);
|
|
|
|
class Logger
|
|
{
|
|
public:
|
|
struct Record
|
|
{
|
|
std::chrono::system_clock::time_point timestamp;
|
|
std::thread::id threadId;
|
|
LogLevel level = LogLevel::Log;
|
|
std::string subsystem;
|
|
std::string message;
|
|
};
|
|
|
|
static Logger& Instance();
|
|
|
|
Logger(const Logger&) = delete;
|
|
Logger& operator=(const Logger&) = delete;
|
|
|
|
~Logger();
|
|
|
|
void Start(LoggerConfig config = LoggerConfig());
|
|
void Stop();
|
|
|
|
void Write(LogLevel level, const std::string& subsystem, const std::string& message);
|
|
bool TryWrite(LogLevel level, const std::string& subsystem, const std::string& message);
|
|
|
|
void Log(const std::string& subsystem, const std::string& message);
|
|
void Warning(const std::string& subsystem, const std::string& message);
|
|
void Error(const std::string& subsystem, const std::string& message);
|
|
|
|
LoggerCounters Counters() const;
|
|
bool IsRunning() const;
|
|
|
|
private:
|
|
Logger() = default;
|
|
|
|
bool ShouldWrite(LogLevel level) const;
|
|
bool Enqueue(Record record, bool block);
|
|
void ThreadMain();
|
|
void WriteRecord(const Record& record);
|
|
void OpenFileSink();
|
|
void CloseFileSink();
|
|
|
|
LoggerConfig mConfig;
|
|
std::ofstream mFile;
|
|
std::thread mThread;
|
|
mutable std::mutex mMutex;
|
|
std::condition_variable mCondition;
|
|
std::deque<Record> mQueue;
|
|
bool mStopping = false;
|
|
bool mRunning = false;
|
|
|
|
mutable std::mutex mCountersMutex;
|
|
LoggerCounters mCounters;
|
|
};
|
|
|
|
bool TryLog(LogLevel level, const std::string& subsystem, const std::string& message);
|
|
void Log(const std::string& subsystem, const std::string& message);
|
|
void LogWarning(const std::string& subsystem, const std::string& message);
|
|
void LogError(const std::string& subsystem, const std::string& message);
|
|
}
|