Files
UnrealEngine/Engine/Source/Programs/UnrealBuildAccelerator/Common/Public/UbaLogger.h
2025-05-18 13:04:45 +08:00

125 lines
3.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "UbaLogWriter.h"
#include "UbaMemory.h"
#include <stdarg.h>
#define UBA_DEBUG_LOGGER 0
#define UBA_LOG_STALLS 0
namespace uba
{
class StringBufferBase;
struct BinaryReader;
struct StringView;
using TraverseThreadErrorFunc = Function<void(const StringView& error)>;
struct LogEntry
{
LogEntryType type;
const tchar* string;
};
class Logger
{
public:
Logger() {}
bool Error(const tchar* format, ...);
bool Warning(const tchar* format, ...);
Logger& Info(const tchar* format, ...);
Logger& Detail(const tchar* format, ...);
Logger& Debug(const tchar* format, ...);
void Logf(LogEntryType type, const tchar* format, ...);
void LogArg(LogEntryType type, const tchar* format, va_list& args);
void Log(LogEntryType type, const StringView& str);
virtual void BeginScope() = 0;
virtual void EndScope() = 0;
virtual void Log(LogEntryType type, const tchar* str, u32 strLen) = 0;
virtual ~Logger() {}
bool ToFalse() { return false; }
};
class LoggerWithWriter : public Logger
{
public:
LoggerWithWriter(LogWriter& writer, const tchar* prefix = nullptr);
virtual void BeginScope() { m_writer.BeginScope(); }
virtual void EndScope() { m_writer.EndScope(); }
virtual void Log(LogEntryType type, const tchar* str, u32 strLen) { m_writer.Log(type, str, strLen, m_prefix, m_prefixLen); }
using Logger::Log;
LogWriter& m_writer;
const tchar* m_prefix;
u32 m_prefixLen;
};
struct MutableLogger : public LoggerWithWriter
{
MutableLogger(LogWriter& writer, const tchar* prefix) : LoggerWithWriter(writer, prefix) {}
virtual void Log(LogEntryType type, const tchar* str, u32 strLen) override { if (!isMuted) LoggerWithWriter::Log(type, str, strLen); }
using LoggerWithWriter::Log;
Atomic<u32> isMuted;
};
class FilteredLogWriter : public LogWriter
{
public:
FilteredLogWriter(LogWriter& writer, LogEntryType level = LogEntryType_Detail) : m_writer(writer), m_level(level) {}
virtual void BeginScope() override { m_writer.BeginScope(); }
virtual void EndScope() override { m_writer.EndScope(); }
virtual void Log(LogEntryType type, const tchar* str, u32 strLen, const tchar* prefix = nullptr, u32 prefixLen = 0) override;
private:
LogWriter& m_writer;
LogEntryType m_level;
};
struct BytesToText
{
BytesToText(u64 bytes);
operator const tchar* () const { return str; };
tchar str[32];
};
struct CountToText
{
CountToText(u64 count);
operator const tchar* () const { return str; };
tchar str[32];
};
#if UBA_DEBUG_LOGGER
Logger* StartDebugLogger(Logger& outerLogger, const tchar* fileName);
Logger* StopDebugLogger(Logger* logger);
#endif
void ParseCallstackInfo(StringBufferBase& out, BinaryReader& reader, const tchar* executable, const StringView* searchPaths);
void PrintContentionSummary(class Logger& logger);
struct CallstackInfo { Vector<u8> data; Vector<u32> threadIds; TString desc; };
void TraverseAllCallstacks(const Function<void(const CallstackInfo&)>& func, const TraverseThreadErrorFunc& errorFunc);
void PrintAllCallstacks(Logger& logger);
struct LogStallScope
{
LogStallScope(Logger& logger, LogEntryType type, u64 timeSeconds, const tchar* messageFormat);
~LogStallScope();
void Leave();
Logger& logger;
LogEntryType type;
u64 timeSeconds;
u64 timeStart;
const tchar* messageFormat;
};
#if UBA_LOG_STALLS
#define LOG_STALL_SCOPE(logger, timeSeconds, messageFormat) LogStallScope lss(logger, LogEntryType_Error, timeSeconds, messageFormat);
#else
#define LOG_STALL_SCOPE(logger, timeSeconds, messageFormat)
#endif
}