summaryrefslogtreecommitdiffstats
path: root/library/cpp/yt
diff options
context:
space:
mode:
authorbabenko <[email protected]>2026-03-09 21:39:03 +0300
committerbabenko <[email protected]>2026-03-09 22:06:26 +0300
commitbd88f4af4c5aeb8d8505113ca9cfcb660518d2e4 (patch)
tree43323faa2bf6098c64b217d206a5911066210d46 /library/cpp/yt
parent6293b7c8da6a1095d0d9a61016edf1b32c1e834c (diff)
YT-27605: YT_LOG_FATAL_AND_THROW captures log message in error attribute
I'm quite unhappy with the amount of copy-pasted and slightly altered code but the differences between `YT_LOG_ALERT_AND_THROW` and `YT_LOG_EVENT` are too subtle for a reasonable generalization. This commit also fixes some misplaced `[[(un)likely]]` annotations. commit_hash:3eda6b52e0e0cea0daf4d996602d446de2d7d732
Diffstat (limited to 'library/cpp/yt')
-rw-r--r--library/cpp/yt/logging/logger.h51
-rw-r--r--library/cpp/yt/logging/unittests/logger_ut.cpp18
-rw-r--r--library/cpp/yt/logging/unittests/ya.make1
3 files changed, 61 insertions, 9 deletions
diff --git a/library/cpp/yt/logging/logger.h b/library/cpp/yt/logging/logger.h
index 7b48b88acd8..e3e6f58d5a3 100644
--- a/library/cpp/yt/logging/logger.h
+++ b/library/cpp/yt/logging/logger.h
@@ -340,14 +340,47 @@ void LogStructuredEvent(
* clients in any specific way.
* 2. Most places where this could be used have trace_id enabled, which would make it easy for
* administrators to find a correlation between an alert and an error, if a user were to report it.
- * 3. Administrators will receive this alert, so there is no need to enrich the error with
- * additional information.
+ * 3. Original log message is stored in "message" attribute of the raised exception.
+ * 4. The exception is raised regardless of the logging level configured for the |Logger| and
+ * and the currently active message suppressions.
*/
#define YT_LOG_ALERT_AND_THROW(...) \
- YT_LOG_EVENT(Logger, ::NYT::NLogging::ELogLevel::Alert, __VA_ARGS__); \
- THROW_ERROR_EXCEPTION( \
- ::NYT::EErrorCode::Fatal, \
- "Malformed request or incorrect state detected")
+ do { \
+ /* NOLINTBEGIN(bugprone-reserved-identifier, readability-identifier-naming) */ \
+ const auto& logger__ = Logger(); \
+ auto level__ = ::NYT::NLogging::ELogLevel::Alert; \
+ auto location__ = __LOCATION__; \
+ \
+ auto loggingContext__ = ::NYT::NLogging::GetLoggingContext(); \
+ auto message__ = ::NYT::NLogging::NDetail::BuildLogMessage(loggingContext__, logger__, __VA_ARGS__); \
+ auto messageStr__ = ::std::string(message__.MessageRef.ToStringBuf()); \
+ \
+ static ::NYT::TLeakyStorage<::NYT::NLogging::TLoggingAnchor> anchorStorage__; \
+ auto* anchor__ = anchorStorage__.Get(); \
+ \
+ bool anchorUpToDate__ = logger__.IsAnchorUpToDate(*anchor__); \
+ if (!anchorUpToDate__) [[unlikely]] { \
+ static std::atomic<bool> anchorRegistered__; \
+ logger__.UpdateStaticAnchor(anchor__, &anchorRegistered__, location__, message__.Anchor); \
+ } \
+ \
+ auto effectiveLevel__ = ::NYT::NLogging::TLogger::GetEffectiveLoggingLevel(level__, *anchor__); \
+ if (logger__.IsLevelEnabled(effectiveLevel__)) { \
+ ::NYT::NLogging::NDetail::LogEventImpl( \
+ loggingContext__, \
+ logger__, \
+ effectiveLevel__, \
+ location__, \
+ anchor__, \
+ std::move(message__.MessageRef)); \
+ } \
+ \
+ THROW_ERROR_EXCEPTION( \
+ ::NYT::EErrorCode::Fatal, \
+ "Malformed request or incorrect state detected") \
+ << ::NYT::TErrorAttribute("message", std::move(messageStr__)); \
+ /* NOLINTEND(bugprone-reserved-identifier, readability-identifier-naming) */ \
+ } while (false)
#define YT_LOG_ALERT_AND_THROW_IF(condition, ...) \
if (Y_UNLIKELY(condition)) { \
@@ -371,7 +404,7 @@ void LogStructuredEvent(
auto* anchor__ = anchorStorage__.Get(); \
\
bool anchorUpToDate__ = logger__.IsAnchorUpToDate(*anchor__); \
- [[likely]] if (anchorUpToDate__) { \
+ if (anchorUpToDate__) [[likely]] { \
auto effectiveLevel__ = ::NYT::NLogging::TLogger::GetEffectiveLoggingLevel(level__, *anchor__); \
if (!logger__.IsLevelEnabled(effectiveLevel__)) { \
break; \
@@ -381,7 +414,7 @@ void LogStructuredEvent(
auto loggingContext__ = ::NYT::NLogging::GetLoggingContext(); \
auto message__ = ::NYT::NLogging::NDetail::BuildLogMessage(loggingContext__, logger__, __VA_ARGS__); \
\
- [[unlikely]] if (!anchorUpToDate__) { \
+ if (!anchorUpToDate__) [[unlikely]] { \
static std::atomic<bool> anchorRegistered__; \
logger__.UpdateStaticAnchor(anchor__, &anchorRegistered__, location__, message__.Anchor); \
} \
@@ -409,7 +442,7 @@ void LogStructuredEvent(
auto* anchor__ = (anchor); \
\
bool anchorUpToDate__ = logger__.IsAnchorUpToDate(*anchor__); \
- [[unlikely]] if (!anchorUpToDate__) { \
+ if (!anchorUpToDate__) [[unlikely]] { \
logger__.UpdateDynamicAnchor(anchor__); \
} \
\
diff --git a/library/cpp/yt/logging/unittests/logger_ut.cpp b/library/cpp/yt/logging/unittests/logger_ut.cpp
index 7696ea4a83b..410a56fc309 100644
--- a/library/cpp/yt/logging/unittests/logger_ut.cpp
+++ b/library/cpp/yt/logging/unittests/logger_ut.cpp
@@ -2,6 +2,8 @@
#include <library/cpp/yt/logging/logger.h>
+#include <library/cpp/yt/error/error.h>
+
namespace NYT::NLogging {
namespace {
@@ -32,6 +34,22 @@ TEST(TLogger, CopyOfNullLogger)
EXPECT_FALSE(logger.IsLevelEnabled(ELogLevel::Fatal));
}
+TEST(TLogger, LogAlertAndThrowMessage)
+{
+ try {
+ TLogger Logger;
+ YT_LOG_ALERT_AND_THROW("Alert message (Arg1: %v, Arg2: %v)",
+ 1,
+ 2);
+ EXPECT_TRUE(false);
+ } catch (const TErrorException& ex) {
+ const auto& error = ex.Error();
+ EXPECT_EQ(error.GetCode(), NYT::EErrorCode::Fatal);
+ EXPECT_EQ(error.GetMessage(), "Malformed request or incorrect state detected");
+ EXPECT_EQ(error.Attributes().Get<std::string>("message"), "Alert message (Arg1: 1, Arg2: 2)");
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
} // namespace
diff --git a/library/cpp/yt/logging/unittests/ya.make b/library/cpp/yt/logging/unittests/ya.make
index 4baea62140e..01946699bb2 100644
--- a/library/cpp/yt/logging/unittests/ya.make
+++ b/library/cpp/yt/logging/unittests/ya.make
@@ -9,6 +9,7 @@ SRCS(
PEERDIR(
library/cpp/testing/gtest
+ library/cpp/yt/error
library/cpp/yt/logging
)