From 8b42ed4b6e995ac0336d1abe6425cfadf239f8d2 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 22 Apr 2026 12:35:46 +0200 Subject: Zen-style trace log events (#1006) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the old (not fully implemented) UE `Logging.*` sink with a typed `ZenLog.*` trace path that preserves structured fmt args end-to-end, so the zen trace analyzer (and future consumers) can re-render log messages with full formatter support. - Hook `Logger::Log` to tap `fmt::format_args` before `vformat` renders them, and emit three new events on a dedicated `ZenLogChannel`: `Category`, `MessageSpec`, `Message`. Args are serialized as `[count][descriptors][payload]` with distinct categories for bool, int, float, and string. Custom formatters fall back to a pre-rendered string. - Bool has its own wire category so `{}` renders as `true`/`false` and `{:d}` as `1`/`0`. - Zen `LogLevel` is translated to UE `ELogVerbosity` on emit so severity filtering works consistently. - Extend the zen trace analyzer to decode `ZenLog.*` via `fmt::vformat` + `dynamic_format_arg_store` — nested widths, chrono specs, etc. all work. Strings are passed as views directly from the event payload (which outlives the format call) rather than copied through a pool. - Retire the old `TraceSink` stub; the typed path supersedes it. - Switch `--trace=default` alias from `cpu,log` to `cpu,zenlog`. - Add `__int128` overloads to the arg encoder guarded by `FMT_USE_INT128` so fmt's int128 dispatch resolves unambiguously on clang/gcc. MSVC and clang-cl are unaffected. --- src/zencore/logging/tracesink.cpp | 92 --------------------------------------- 1 file changed, 92 deletions(-) delete mode 100644 src/zencore/logging/tracesink.cpp (limited to 'src/zencore/logging/tracesink.cpp') diff --git a/src/zencore/logging/tracesink.cpp b/src/zencore/logging/tracesink.cpp deleted file mode 100644 index 8a6f4e40c..000000000 --- a/src/zencore/logging/tracesink.cpp +++ /dev/null @@ -1,92 +0,0 @@ - -// Copyright Epic Games, Inc. All Rights Reserved. - -#include -#include -#include -#include -#include - -#if ZEN_WITH_TRACE - -namespace zen::logging { - -UE_TRACE_CHANNEL_DEFINE(LogChannel) - -UE_TRACE_EVENT_BEGIN(Logging, LogCategory, NoSync | Important) - UE_TRACE_EVENT_FIELD(const void*, CategoryPointer) - UE_TRACE_EVENT_FIELD(uint8_t, DefaultVerbosity) - UE_TRACE_EVENT_FIELD(UE::Trace::AnsiString, Name) -UE_TRACE_EVENT_END() - -UE_TRACE_EVENT_BEGIN(Logging, LogMessageSpec, NoSync | Important) - UE_TRACE_EVENT_FIELD(const void*, LogPoint) - UE_TRACE_EVENT_FIELD(const void*, CategoryPointer) - UE_TRACE_EVENT_FIELD(int32_t, Line) - UE_TRACE_EVENT_FIELD(uint8_t, Verbosity) - UE_TRACE_EVENT_FIELD(UE::Trace::AnsiString, FileName) - UE_TRACE_EVENT_FIELD(UE::Trace::AnsiString, FormatString) -UE_TRACE_EVENT_END() - -UE_TRACE_EVENT_BEGIN(Logging, LogMessage, NoSync) - UE_TRACE_EVENT_FIELD(const void*, LogPoint) - UE_TRACE_EVENT_FIELD(uint64_t, Cycle) - UE_TRACE_EVENT_FIELD(uint8_t[], FormatArgs) -UE_TRACE_EVENT_END() - -void -TraceLogCategory(const logging::Logger* Category, const char* Name, logging::LogLevel DefaultVerbosity) -{ - uint16_t NameLen = uint16_t(strlen(Name)); - UE_TRACE_LOG(Logging, LogCategory, LogChannel, NameLen * sizeof(ANSICHAR)) - << LogCategory.CategoryPointer(Category) << LogCategory.DefaultVerbosity(uint8_t(DefaultVerbosity)) - << LogCategory.Name(Name, NameLen); -} - -void -TraceLogMessageSpec(const void* LogPoint, - const logging::Logger* Category, - logging::LogLevel Verbosity, - const std::string_view File, - int32_t Line, - const std::string_view Format) -{ - uint16_t FileNameLen = uint16_t(File.size()); - uint16_t FormatStringLen = uint16_t(Format.size()); - uint32_t DataSize = (FileNameLen * sizeof(ANSICHAR)) + (FormatStringLen * sizeof(ANSICHAR)); - UE_TRACE_LOG(Logging, LogMessageSpec, LogChannel, DataSize) - << LogMessageSpec.LogPoint(LogPoint) << LogMessageSpec.CategoryPointer(Category) << LogMessageSpec.Line(Line) - << LogMessageSpec.Verbosity(uint8_t(Verbosity)) << LogMessageSpec.FileName(File.data(), FileNameLen) - << LogMessageSpec.FormatString(Format.data(), FormatStringLen); -} - -void -TraceLogMessageInternal(const void* LogPoint, int32_t EncodedFormatArgsSize, const uint8_t* EncodedFormatArgs) -{ - UE_TRACE_LOG(Logging, LogMessage, LogChannel) << LogMessage.LogPoint(LogPoint) << LogMessage.Cycle(GetHifreqTimerValue()) - << LogMessage.FormatArgs(EncodedFormatArgs, EncodedFormatArgsSize); -} - -////////////////////////////////////////////////////////////////////////// - -void -TraceSink::Log(const LogMessage& Msg) -{ - ZEN_UNUSED(Msg); -} - -void -TraceSink::Flush() -{ -} - -void -TraceSink::SetFormatter(std::unique_ptr /*InFormatter*/) -{ - // This sink doesn't use a formatter since it just forwards the raw format - // args to the trace system -} - -} // namespace zen::logging - -#endif -- cgit v1.2.3