diff options
| author | babenko <[email protected]> | 2026-03-09 21:39:03 +0300 |
|---|---|---|
| committer | babenko <[email protected]> | 2026-03-09 22:06:26 +0300 |
| commit | bd88f4af4c5aeb8d8505113ca9cfcb660518d2e4 (patch) | |
| tree | 43323faa2bf6098c64b217d206a5911066210d46 /library/cpp/yt | |
| parent | 6293b7c8da6a1095d0d9a61016edf1b32c1e834c (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.h | 51 | ||||
| -rw-r--r-- | library/cpp/yt/logging/unittests/logger_ut.cpp | 18 | ||||
| -rw-r--r-- | library/cpp/yt/logging/unittests/ya.make | 1 |
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 ) |
