From 03594a1b8c91b99b4d4455b6ba3d705610ebc980 Mon Sep 17 00:00:00 2001 From: Baiju Meswani Date: Sun, 4 Aug 2024 23:02:08 -0700 Subject: [PATCH] Only log when enabled to avoid unnecessary printing on stdout (#753) --- src/logging.cpp | 2 ++ src/logging.h | 1 + src/models/env_utils.cpp | 57 ++++++++++++++++++++++++++++++++++++ src/models/env_utils.h | 15 ++++++++++ src/models/onnxruntime_api.h | 21 +++++++++---- 5 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 src/models/env_utils.cpp create mode 100644 src/models/env_utils.h diff --git a/src/logging.cpp b/src/logging.cpp index e92afee82..26cb64033 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -36,6 +36,8 @@ void SetLogBool(std::string_view name, bool value) { g_log.model_output_values = value; else if (name == "model_logits") g_log.model_logits = value; + else if (name == "ort_lib") + g_log.ort_lib = value; else throw JSON::unknown_value_error{}; } diff --git a/src/logging.h b/src/logging.h index 99dc8c3d4..9d16c57f9 100644 --- a/src/logging.h +++ b/src/logging.h @@ -42,6 +42,7 @@ struct LogItems { bool model_output_shapes{}; // Before the model runs there are only the output shapes, no values in them. Useful for pre Session::Run debugging bool model_output_values{}; // After the model runs the output tensor values can be displayed bool model_logits{}; // Same as model_output_values but only for the logits + bool ort_lib{}; // Log the onnxruntime library loading and api calls. }; extern LogItems g_log; diff --git a/src/models/env_utils.cpp b/src/models/env_utils.cpp new file mode 100644 index 000000000..d4d14634c --- /dev/null +++ b/src/models/env_utils.cpp @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "env_utils.h" + +#include + +#if _MSC_VER +#include +#endif + +namespace Generators { + +std::string GetEnvironmentVariable(const char* var_name) { +#if _MSC_VER + // Why getenv() should be avoided on Windows: + // https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/getenv-wgetenv + // Instead use the Win32 API: GetEnvironmentVariableA() + + // Max limit of an environment variable on Windows including the null-terminating character + constexpr DWORD kBufferSize = 32767; + + // Create buffer to hold the result + std::string buffer(kBufferSize, '\0'); + + // The last argument is the size of the buffer pointed to by the lpBuffer parameter, including the null-terminating character, in characters. + // If the function succeeds, the return value is the number of characters stored in the buffer pointed to by lpBuffer, not including the terminating null character. + // Therefore, If the function succeeds, kBufferSize should be larger than char_count. + auto char_count = ::GetEnvironmentVariableA(var_name, buffer.data(), kBufferSize); + + if (kBufferSize > char_count) { + buffer.resize(char_count); + return buffer; + } + + return {}; +#else + const char* val = getenv(var_name); + return val == nullptr ? "" : std::string(val); +#endif // _MSC_VER +} + +void GetEnvironmentVariable(const char* var_name, bool& value) { + std::string str_value = GetEnvironmentVariable(var_name); + if (str_value == "1" || str_value == "true") { + value = true; + } else if (str_value == "0" || str_value == "false") { + value = false; + } else if (!str_value.empty()) { + throw std::invalid_argument("Invalid value for environment variable " + std::string(var_name) + ": " + str_value + + ". Expected '1' or 'true' for true, '0' or 'false' for false."); + } + + // Otherwise, value will not be modified. +} + +} // namespace Generators diff --git a/src/models/env_utils.h b/src/models/env_utils.h new file mode 100644 index 000000000..d436bedda --- /dev/null +++ b/src/models/env_utils.h @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include + +namespace Generators { + +std::string GetEnvironmentVariable(const char* var_name); + +// This overload is used to get boolean environment variables. +// If the environment variable is set to "1" or "true" (case-sensitive), value will be set to true. +// Otherwise, value will not be modified. +void GetEnvironmentVariable(const char* var_name, bool& value); + +} // namespace Generators diff --git a/src/models/onnxruntime_api.h b/src/models/onnxruntime_api.h index eebfe0278..2b7f3371e 100644 --- a/src/models/onnxruntime_api.h +++ b/src/models/onnxruntime_api.h @@ -73,6 +73,7 @@ p_session_->Run(nullptr, input_names, inputs, std::size(inputs), output_names, o #include "onnxruntime_c_api.h" #include "../span.h" #include "../logging.h" +#include "env_utils.h" #if defined(__ANDROID__) #include @@ -93,11 +94,14 @@ p_session_->Run(nullptr, input_names, inputs, std::size(inputs), output_names, o #define PATH_MAX (4096) #endif -#define LOG_DEBUG(...) Generators::Log("debug", __VA_ARGS__) -#define LOG_INFO(...) Generators::Log("info", __VA_ARGS__) -#define LOG_WARN(...) Generators::Log("warning", __VA_ARGS__) -#define LOG_ERROR(...) Generators::Log("error", __VA_ARGS__) -#define LOG_FATAL(...) Generators::Log("fatal", __VA_ARGS__) +#define LOG_WHEN_ENABLED(LOG_FUNC) \ + if (Generators::g_log.enabled && Generators::g_log.ort_lib) LOG_FUNC + +#define LOG_DEBUG(...) LOG_WHEN_ENABLED(Generators::Log("debug", __VA_ARGS__)) +#define LOG_INFO(...) LOG_WHEN_ENABLED(Generators::Log("info", __VA_ARGS__)) +#define LOG_WARN(...) LOG_WHEN_ENABLED(Generators::Log("warning", __VA_ARGS__)) +#define LOG_ERROR(...) LOG_WHEN_ENABLED(Generators::Log("error", __VA_ARGS__)) +#define LOG_FATAL(...) LOG_WHEN_ENABLED(Generators::Log("fatal", __VA_ARGS__)) #endif @@ -175,6 +179,13 @@ inline void InitApi() { return; } + bool ort_lib = false; + Generators::GetEnvironmentVariable("ORTGENAI_LOG_ORT_LIB", ort_lib); + if (ort_lib) { + Generators::SetLogBool("enabled", true); + Generators::SetLogBool("ort_lib", true); + } + #if defined(__linux__) // If the GenAI library links against the onnxruntime library, it will have a dependency on a specific // version of OrtGetApiBase.