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