Telemetry.h#
Fully qualified name: omni/structuredlog/Telemetry.h
File members: omni/structuredlog/Telemetry.h
// Copyright (c) 2021-2024, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#include "IStructuredLogSettings.h"
#include "../extras/UniqueApp.h"
#include "../../carb/launcher/ILauncher.h"
#include "../../carb/launcher/LauncherUtils.h"
#include "../../carb/settings/ISettings.h"
namespace omni
{
namespace telemetry
{
constexpr const char* const kStayAliveSetting = "/telemetry/stayAlive";
constexpr const char* kUploadAllAndExitSetting = "/telemetry/uploadAllAndExit";
constexpr const char* const kPollTimeSetting = "/telemetry/pollTime";
constexpr const char* const kTelemetryModeSetting = "/telemetry/mode";
constexpr const char* const kTelemetryTagSetting = "/telemetry/modeTag";
constexpr const char* const kTelemetryEnableAnonymousDataSetting = "/telemetry/enableAnonymousData";
constexpr const char* const kTelemetryDisableAnonymousDataEnvvar = "OMNI_TELEMETRY_DISABLE_ANONYMOUS_DATA";
constexpr const char* const kTelemetryRunEnvironmentSetting = "/telemetry/runEnvironment";
constexpr const char* const kAllowRootSetting = "/telemetry/allowRoot";
constexpr const char* const kRestrictedRegionsSetting = "/telemetry/restrictedRegions";
constexpr const char* const kRestrictedRegionAssumptionSetting = "/telemetry/restrictedRegionAssumption";
constexpr const char* const kLogFileSetting = "/telemetry/log/file";
constexpr const char* const kLogLevelSetting = "/telemetry/log/level";
constexpr const char* const kUseOpenEndpointSetting = "/telemetry/useOpenEndpoint";
constexpr const char* const kExtraFieldsToAddSetting = "/telemetry/extraFieldsToAdd";
constexpr const char* const kReplaceExtraFieldsSetting = "/telemetry/replaceExtraFields";
constexpr const char* const kLaunchGuardNameSetting = "/telemetry/launchGuardName";
constexpr const char* const kTransmitterSetting = "/telemetry/transmitter";
constexpr const char* const kResendEventsSettingLeaf = "resendEvents";
constexpr const char* const kTransmissionLimitSettingLeaf = "transmissionLimit";
constexpr const char* const kQueueLimitSettingLeaf = "queueLimit";
constexpr const char* const kTelemetryEndpointSettingLeaf = "endpoint";
constexpr const char* const kTelemetrySchemasUrlSettingLeaf = "schemasUrl";
constexpr const char* const kTelemetryAuthenticateSettingLeaf = "authenticate";
constexpr const char* const kTelemetryAuthTokenUrlSettingLeaf = "authTokenUrl";
constexpr const char* const kTelemetryAuthTokenKeyNameSettingLeaf = "authTokenKeyName";
constexpr const char* const kTelemetryAuthTokenExpiryNameSettingLeaf = "authTokenExpiryName";
constexpr const char* const kEventProtocolLeaf = "eventProtocol";
constexpr const char* const kSeekTagNameLeaf = "seekTagName";
constexpr const char* const kTelemetryAuthTokenTypeLeaf = "authTokenType";
constexpr const char* const kOldEventThresholdSettingLeaf = "oldEventThreshold";
constexpr const char* const kIgnoreOldEventsSettingLeaf = "ignoreOldEvents";
constexpr const char* const kPseudonymizeOldEventsSettingLeaf = "pseudonymizeOldEvents";
constexpr const char* const kRetryLimitSettingLeaf = "retryLimit";
constexpr const char* const kMessageMatchingModeLeaf = "messageMatchMode";
inline extras::UniqueApp createGuard()
{
carb::settings::ISettings* settings;
const char* guardName = "omni.telemetry.transmitter";
std::string value;
auto getGuardPath = []() -> std::string {
#if OMNI_PLATFORM_LINUX
// XDG_RUNTIME_DIR is the standard place for putting runtime IPC objects on Linux
const char* runDir = getenv("XDG_RUNTIME_DIR");
if (runDir != nullptr)
{
return runDir;
}
#endif
core::ObjectPtr<omni::structuredlog::IStructuredLog> strucLog;
core::ObjectPtr<omni::structuredlog::IStructuredLogSettings> settings;
strucLog = omni::core::borrow(omniGetStructuredLogWithoutAcquire());
if (strucLog.get() == nullptr)
{
OMNI_LOG_ERROR("failed to get IStructuredLog");
return "";
}
settings = strucLog.as<structuredlog::IStructuredLogSettings>();
if (settings.get() == nullptr)
{
OMNI_LOG_ERROR("failed to get IStructuredLogSettings");
return "";
}
return settings->getLogOutputPath();
};
settings = carb::getCachedInterface<carb::settings::ISettings>();
if (settings != nullptr && settings->isAccessibleAs(carb::dictionary::ItemType::eString, kLaunchGuardNameSetting))
{
value = carb::settings::getString(settings, kLaunchGuardNameSetting, guardName);
guardName = value.c_str();
}
return extras::UniqueApp(getGuardPath().c_str(), guardName);
}
inline std::string getTransmitterLogPath()
{
constexpr const char* kLogFileFallback = "./omni.telemetry.transmitter.log";
carb::settings::ISettings* settings = carb::getFramework()->tryAcquireInterface<carb::settings::ISettings>();
core::ObjectPtr<omni::structuredlog::IStructuredLog> strucLog =
omni::core::borrow(omniGetStructuredLogWithoutAcquire());
core::ObjectPtr<omni::structuredlog::IStructuredLogSettings> strucLogSettings;
if (settings != nullptr)
{
settings->setDefaultString(kLogFileSetting, "");
carb::cpp::optional<std::string> logFile = carb::settings::getStringOpt(settings, kLogFileSetting);
if (logFile && !logFile->empty())
return *logFile;
}
else
{
CARB_LOG_ERROR("failed to acquire ISettings");
}
if (strucLog.get() == nullptr)
{
OMNI_LOG_ERROR("failed to get IStructuredLog - using CWD");
return kLogFileFallback;
}
strucLogSettings = strucLog.as<structuredlog::IStructuredLogSettings>();
if (strucLogSettings.get() == nullptr)
{
OMNI_LOG_ERROR("failed to get IStructuredLogSettings - using CWD for the log file");
return kLogFileFallback;
}
return std::string(strucLogSettings->getLogOutputPath()) + "/omni.telemetry.transmitter.log";
}
inline bool launchTransmitter(const char* transmitterPath, const std::vector<std::string> extraArgs = {})
{
#if OMNI_PLATFORM_WINDOWS
const char* ext = ".exe";
#else
const char* ext = "";
#endif
carb::launcher::ILauncher* launcher = carb::getFramework()->tryAcquireInterface<carb::launcher::ILauncher>();
carb::settings::ISettings* settings = carb::getFramework()->tryAcquireInterface<carb::settings::ISettings>();
extras::UniqueApp guard = createGuard();
carb::launcher::ArgCollector args;
carb::launcher::EnvCollector env;
carb::launcher::LaunchDesc desc = {};
size_t envCount;
if (launcher == nullptr)
{
OMNI_LOG_ERROR("failed to acquire ILauncher");
return false;
}
guard.connectClientProcess();
args.format("%s/omni.telemetry.transmitter%s", transmitterPath, ext);
args.add("/telemetry", "--/", carb::launcher::fSettingsEnumFlagRecursive);
args.add("/structuredLog/extraFields", "--/", 0);
args.add("/log", "--/", carb::launcher::fSettingsEnumFlagRecursive, [](const char* path, void* ctx) {
CARB_UNUSED(ctx);
return strcmp(path, "/log/enableStandardStreamOutput") != 0 && strcmp(path, "/log/file") != 0 &&
strcmp(path, "/log/level") != 0;
});
// output will not go to the standard streams because it's annoying if
// output goes to your terminal after your process finishes and there is no
// way to ensure the transmitter shuts down before your process
args.add("--/log/enableStandardStreamOutput=false");
args.format("--/log/file=%s", getTransmitterLogPath().c_str());
if (settings == nullptr)
{
OMNI_LOG_ERROR("failed to acquire ISettings");
}
else
{
settings->setDefaultString(kLogLevelSetting, "");
carb::cpp::optional<std::string> logLevel = carb::settings::getStringOpt(settings, kLogLevelSetting);
if (logLevel && !logLevel->empty())
{
args.format("--/log/level=%s", logLevel->c_str());
}
else
{
logLevel = carb::settings::getStringOpt(settings, "/log/level");
if (logLevel && !logLevel->empty())
{
args.format("--/log/level=%s", logLevel->c_str());
}
}
}
for (const std::string& arg : extraArgs)
{
args.add(arg);
}
// add the parent environment but remove the `CARB_APP_PATH` and `CARB_APP_NAME` variables
// since they will negatively affect the behaviour of the transmitter. Note that since
// we're explicitly adding the full parent environment here and just subtracting some
// variables, we need to also use the `fLaunchFlagNoInheritEnv` flag when launching the
// child process so that ILauncher doesn't implicitly add them back.
env.add();
envCount = env.getCount();
env.remove("CARB_APP_PATH");
env.remove("CARB_APP_NAME");
if (env.getCount() != envCount)
{
desc.flags |= carb::launcher::fLaunchFlagAllowBadEnv | carb::launcher::fLaunchFlagNoInheritEnv;
desc.env = env.getEnv();
desc.envCount = env.getCount();
}
desc.argv = args.getArgs(&desc.argc);
desc.flags |= carb::launcher::fLaunchFlagNoStdStreams;
return launcher->launchProcessDetached(desc) != carb::launcher::kBadId;
}
} // namespace telemetry
} // namespace omni