origin_attributes.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include "origin_attributes.h"
  2. #include "error_attributes.h"
  3. #include <library/cpp/yt/assert/assert.h>
  4. #include <library/cpp/yt/misc/thread_name.h>
  5. #include <library/cpp/yt/misc/tls.h>
  6. #include <library/cpp/yt/string/format.h>
  7. #include <util/system/thread.h>
  8. namespace NYT {
  9. ////////////////////////////////////////////////////////////////////////////////
  10. YT_DEFINE_THREAD_LOCAL(bool, ErrorSanitizerEnabled, false);
  11. YT_DEFINE_THREAD_LOCAL(TInstant, ErrorSanitizerDatetimeOverride);
  12. YT_DEFINE_THREAD_LOCAL(TSharedRef, ErrorSanitizerLocalHostNameOverride);
  13. TErrorSanitizerGuard::TErrorSanitizerGuard(TInstant datetimeOverride, TSharedRef localHostNameOverride)
  14. : SavedEnabled_(ErrorSanitizerEnabled())
  15. , SavedDatetimeOverride_(ErrorSanitizerDatetimeOverride())
  16. , SavedLocalHostNameOverride_(ErrorSanitizerLocalHostNameOverride())
  17. {
  18. ErrorSanitizerEnabled() = true;
  19. ErrorSanitizerDatetimeOverride() = datetimeOverride;
  20. ErrorSanitizerLocalHostNameOverride() = std::move(localHostNameOverride);
  21. }
  22. TErrorSanitizerGuard::~TErrorSanitizerGuard()
  23. {
  24. YT_ASSERT(ErrorSanitizerEnabled());
  25. ErrorSanitizerEnabled() = SavedEnabled_;
  26. ErrorSanitizerDatetimeOverride() = SavedDatetimeOverride_;
  27. ErrorSanitizerLocalHostNameOverride() = std::move(SavedLocalHostNameOverride_);
  28. }
  29. bool IsErrorSanitizerEnabled() noexcept
  30. {
  31. return ErrorSanitizerEnabled();
  32. }
  33. ////////////////////////////////////////////////////////////////////////////////
  34. bool TOriginAttributes::operator==(const TOriginAttributes& other) const noexcept
  35. {
  36. return
  37. Host == other.Host &&
  38. Datetime == other.Datetime &&
  39. Pid == other.Pid &&
  40. Tid == other.Tid &&
  41. ExtensionData == other.ExtensionData;
  42. }
  43. void TOriginAttributes::Capture()
  44. {
  45. if (ErrorSanitizerEnabled()) {
  46. Datetime = ErrorSanitizerDatetimeOverride();
  47. HostHolder = ErrorSanitizerLocalHostNameOverride();
  48. Host = HostHolder.empty() ? TStringBuf() : TStringBuf(HostHolder.Begin(), HostHolder.End());
  49. return;
  50. }
  51. Datetime = TInstant::Now();
  52. Pid = GetPID();
  53. Tid = TThread::CurrentThreadId();
  54. ThreadName = GetCurrentThreadName();
  55. ExtensionData = NDetail::GetExtensionData();
  56. }
  57. ////////////////////////////////////////////////////////////////////////////////
  58. namespace NDetail {
  59. std::optional<TOriginAttributes::TErasedExtensionData> GetExtensionData()
  60. {
  61. using TFunctor = TOriginAttributes::TErasedExtensionData(*)();
  62. if (auto strong = NGlobal::GetErasedVariable(GetExtensionDataTag)) {
  63. return strong->AsConcrete<TFunctor>()();
  64. }
  65. return std::nullopt;
  66. }
  67. TString FormatOrigin(const TOriginAttributes& attributes)
  68. {
  69. using TFunctor = TString(*)(const TOriginAttributes&);
  70. if (auto strong = NGlobal::GetErasedVariable(FormatOriginTag)) {
  71. return strong->AsConcrete<TFunctor>()(attributes);
  72. }
  73. return Format(
  74. "%v (pid %v, thread %v)",
  75. attributes.Host,
  76. attributes.Pid,
  77. MakeFormatterWrapper([&] (auto* builder) {
  78. auto threadName = attributes.ThreadName.ToStringBuf();
  79. if (threadName.empty()) {
  80. FormatValue(builder, attributes.Tid, "v");
  81. return;
  82. }
  83. FormatValue(builder, threadName, "v");
  84. }));
  85. }
  86. ////////////////////////////////////////////////////////////////////////////////
  87. TOriginAttributes ExtractFromDictionary(TErrorAttributes* attributes)
  88. {
  89. using TFunctor = TOriginAttributes(*)(TErrorAttributes*);
  90. if (auto strong = NGlobal::GetErasedVariable(ExtractFromDictionaryTag)) {
  91. return strong->AsConcrete<TFunctor>()(attributes);
  92. }
  93. return ExtractFromDictionaryDefault(attributes);
  94. }
  95. ////////////////////////////////////////////////////////////////////////////////
  96. TOriginAttributes ExtractFromDictionaryDefault(TErrorAttributes* attributes)
  97. {
  98. TOriginAttributes result;
  99. if (attributes == nullptr) {
  100. return result;
  101. }
  102. static const std::string HostKey("host");
  103. result.HostHolder = TSharedRef::FromString(attributes->GetAndRemove(HostKey, std::string()));
  104. result.Host = result.HostHolder.empty() ? TStringBuf() : TStringBuf(result.HostHolder.Begin(), result.HostHolder.End());
  105. static const std::string DatetimeKey("datetime");
  106. result.Datetime = attributes->GetAndRemove(DatetimeKey, TInstant());
  107. static const std::string PidKey("pid");
  108. result.Pid = attributes->GetAndRemove(PidKey, TProcessId{});
  109. static const std::string TidKey("tid");
  110. result.Tid = attributes->GetAndRemove(TidKey, NThreading::InvalidThreadId);
  111. static const std::string ThreadNameKey("thread");
  112. result.ThreadName = TString(attributes->GetAndRemove(ThreadNameKey, std::string()));
  113. return result;
  114. }
  115. } // namespace NDetail
  116. ////////////////////////////////////////////////////////////////////////////////
  117. } // namespace NYT