diff options
author | qrort <qrort@yandex-team.com> | 2022-12-02 11:31:25 +0300 |
---|---|---|
committer | qrort <qrort@yandex-team.com> | 2022-12-02 11:31:25 +0300 |
commit | b1f4ffc9c8abff3ba58dc1ec9a9f92d2f0de6806 (patch) | |
tree | 2a23209faf0fea5586a6d4b9cee60d1b318d29fe /library/cpp/unistat | |
parent | 559174a9144de40d6bb3997ea4073c82289b4974 (diff) | |
download | ydb-b1f4ffc9c8abff3ba58dc1ec9a9f92d2f0de6806.tar.gz |
remove kikimr/driver DEPENDS
Diffstat (limited to 'library/cpp/unistat')
-rw-r--r-- | library/cpp/unistat/idl/stats.proto | 19 | ||||
-rw-r--r-- | library/cpp/unistat/raii.cpp | 1 | ||||
-rw-r--r-- | library/cpp/unistat/raii.h | 120 | ||||
-rw-r--r-- | library/cpp/unistat/types.h | 15 | ||||
-rw-r--r-- | library/cpp/unistat/unistat.cpp | 461 | ||||
-rw-r--r-- | library/cpp/unistat/unistat.h | 382 |
6 files changed, 0 insertions, 998 deletions
diff --git a/library/cpp/unistat/idl/stats.proto b/library/cpp/unistat/idl/stats.proto deleted file mode 100644 index 10a63ec8a2a..00000000000 --- a/library/cpp/unistat/idl/stats.proto +++ /dev/null @@ -1,19 +0,0 @@ -message TInstanceStats { - message THistogram { - message TBucket { - required double Boundary = 1; - required uint64 Weight = 2; - } - repeated TBucket Bucket = 1; - } - - message TMetric { - required string Name = 1; - oneof value { - double Number = 2; - THistogram Hgram = 3; - } - } - - repeated TMetric Metric = 1; -} diff --git a/library/cpp/unistat/raii.cpp b/library/cpp/unistat/raii.cpp deleted file mode 100644 index c06a2e05c72..00000000000 --- a/library/cpp/unistat/raii.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "raii.h" diff --git a/library/cpp/unistat/raii.h b/library/cpp/unistat/raii.h deleted file mode 100644 index f8f46745fe2..00000000000 --- a/library/cpp/unistat/raii.h +++ /dev/null @@ -1,120 +0,0 @@ -#pragma once - -#include "unistat.h" - -#include <util/datetime/base.h> -#include <util/generic/noncopyable.h> -#include <util/generic/va_args.h> -#include <util/generic/yexception.h> -#include <util/system/defaults.h> - -class TUnistatTimer: public TNonCopyable { -public: - template <typename T> - TUnistatTimer(TUnistat& unistat, T&& holename) - : Started_(Now()) - , HoleName_(ToString(holename)) - , Aggregator_(unistat) - { - } - - ~TUnistatTimer() { - if (!Dismiss_) { - Aggregator_.PushSignalUnsafe(HoleName_, (Now() - Started_).MillisecondsFloat()); - } - } - - void Dismiss() noexcept { - Dismiss_ = true; - } - - void Accept() noexcept { - Dismiss_ = false; - } - -private: - bool Dismiss_{false}; - const TInstant Started_; - const TString HoleName_; - TUnistat& Aggregator_; -}; - -class TUnistatExceptionCounter: public TNonCopyable { -public: - template <typename T, typename U> - TUnistatExceptionCounter(TUnistat& unistat, T&& hasExceptionHolename, U&& noExceptionHolename) - : HasExceptionHoleName_(ToString(hasExceptionHolename)) - , NoExceptionHoleName_(ToString(noExceptionHolename)) - , Aggregator_(unistat) - { - } - - template <typename T> - TUnistatExceptionCounter(TUnistat& unistat, T&& hasExceptionHolename) - : HasExceptionHoleName_(ToString(hasExceptionHolename)) - , Aggregator_(unistat) - { - } - - ~TUnistatExceptionCounter() { - if (!Dismiss_) { - if (UncaughtException()) { - Aggregator_.PushSignalUnsafe(HasExceptionHoleName_, 1.); - } else if (NoExceptionHoleName_) { - Aggregator_.PushSignalUnsafe(NoExceptionHoleName_, 1.); - } - } - } - - void Dismiss() noexcept { - Dismiss_ = true; - } - - void Accept() noexcept { - Dismiss_ = false; - } - -private: - bool Dismiss_{false}; - const TString HasExceptionHoleName_; - const TString NoExceptionHoleName_; - TUnistat& Aggregator_; -}; - -/** - * @def Y_UNISTAT_TIMER - * - * Macro is needed to time scope and push time into aggregator. - * - * @code - * void DoSomethingImportant() { - * Y_UNISTAT_TIMER(TUnistat::Instance(), "doing-important-stuff") - * // doing something here - * } - * @endcode - */ -#define Y_UNISTAT_TIMER(unistat, holeName) \ - ::TUnistatTimer Y_GENERATE_UNIQUE_ID(timer){unistat, holeName}; - -#define Y_UNISTAT_EXCEPTION_COUNTER_IMPL_2(unistat, hasExceptionHoleName) \ - ::TUnistatExceptionCounter Y_GENERATE_UNIQUE_ID(exceptionCounter){unistat, hasExceptionHoleName}; - -#define Y_UNISTAT_EXCEPTION_COUNTER_IMPL_3(unistat, hasExceptionHolename, noExceptionHolename) \ - ::TUnistatExceptionCounter Y_GENERATE_UNIQUE_ID(exceptionCounter){unistat, hasExceptionHolename, noExceptionHolename}; - -#define Y_UNISTAT_EXCEPTION_COUNTER_IMPL_DISPATCHER(_1, _2, _3, NAME, ...) NAME - -/** - * @def Y_UNISTAT_EXCEPTION_COUNTER - * - * Macro is needed to check if there was an exception on scope exit or not. - * - * @code - * void DoSomethingThatMayThrowException() { - * Y_UNISTAT_EXCEPTION_COUNTER(TUnistat::Instance(), "exception_occured", "no_exception") - * Y_UNISTAT_EXCEPTION_COUNTER(TUnistat::Instance(), "wow_exception_occured") - * // doing something here - * } - * @endcode - */ -#define Y_UNISTAT_EXCEPTION_COUNTER(...) Y_PASS_VA_ARGS(Y_UNISTAT_EXCEPTION_COUNTER_IMPL_DISPATCHER(__VA_ARGS__, Y_UNISTAT_EXCEPTION_COUNTER_IMPL_3, Y_UNISTAT_EXCEPTION_COUNTER_IMPL_2)(__VA_ARGS__)) diff --git a/library/cpp/unistat/types.h b/library/cpp/unistat/types.h deleted file mode 100644 index f4346c95f6d..00000000000 --- a/library/cpp/unistat/types.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <util/generic/string.h> - -enum class EAggregationType { - Average /* "aver" Брать среднее среди всех полученных хостовых значений */, - HostHistogram /* "hgram" Выполнять слияние всех полученных хостовых значений в гистограмму */, - Max /* "max" Брать максимальное среди всех полученных хостовых значений */, - Min /* "min" Брать минимальное среди всех полученных хостовых значений */, - Sum /* "summ" Брать сумму всех полученных хостовых значений */, - SumOne /* "sumone" summ c None для отсутсвия сигналов */, - LastValue /* "trnsp" Брать последнее среди всех полученных хостовых значений */ -}; - -const TString& ToString(EAggregationType x); diff --git a/library/cpp/unistat/unistat.cpp b/library/cpp/unistat/unistat.cpp deleted file mode 100644 index 21bf49ff012..00000000000 --- a/library/cpp/unistat/unistat.cpp +++ /dev/null @@ -1,461 +0,0 @@ -#include "unistat.h" -#include <util/generic/strbuf.h> - -using namespace NUnistat; - -TIntervalsBuilder& TIntervalsBuilder::Append(double value) { - Y_ENSURE(Intervals_.empty() || Intervals_.back() < value); - Intervals_.push_back(value); - return *this; -} - -TIntervalsBuilder& TIntervalsBuilder::AppendFlat(size_t count, double step) { - Y_ENSURE(Intervals_.size() > 0 && step > 0); - double x = Intervals_.back(); - for (size_t i = 0; i < count; ++i) { - x += step; - Intervals_.push_back(x); - } - return *this; -} - -TIntervalsBuilder& TIntervalsBuilder::AppendExp(size_t count, double base) { - Y_ENSURE(Intervals_.size() > 0 && base > 1); - double x = Intervals_.back(); - for (size_t i = 0; i < count; ++i) { - x *= base; - Intervals_.push_back(x); - } - return *this; -} - -TIntervalsBuilder& TIntervalsBuilder::FlatRange(size_t count, double start, double stop) { - Y_ENSURE(count > 0 && start < stop); - Append(start); - AppendFlat(count - 1, (stop - start) / count); - return *this; -} - -TIntervalsBuilder& TIntervalsBuilder::ExpRange(size_t count, double start, double stop) { - Y_ENSURE(count > 0 && start < stop); - Append(start); - AppendExp(count - 1, std::pow(stop / start, 1. / count)); - return *this; -} - -TIntervals TIntervalsBuilder::Build() { - Y_ENSURE(Intervals_.size() <= MAX_HISTOGRAM_SIZE); - Y_ENSURE(IsSorted(Intervals_.begin(), Intervals_.end())); - return std::move(Intervals_); -} - -IHolePtr TUnistat::DrillFloatHole(const TString& name, const TString& suffix, TPriority priority, TStartValue startValue, EAggregationType type, bool alwaysVisible) { - return DrillFloatHole(name, "", suffix, priority, startValue, type, alwaysVisible); -} - -IHolePtr TUnistat::DrillFloatHole(const TString& name, const TString& description, const TString& suffix, TPriority priority, TStartValue startValue, EAggregationType type, bool alwaysVisible) { - { - TReadGuard guard(Mutex); - IHolePtr* exhole = Holes.FindPtr(name); - if (exhole) { - return *exhole; - } - } - { - TWriteGuard guard(Mutex); - IHolePtr* exhole = Holes.FindPtr(name); - if (exhole) { - return *exhole; - } - IHolePtr hole = new TFloatHole(name, description, suffix, type, priority.Priority, startValue.StartValue, alwaysVisible); - for (const auto& tag : GlobalTags) { - hole->AddTag(tag.first, tag.second); - } - Holes[name] = hole; - HolesByPriorityAndTags.insert(hole.Get()); - return hole; - } -} - -IHolePtr TUnistat::DrillHistogramHole(const TString& name, const TString& suffix, TPriority priority, const NUnistat::TIntervals& intervals, EAggregationType type, bool alwaysVisible) { - return DrillHistogramHole(name, "", suffix, priority, intervals, type, alwaysVisible); -} - -IHolePtr TUnistat::DrillHistogramHole(const TString& name, const TString& description, const TString& suffix, TPriority priority, const NUnistat::TIntervals& intervals, EAggregationType type, bool alwaysVisible) { - { - TReadGuard guard(Mutex); - IHolePtr* exhole = Holes.FindPtr(name); - if (exhole) { - return *exhole; - } - } - { - TWriteGuard guard(Mutex); - IHolePtr* exhole = Holes.FindPtr(name); - if (exhole) { - return *exhole; - } - IHolePtr hole = new THistogramHole(name, description, suffix, type, priority.Priority, intervals, alwaysVisible); - for (const auto& tag : GlobalTags) { - hole->AddTag(tag.first, tag.second); - } - Holes[name] = hole; - HolesByPriorityAndTags.insert(hole.Get()); - return hole; - } -} - -void TUnistat::AddGlobalTag(const TString& tagName, const TString& tagValue) { - TWriteGuard guard(Mutex); - GlobalTags[tagName] = tagValue; - for (IHole* hole : HolesByPriorityAndTags) { - hole->AddTag(tagName, tagValue); - } -} - -bool TUnistat::PushSignalUnsafeImpl(const TStringBuf holename, double signal) { - IHolePtr* hole = Holes.FindPtr(holename); - if (!hole) { - return false; - } - - (*hole)->PushSignal(signal); - return true; -} - -TMaybe<TInstanceStats::TMetric> TUnistat::GetSignalValueUnsafeImpl(const TStringBuf holename) { - IHolePtr* hole = Holes.FindPtr(holename); - if (!hole) { - return Nothing(); - } - - TInstanceStats stat; - (*hole)->ExportToProto(stat); - if (!stat.GetMetric().size()) { - return Nothing(); - } - return std::move(*stat.MutableMetric(0)); -} - -bool TUnistat::ResetSignalUnsafeImpl(const TStringBuf holename) { - IHolePtr* hole = Holes.FindPtr(holename); - if (!hole) { - return false; - } - - (*hole)->ResetSignal(); - return true; -} - -TString TUnistat::CreateInfoDump(int level) const { - TReadGuard guard(Mutex); - NJsonWriter::TBuf json; - json.BeginObject(); - for (IHole* hole : HolesByPriorityAndTags) { - if (hole->GetPriority() < level) { - break; - } - hole->PrintInfo(json); - } - json.EndObject(); - return json.Str(); -} - -TString TUnistat::CreateJsonDump(int level, bool allHoles) const { - TReadGuard guard(Mutex); - NJsonWriter::TBuf json; - json.BeginList(); - bool filterZeroHoles = !allHoles && level >= 0; - for (IHole* hole : HolesByPriorityAndTags) { - if (hole->GetPriority() < level) { - break; - } - hole->PrintValue(json, filterZeroHoles); - } - json.EndList(); - return json.Str(); -} - -TString TUnistat::CreatePushDump(int level, const NUnistat::TTags& tags, ui32 ttl, bool allHoles) const { - TReadGuard guard(Mutex); - NJsonWriter::TBuf json; - json.BeginList(); - bool filterZeroHoles = !allHoles && level >= 0; - int prevPriority = Max<int>(); - TString prevTagsStr; - for (IHole* hole : HolesByPriorityAndTags) { - int priority = hole->GetPriority(); - TString tagStr = hole->GetTagsStr(); - if (priority < level) { - break; - } - if (prevPriority != priority || prevTagsStr != tagStr) { - if (prevPriority != Max<int>()) { - json.EndList(); - json.EndObject(); - } - json.BeginObject(); - if (ttl) { - json.WriteKey("ttl").WriteULongLong(ttl); - } - json.WriteKey("tags").BeginObject() - .WriteKey("_priority").WriteInt(hole->GetPriority()); - for (const auto& tag : tags) { - json.WriteKey(tag.first); - json.WriteString(tag.second); - } - for (const auto& tag : hole->GetTags()) { - json.WriteKey(tag.first); - json.WriteString(tag.second); - } - json.EndObject(); - json.WriteKey("values").BeginList(); - prevPriority = priority; - prevTagsStr = tagStr; - } - hole->PrintToPush(json, filterZeroHoles); - } - if (prevPriority != Max<int>()) { - json.EndList(); - json.EndObject(); - } - json.EndList(); - return json.Str(); -} - -void TUnistat::ExportToProto(TInstanceStats& stats, int level) const { - TReadGuard guard(Mutex); - - for (IHole* hole : HolesByPriorityAndTags) { - if (hole->GetPriority() < level) { - break; - } - hole->ExportToProto(stats); - } -} - -TString TUnistat::GetSignalDescriptions() const { - TReadGuard guard(Mutex); - NJsonWriter::TBuf json; - json.BeginObject(); - - for (IHole* hole : HolesByPriorityAndTags) { - json.WriteKey(hole->GetName()); - json.WriteString(hole->GetDescription()); - } - - json.EndObject(); - return json.Str(); -} - -TVector<TString> TUnistat::GetHolenames() const { - TReadGuard guard(Mutex); - - TVector<TString> holenames; - for (const auto& [holeName, holeData] : Holes) { - holenames.emplace_back(holeName); - } - - return holenames; -} - -bool TUnistat::EraseHole(const TString& name) { - TWriteGuard guard(Mutex); - auto holeIterator = Holes.find(name); - if (holeIterator == Holes.end()) { - return false; - } - - HolesByPriorityAndTags.erase(holeIterator->second.Get()); - Holes.erase(holeIterator); - return true; -} - -void TFloatHole::PrintInfo(NJsonWriter::TBuf& json) const { - TValue value; - value.Atomic = AtomicGet(Value.Atomic); - json.WriteKey(Name) - .BeginObject() - .WriteKey(TStringBuf("Priority")) - .WriteInt(Priority) - .WriteKey(TStringBuf("Value")) - .WriteDouble(value.Value) - .WriteKey(TStringBuf("Type")) - .WriteString(ToString(Type)) - .WriteKey(TStringBuf("Suffix")) - .WriteString(Suffix) - .WriteKey(TStringBuf("Tags")) - .WriteString(GetTagsStr()) - .EndObject(); -} - -void TFloatHole::PrintValue(NJsonWriter::TBuf& json, bool check) const { - if (check && !AtomicGet(Pushed)) { - return; - } - - TValue value; - value.Atomic = AtomicGet(Value.Atomic); - json.BeginList() - .WriteString(TString::Join(GetTagsStr(), Name, TStringBuf("_"), Suffix)) - .WriteDouble(value.Value) - .EndList(); -} - -void TFloatHole::PrintToPush(NJsonWriter::TBuf& json, bool check) const { - if (check && !AtomicGet(Pushed)) { - return; - } - - TValue value; - value.Atomic = AtomicGet(Value.Atomic); - json.BeginObject() - .WriteKey("name").WriteString(TString::Join(Name, TStringBuf("_"), Suffix)) - .WriteKey("val").WriteDouble(value.Value) - .EndObject(); -} - - -void TFloatHole::ExportToProto(TInstanceStats& stats) const { - if (!AtomicGet(Pushed)) { - return; - } - - TValue value; - value.Atomic = AtomicGet(Value.Atomic); - TInstanceStats::TMetric* metric = stats.AddMetric(); - metric->SetName(TString::Join(GetTagsStr(), Name, TStringBuf("_"), Suffix)); - metric->SetNumber(value.Value); -} - -void TFloatHole::PushSignal(double signal) { - AtomicSet(Pushed, 1); - TValue old, toset; - do { - old.Atomic = AtomicGet(Value.Atomic); - switch (Type) { - case EAggregationType::Max: - toset.Value = Max(signal, old.Value); - break; - case EAggregationType::Min: - toset.Value = Min(signal, old.Value); - break; - case EAggregationType::Sum: - toset.Value = signal + old.Value; - break; - case EAggregationType::LastValue: - toset.Value = signal; - break; - default: - assert(0); - } - } while (!AtomicCas(&Value.Atomic, toset.Atomic, old.Atomic)); -} - -void TFloatHole::ResetSignal() { - AtomicSet(Value.Atomic, 0); - AtomicSet(Pushed, 0); -} - -void THistogramHole::PrintInfo(NJsonWriter::TBuf& json) const { - json.WriteKey(Name) - .BeginObject() - .WriteKey(TStringBuf("Priority")) - .WriteInt(Priority) - .WriteKey(TStringBuf("Value")); - - PrintWeights(json); - - json.WriteKey(TStringBuf("Type")) - .WriteString(ToString(Type)); - json.WriteKey(TStringBuf("Suffix")) - .WriteString(Suffix); - json.WriteKey(TStringBuf("Tags")) - .WriteString(GetTagsStr()) - .EndObject(); -} - -void THistogramHole::PrintValue(NJsonWriter::TBuf& json, bool check) const { - if (check && !AtomicGet(Pushed)) { - return; - } - - json.BeginList() - .WriteString(TString::Join(GetTagsStr(), Name, TStringBuf("_"), Suffix)); - - PrintWeights(json); - - json.EndList(); -} - -void THistogramHole::PrintToPush(NJsonWriter::TBuf& json, bool check) const { - if (check && !AtomicGet(Pushed)) { - return; - } - - json.BeginObject() - .WriteKey("name").WriteString(TString::Join(Name, TStringBuf("_"), Suffix)) - .WriteKey("val"); - PrintWeights(json); - json.EndObject(); -} - -void THistogramHole::PrintWeights(NJsonWriter::TBuf& json) const { - json.BeginList(); - for (size_t i = 0, size = Weights.size(); i < size; ++i) { - json.BeginList() - .WriteDouble(Intervals[i]) - .WriteLongLong(AtomicGet(Weights[i])) - .EndList(); - } - json.EndList(); -} - -void THistogramHole::ExportToProto(TInstanceStats& stats) const { - if (!AtomicGet(Pushed)) { - return; - } - - TInstanceStats::TMetric* metric = stats.AddMetric(); - metric->SetName(TString::Join(GetTagsStr(), Name, TStringBuf("_"), Suffix)); - - TInstanceStats::THistogram* hgram = metric->MutableHgram(); - for (size_t i = 0, size = Weights.size(); i < size; ++i) { - TInstanceStats::THistogram::TBucket* bucket = hgram->AddBucket(); - bucket->SetBoundary(Intervals[i]); - bucket->SetWeight(AtomicGet(Weights[i])); - } -} - -void THistogramHole::PushSignal(double signal) { - AtomicSet(Pushed, 1); - - const size_t i = UpperBound(Intervals.cbegin(), Intervals.cend(), signal) - Intervals.cbegin(); // Intervals[i - 1] <= signal < Intervals[i] - if (i > 0) { - AtomicIncrement(Weights[i - 1]); - } -} - -void THistogramHole::ResetSignal() { - for (size_t i = 0; i < Intervals.size(); ++i) { - SetWeight(i, 0); - } - AtomicSet(Pushed, 0); -} - -void THistogramHole::SetWeight(ui32 index, TAtomicBase value) { - AtomicSet(Weights.at(index), value); -} - -void TUnistat::Reset() { - TWriteGuard guard(Mutex); - Holes.clear(); - HolesByPriorityAndTags.clear(); - GlobalTags.clear(); -} - -void TUnistat::ResetSignals() { - for (auto& hole : Holes) { - hole.second->ResetSignal(); - } -} diff --git a/library/cpp/unistat/unistat.h b/library/cpp/unistat/unistat.h deleted file mode 100644 index 50acc0b30b5..00000000000 --- a/library/cpp/unistat/unistat.h +++ /dev/null @@ -1,382 +0,0 @@ -#pragma once - -#include <util/generic/singleton.h> -#include <util/generic/string.h> -#include <library/cpp/deprecated/atomic/atomic.h> -#include <util/generic/ptr.h> -#include <util/generic/vector.h> -#include <util/generic/hash.h> -#include <util/generic/maybe.h> -#include <util/generic/set.h> -#include <util/generic/map.h> -#include <util/string/strip.h> -#include <util/system/rwlock.h> - -#include <library/cpp/json/writer/json.h> -#include <library/cpp/unistat/idl/stats.pb.h> - -#include <functional> - -#include "types.h" - -/* - Agregator of Search Statistics - see https://wiki.yandex-team.ru/jandekspoisk/sepe/monitoring/stat-handle - see https://st.yandex-team.ru/SEARCH-948 -*/ - -namespace NUnistat { - struct TPriority { - constexpr explicit TPriority(int priority) - : Priority(priority) - { - } - const int Priority; - }; - - struct TStartValue { - constexpr explicit TStartValue(double startValue) - : StartValue(startValue) - { - } - - const double StartValue; - }; - - class IHole { - public: - virtual int GetPriority() const = 0; - virtual TString GetName() const = 0; - virtual TString GetDescription() const = 0; - virtual TString GetTagsStr() const = 0; - virtual TMap<TString, TString> GetTags() const = 0; - virtual void PrintValue(NJsonWriter::TBuf& json, bool check = true) const = 0; - virtual void PrintInfo(NJsonWriter::TBuf& json) const = 0; - virtual void PrintToPush(NJsonWriter::TBuf& json, bool check = true) const = 0; - virtual void ExportToProto(TInstanceStats& stats) const = 0; - virtual void PushSignal(double signal) = 0; - virtual void ResetSignal() = 0; - virtual void AddTag(const TString& tagName, const TString& tagValue) = 0; - virtual ~IHole() = default; - }; - - class TBaseHole: public IHole { - public: - void AddTag(const TString& tagName, const TString& tagValue) override { - TWriteGuard guard(Mutex); - Tags[tagName] = tagValue; - RebuildTagString(); - } - - protected: - TBaseHole(const TString& name, const TString& description, const TString& suffix, int priority) - : Name(name) - , Description(description) - , Suffix(suffix) - , Priority(priority) - - { - ParseTagsFromName(name); - } - - int GetPriority() const override { - return Priority; - } - - TString GetName() const override { - return Name; - } - - TString GetDescription() const override { - return Description; - } - - TString GetTagsStr() const override { - TReadGuard guard(Mutex); - return TagsJoined; - } - - TMap<TString, TString> GetTags() const override { - TReadGuard guard(Mutex); - return Tags; - } - - TString Name; - const TString Description; - const TString Suffix; - int Priority = 1; - - TRWMutex Mutex; - TMap<TString, TString> Tags; - TString TagsJoined; - - private: - void RebuildTagString() { - TagsJoined.clear(); - TStringOutput ss{TagsJoined}; - for (const auto& tag : Tags) { - ss << tag.first << "=" << tag.second << ";"; - } - } - - void ParseTagsFromName(TStringBuf name) { - TStringBuf tmp = name; - while (TStringBuf tag = tmp.NextTok(';')) { - TStringBuf name, value; - if (tag.TrySplit('=', name, value)) { - TStringBuf nameStr = StripString(name); - TStringBuf valueStr = StripString(value); - if (nameStr) { - Tags[ToString(nameStr)] = ToString(valueStr); - } - } - else { - Name = ToString(StripString(tag)); - } - } - - RebuildTagString(); - } - }; - - class TTypedHole: public TBaseHole { - protected: - TTypedHole(const TString& name, - const TString& description, - const TString& suffix, - EAggregationType type, - int priority, - bool alwaysVisible = false) - : TBaseHole(name, description, suffix, priority) - , Type(type) - , Pushed(alwaysVisible) - { - } - - const EAggregationType Type; - TAtomic Pushed; - }; - - class TFloatHole: public TTypedHole { - public: - TFloatHole(const TString& name, - const TString& description, - const TString& suffix, - EAggregationType type, - int priority, - double startValue, - bool alwaysVisible) - : TTypedHole(name, description, suffix, type, priority, alwaysVisible) - { - Value.Value = startValue; - } - - void PrintValue(NJsonWriter::TBuf& json, bool check = true) const override; - void PrintToPush(NJsonWriter::TBuf& json, bool check) const override; - void PrintInfo(NJsonWriter::TBuf& json) const override; - void ExportToProto(TInstanceStats& stats) const override; - - void PushSignal(double signal) override; - virtual void ResetSignal() override; - - private: - union TValue { - double Value; - TAtomic Atomic; - }; - - TValue Value; - }; - - using TIntervals = TVector<double>; - - const size_t MAX_HISTOGRAM_SIZE = 50; - - // - // Examples: - // Append(7).AppendFlat(2, 3) -> {7, 10, 13} - // FlatRange(4, 1, 5).FlatRange(3, 5, 20) -> {1, 2, 3, 4, 5, 10, 15} - // ExpRange(4, 1, 16).ExpRange(3, 16, 1024) -> {1, 2, 4, 8, 16, 64, 256} - // - class TIntervalsBuilder { - public: - // Append single point - TIntervalsBuilder& Append(double value); - - // Appends @count points at equal intervals: - // [last + step, last + 2 * step, ..., last + count * step] - TIntervalsBuilder& AppendFlat(size_t count, double step); - - // Appends @count points at exponential intervals: - // [last * base, last * base^2, ..., last * base^count] - TIntervalsBuilder& AppendExp(size_t count, double base); - - // Adds @count points at equal intervals, @stop is not included: - // [start, start + d, start + 2d, ..., start + count * d = stop) - TIntervalsBuilder& FlatRange(size_t count, double start, double stop); - - // Adds @count points at exponential intervals, @stop is not included: - // [start, start * q, start * q^2, ..., start * q^count = stop) - TIntervalsBuilder& ExpRange(size_t count, double start, double stop); - - TIntervals Build(); - private: - TIntervals Intervals_; - }; - - class THistogramHole: public TTypedHole { - public: - THistogramHole(const TString& name, const TString& description, const TString& suffix, EAggregationType type, int priority, TIntervals intervals, bool alwaysVisible) - : TTypedHole(name, description, suffix, type, priority, alwaysVisible) - , Intervals(std::move(intervals)) - { - Weights.resize(Intervals.size()); - } - - void PrintValue(NJsonWriter::TBuf& json, bool check = true) const override; - void PrintToPush(NJsonWriter::TBuf& json, bool check) const override; - void PrintInfo(NJsonWriter::TBuf& json) const override; - void ExportToProto(TInstanceStats& stats) const override; - - void PushSignal(double signal) override; - virtual void ResetSignal() override; - - // for tests only - void SetWeight(ui32 index, TAtomicBase value); - - private: - void PrintWeights(NJsonWriter::TBuf& json) const; - - const TIntervals Intervals; - TVector<TAtomicBase> Weights; - }; - - struct THolePriorityComparator { - bool operator()(IHole* lhs, IHole* rhs) const { - // Priorities are sorted in descending order, tags and names in ascending order. - auto lp = lhs->GetPriority(); - auto rp = rhs->GetPriority(); - if (lp != rp) { - return lp > rp; - } - - const auto& lt = lhs->GetTagsStr(); - const auto& rt = rhs->GetTagsStr(); - int cmp = lt.compare(rt); - if (cmp) { - return cmp < 0; - } - - return lhs->GetName() < rhs->GetName(); - } - }; - - using IHolePtr = TAtomicSharedPtr<NUnistat::IHole>; - using TTags = TMap<TString, TString>; -} - -class TUnistat { -public: - static TUnistat& Instance() { - return *Singleton<TUnistat>(); - } - - NUnistat::IHolePtr DrillFloatHole(const TString& name, - const TString& description, - const TString& suffix, - NUnistat::TPriority priority, - NUnistat::TStartValue startValue = NUnistat::TStartValue(0), - EAggregationType type = EAggregationType::Sum, - bool alwaysVisible = false); - - NUnistat::IHolePtr DrillFloatHole(const TString& name, - const TString& suffix, - NUnistat::TPriority priority, - NUnistat::TStartValue startValue = NUnistat::TStartValue(0), - EAggregationType type = EAggregationType::Sum, - bool alwaysVisible = false); - - - NUnistat::IHolePtr DrillHistogramHole(const TString& name, - const TString& description, - const TString& suffix, - NUnistat::TPriority priority, - const NUnistat::TIntervals& intervals, - EAggregationType type = EAggregationType::HostHistogram, - bool alwaysVisible = false); - - NUnistat::IHolePtr DrillHistogramHole(const TString& name, - const TString& suffix, - NUnistat::TPriority priority, - const NUnistat::TIntervals& intervals, - EAggregationType type = EAggregationType::HostHistogram, - bool alwaysVisible = false); - - void AddGlobalTag(const TString& tagName, const TString& tagValue); - - /*It called Unsafe, because assumed, that all holes are initilized before - first usage. Underlying hash is not locked, when invoked */ - template <typename T> - bool PushSignalUnsafe(const T& holename, double signal) { - return PushSignalUnsafeImpl(GetHolename(holename), signal); - } - - template <typename T> - TMaybe<TInstanceStats::TMetric> GetSignalValueUnsafe(const T& holename) { - return GetSignalValueUnsafeImpl(GetHolename(holename)); - } - - template <typename T> - bool ResetSignalUnsafe(const T& holename) { - return ResetSignalUnsafeImpl(GetHolename(holename)); - } - - TString CreateJsonDump(int level, bool allHoles = true) const; - TString CreatePushDump(int level, const NUnistat::TTags& tags = NUnistat::TTags(), ui32 ttl = 0, bool allHoles = false) const; - TString CreateInfoDump(int level) const; - void ExportToProto(TInstanceStats& stats, int level) const; - TString GetSignalDescriptions() const; - TVector<TString> GetHolenames() const; - - /* Erase hole from TUnistat internal state - returns false if name wasn't found */ - bool EraseHole(const TString& name); - - void Reset(); - void ResetSignals(); - -private: - template <typename T> - std::enable_if_t<std::is_same<T, TStringBuf>::value || - std::is_same<T, TString>::value || - std::is_same<T, char*>::value || - std::is_same<T, const char*>::value, - const T&> - GetHolename(const T& holename) { - return holename; - } - - template <typename T> - std::enable_if_t<std::is_enum<T>::value, TString> - GetHolename(const T holename) { - return ToString(holename); - } - - template <typename T> - std::enable_if_t<(std::is_same<char, std::remove_all_extents_t<T>>::value && - std::is_array<T>::value && std::rank<T>::value == 1 && std::extent<T>::value > 1), - TStringBuf> - GetHolename(const T& holename) { - return {holename, std::extent<T>::value - 1}; - } - - bool PushSignalUnsafeImpl(const TStringBuf holename, double signal); - TMaybe<TInstanceStats::TMetric> GetSignalValueUnsafeImpl(const TStringBuf holename); - bool ResetSignalUnsafeImpl(const TStringBuf holename); - -private: - TRWMutex Mutex; - THashMap<TString, NUnistat::IHolePtr> Holes; - TSet<NUnistat::IHole*, NUnistat::THolePriorityComparator> HolesByPriorityAndTags; - TMap<TString, TString> GlobalTags; -}; |