// Copyright Epic Games, Inc. All Rights Reserved. #include #include #include namespace zen::logging { struct Logger::Impl { std::string m_Name; SinkPtr m_Sink; ErrorHandler* m_ErrorHandler = nullptr; }; Logger::Logger(std::string_view InName, SinkPtr InSink) : m_Impl(std::make_unique()) { m_Impl->m_Name = InName; m_Impl->m_Sink = std::move(InSink); } Logger::~Logger() = default; void Logger::Log(const LogPoint& Point, fmt::format_args Args) { if (!ShouldLog(Point.Level)) { return; } fmt::basic_memory_buffer Buffer; fmt::vformat_to(fmt::appender(Buffer), Point.FormatString, Args); LogMessage LogMsg(Point, m_Impl->m_Name, std::string_view(Buffer.data(), Buffer.size())); LogMsg.SetThreadId(GetCurrentThreadId()); SinkIt(LogMsg); FlushIfNeeded(Point.Level); } void Logger::SinkIt(const LogMessage& Msg) { if (m_Impl->m_Sink && m_Impl->m_Sink->ShouldLog(Msg.GetLevel())) { try { m_Impl->m_Sink->Log(Msg); } catch (const std::exception& Ex) { if (m_Impl->m_ErrorHandler) { m_Impl->m_ErrorHandler->HandleError(Ex.what()); } } } } void Logger::FlushIfNeeded(LogLevel InLevel) { if (InLevel >= m_FlushLevel.load(std::memory_order_relaxed)) { Flush(); } } void Logger::Flush() { if (m_Impl->m_Sink) { try { m_Impl->m_Sink->Flush(); } catch (const std::exception& Ex) { if (m_Impl->m_ErrorHandler) { m_Impl->m_ErrorHandler->HandleError(Ex.what()); } } } } void Logger::SetSink(SinkPtr InSink) { m_Impl->m_Sink = std::move(InSink); } void Logger::SetErrorHandler(ErrorHandler* Handler) { m_Impl->m_ErrorHandler = Handler; } void Logger::SetFormatter(std::unique_ptr InFormatter) { if (m_Impl->m_Sink) { m_Impl->m_Sink->SetFormatter(std::move(InFormatter)); } } std::string_view Logger::Name() const { return m_Impl->m_Name; } Ref Logger::Clone(std::string_view NewName) const { Ref Cloned(new Logger(NewName, m_Impl->m_Sink)); Cloned->SetLevel(m_Level.load(std::memory_order_relaxed)); Cloned->SetFlushLevel(m_FlushLevel.load(std::memory_order_relaxed)); Cloned->SetErrorHandler(m_Impl->m_ErrorHandler); return Cloned; } } // namespace zen::logging