// Copyright Epic Games, Inc. All Rights Reserved. #if ZEN_WITH_TRACE # include # include # include # include # include # define TRACE_IMPLEMENT 1 # include # include namespace zen { void TraceConfigure() { // Configure channels based on command line options using namespace std::literals; constexpr std::string_view TraceOption = "--trace="sv; std::function ProcessChannelList; auto ProcessTraceArg = [&](const std::string_view& Arg) { if (Arg == "default"sv) { ProcessChannelList("cpu,log"sv); } else if (Arg == "memory"sv) { ProcessChannelList("memtag,memalloc,callstack,module"sv); } else if (Arg == "memory_light"sv) { ProcessChannelList("memtag,memalloc"sv); } else if (Arg == "memtag"sv) { // memtag actually traces to the memalloc channel ProcessChannelList("memalloc"sv); } else { // Presume that the argument is a trace channel name StringBuilder<128> AnsiChannel; AnsiChannel << Arg; const bool IsEnabled = trace::ToggleChannel(AnsiChannel.c_str(), true); if (IsEnabled == false) { // Logging here could be iffy, but we might want some other feedback mechanism here // to indicate to users that they're not getting what they might be expecting } } }; ProcessChannelList = [&](const std::string_view& OptionArgs) { IterateCommaSeparatedValue(OptionArgs, ProcessTraceArg); }; bool TraceOptionPresent = false; std::function ProcessArg = [&](const std::string_view& Arg) { if (Arg.starts_with(TraceOption)) { const std::string_view OptionArgs = Arg.substr(TraceOption.size()); TraceOptionPresent = true; ProcessChannelList(OptionArgs); } }; IterateCommandlineArgs(ProcessArg); if (!TraceOptionPresent) { ProcessTraceArg("default"sv); } } void TraceInit(std::string_view ProgramName) { static std::atomic_bool gInited = false; bool Expected = false; if (!gInited.compare_exchange_strong(Expected, true)) { return; } trace::FInitializeDesc Desc = { .bUseImportantCache = true, }; trace::Initialize(Desc); # if ZEN_PLATFORM_WINDOWS const char* CommandLineString = GetCommandLineA(); # else const char* CommandLineString = ""; # endif trace::ThreadRegister("main", /* system id */ 0, /* sort id */ 0); trace::DescribeSession(ProgramName, # if ZEN_BUILD_DEBUG trace::Build::Debug, # else trace::Build::Development, # endif CommandLineString, ZEN_CFG_VERSION_BUILD_STRING); atexit([] { # if ZEN_WITH_MEMTRACK zen::MemoryTrace_Shutdown(); # endif trace::Update(); TraceShutdown(); }); TraceConfigure(); } void TraceShutdown() { (void)TraceStop(); trace::Shutdown(); } bool IsTracing() { return trace::IsTracing(); } void TraceStart(std::string_view ProgramName, const char* HostOrPath, TraceType Type) { TraceInit(ProgramName); switch (Type) { case TraceType::Network: trace::SendTo(HostOrPath); break; case TraceType::File: trace::WriteTo(HostOrPath); break; case TraceType::None: break; } } bool TraceStop() { if (trace::Stop()) { return true; } return false; } } // namespace zen #endif // ZEN_WITH_TRACE