diff options
author | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
---|---|---|
committer | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
commit | 22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch) | |
tree | bffa27765faf54126ad44bcafa89fadecb7a73d7 /library/cpp/yt/logging/logger.cpp | |
parent | 332b99e2173f0425444abb759eebcb2fafaa9209 (diff) | |
download | ydb-22f8ae0e3f5d68b92aecccdf96c1d841a0334311.tar.gz |
validate canons without yatest_common
Diffstat (limited to 'library/cpp/yt/logging/logger.cpp')
-rw-r--r-- | library/cpp/yt/logging/logger.cpp | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/library/cpp/yt/logging/logger.cpp b/library/cpp/yt/logging/logger.cpp new file mode 100644 index 0000000000..7f6f217d86 --- /dev/null +++ b/library/cpp/yt/logging/logger.cpp @@ -0,0 +1,249 @@ +#include "logger.h" + +#include <library/cpp/yt/assert/assert.h> + +#include <library/cpp/yt/cpu_clock/clock.h> + +#include <util/system/compiler.h> +#include <util/system/thread.h> + +namespace NYT::NLogging { + +//////////////////////////////////////////////////////////////////////////////// + +namespace NDetail { + +TSharedRef TMessageStringBuilder::Flush() +{ + return Buffer_.Slice(0, GetLength()); +} + +void TMessageStringBuilder::DisablePerThreadCache() +{ + Cache_ = nullptr; + CacheDestroyed_ = true; +} + +void TMessageStringBuilder::DoReset() +{ + Buffer_.Reset(); +} + +void TMessageStringBuilder::DoReserve(size_t newCapacity) +{ + auto oldLength = GetLength(); + newCapacity = FastClp2(newCapacity); + + auto newChunkSize = std::max(ChunkSize, newCapacity); + // Hold the old buffer until the data is copied. + auto oldBuffer = std::move(Buffer_); + auto* cache = GetCache(); + if (Y_LIKELY(cache)) { + auto oldCapacity = End_ - Begin_; + auto deltaCapacity = newCapacity - oldCapacity; + if (End_ == cache->Chunk.Begin() + cache->ChunkOffset && + cache->ChunkOffset + deltaCapacity <= cache->Chunk.Size()) + { + // Resize inplace. + Buffer_ = cache->Chunk.Slice(cache->ChunkOffset - oldCapacity, cache->ChunkOffset + deltaCapacity); + cache->ChunkOffset += deltaCapacity; + End_ = Begin_ + newCapacity; + return; + } + + if (Y_UNLIKELY(cache->ChunkOffset + newCapacity > cache->Chunk.Size())) { + cache->Chunk = TSharedMutableRef::Allocate<TMessageBufferTag>(newChunkSize, {.InitializeStorage = false}); + cache->ChunkOffset = 0; + } + + Buffer_ = cache->Chunk.Slice(cache->ChunkOffset, cache->ChunkOffset + newCapacity); + cache->ChunkOffset += newCapacity; + } else { + Buffer_ = TSharedMutableRef::Allocate<TMessageBufferTag>(newChunkSize, {.InitializeStorage = false}); + newCapacity = newChunkSize; + } + if (oldLength > 0) { + ::memcpy(Buffer_.Begin(), Begin_, oldLength); + } + Begin_ = Buffer_.Begin(); + End_ = Begin_ + newCapacity; +} + +TMessageStringBuilder::TPerThreadCache* TMessageStringBuilder::GetCache() +{ + if (Y_LIKELY(Cache_)) { + return Cache_; + } + if (CacheDestroyed_) { + return nullptr; + } + static thread_local TPerThreadCache Cache; + Cache_ = &Cache; + return Cache_; +} + +TMessageStringBuilder::TPerThreadCache::~TPerThreadCache() +{ + TMessageStringBuilder::DisablePerThreadCache(); +} + +thread_local TMessageStringBuilder::TPerThreadCache* TMessageStringBuilder::Cache_; +thread_local bool TMessageStringBuilder::CacheDestroyed_; + +} // namespace NDetail + +//////////////////////////////////////////////////////////////////////////////// + +Y_WEAK TLoggingContext GetLoggingContext() +{ + return { + .Instant = GetCpuInstant(), + .ThreadId = TThread::CurrentThreadId(), + .ThreadName = GetLoggingThreadName(), + }; +} + +Y_WEAK ILogManager* GetDefaultLogManager() +{ + return nullptr; +} + +//////////////////////////////////////////////////////////////////////////////// + +TLoggingThreadName GetLoggingThreadName() +{ + static thread_local TLoggingThreadName loggingThreadName; + if (loggingThreadName.Length == 0) { + if (auto name = TThread::CurrentThreadName()) { + auto length = std::min(TLoggingThreadName::BufferCapacity - 1, static_cast<int>(name.length())); + loggingThreadName.Length = length; + ::memcpy(loggingThreadName.Buffer.data(), name.data(), length); + } + } + return loggingThreadName; +} + +//////////////////////////////////////////////////////////////////////////////// + +TLogger::TLogger(ILogManager* logManager, TStringBuf categoryName) + : LogManager_(logManager) + , Category_(LogManager_ ? LogManager_->GetCategory(categoryName) : nullptr) + , MinLevel_(LogManager_ ? LoggerDefaultMinLevel : NullLoggerMinLevel) +{ } + +TLogger::TLogger(TStringBuf categoryName) + : TLogger(GetDefaultLogManager(), categoryName) +{ } + +TLogger::operator bool() const +{ + return LogManager_; +} + +const TLoggingCategory* TLogger::GetCategory() const +{ + return Category_; +} + +bool TLogger::IsLevelEnabledHeavy(ELogLevel level) const +{ + // Note that we managed to reach this point, i.e. level >= MinLevel_, + // which implies that MinLevel_ != ELogLevel::Maximum, so this logger was not + // default constructed, thus it has non-trivial category. + YT_ASSERT(Category_); + + if (Category_->CurrentVersion != Category_->ActualVersion->load(std::memory_order::relaxed)) { + LogManager_->UpdateCategory(const_cast<TLoggingCategory*>(Category_)); + } + + return level >= Category_->MinPlainTextLevel; +} + +bool TLogger::GetAbortOnAlert() const +{ + return LogManager_->GetAbortOnAlert(); +} + +bool TLogger::IsEssential() const +{ + return Essential_; +} + +void TLogger::UpdateAnchor(TLoggingAnchor* anchor) const +{ + LogManager_->UpdateAnchor(anchor); +} + +void TLogger::RegisterStaticAnchor(TLoggingAnchor* anchor, ::TSourceLocation sourceLocation, TStringBuf message) const +{ + LogManager_->RegisterStaticAnchor(anchor, sourceLocation, message); +} + +void TLogger::Write(TLogEvent&& event) const +{ + LogManager_->Enqueue(std::move(event)); +} + +void TLogger::AddRawTag(const TString& tag) +{ + if (!Tag_.empty()) { + Tag_ += ", "; + } + Tag_ += tag; +} + +TLogger TLogger::WithRawTag(const TString& tag) const +{ + auto result = *this; + result.AddRawTag(tag); + return result; +} + +TLogger TLogger::WithEssential(bool essential) const +{ + auto result = *this; + result.Essential_ = essential; + return result; +} + +TLogger TLogger::WithMinLevel(ELogLevel minLevel) const +{ + auto result = *this; + if (result) { + result.MinLevel_ = minLevel; + } + return result; +} + +const TString& TLogger::GetTag() const +{ + return Tag_; +} + +const TLogger::TStructuredTags& TLogger::GetStructuredTags() const +{ + return StructuredTags_; +} + +//////////////////////////////////////////////////////////////////////////////// + +void LogStructuredEvent( + const TLogger& logger, + NYson::TYsonString message, + ELogLevel level) +{ + YT_VERIFY(message.GetType() == NYson::EYsonType::MapFragment); + auto loggingContext = GetLoggingContext(); + auto event = NDetail::CreateLogEvent( + loggingContext, + logger, + level); + event.MessageKind = ELogMessageKind::Structured; + event.MessageRef = message.ToSharedRef(); + event.Family = ELogFamily::Structured; + logger.Write(std::move(event)); +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT::NLogging |