aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/unistat
diff options
context:
space:
mode:
authorqrort <qrort@yandex-team.com>2022-12-02 11:31:25 +0300
committerqrort <qrort@yandex-team.com>2022-12-02 11:31:25 +0300
commitb1f4ffc9c8abff3ba58dc1ec9a9f92d2f0de6806 (patch)
tree2a23209faf0fea5586a6d4b9cee60d1b318d29fe /library/cpp/unistat
parent559174a9144de40d6bb3997ea4073c82289b4974 (diff)
downloadydb-b1f4ffc9c8abff3ba58dc1ec9a9f92d2f0de6806.tar.gz
remove kikimr/driver DEPENDS
Diffstat (limited to 'library/cpp/unistat')
-rw-r--r--library/cpp/unistat/idl/stats.proto19
-rw-r--r--library/cpp/unistat/raii.cpp1
-rw-r--r--library/cpp/unistat/raii.h120
-rw-r--r--library/cpp/unistat/types.h15
-rw-r--r--library/cpp/unistat/unistat.cpp461
-rw-r--r--library/cpp/unistat/unistat.h382
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;
-};