123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- #pragma once
- #include <library/cpp/monlib/counters/counters.h>
- #include <library/cpp/monlib/metrics/histogram_collector.h>
- #include <library/cpp/threading/light_rw_lock/lightrwlock.h>
- #include <library/cpp/containers/stack_vector/stack_vec.h>
- #include <util/generic/cast.h>
- #include <util/generic/map.h>
- #include <util/generic/ptr.h>
- #include <util/string/cast.h>
- #include <util/system/rwlock.h>
- #include <functional>
- namespace NMonitoring {
- struct TCounterForPtr;
- struct TDynamicCounters;
- struct ICountableConsumer;
- struct TCountableBase: public TAtomicRefCount<TCountableBase> {
- // Private means that the object must not be serialized unless the consumer
- // has explicitly specified this by setting its Visibility to Private.
- //
- // Works only for the methods that accept ICountableConsumer
- enum class EVisibility: ui8 {
- Unspecified,
- Public,
- Private,
- };
- virtual ~TCountableBase() {
- }
- virtual void Accept(
- const TString& labelName, const TString& labelValue,
- ICountableConsumer& consumer) const = 0;
- virtual EVisibility Visibility() const {
- return Visibility_;
- }
- protected:
- EVisibility Visibility_{EVisibility::Unspecified};
- };
- inline bool IsVisible(TCountableBase::EVisibility myLevel, TCountableBase::EVisibility consumerLevel) {
- if (myLevel == TCountableBase::EVisibility::Private
- && consumerLevel != TCountableBase::EVisibility::Private) {
- return false;
- }
- return true;
- }
- struct ICountableConsumer {
- virtual ~ICountableConsumer() {
- }
- virtual void OnCounter(
- const TString& labelName, const TString& labelValue,
- const TCounterForPtr* counter) = 0;
- virtual void OnHistogram(
- const TString& labelName, const TString& labelValue,
- IHistogramSnapshotPtr snapshot, bool derivative) = 0;
- virtual void OnGroupBegin(
- const TString& labelName, const TString& labelValue,
- const TDynamicCounters* group) = 0;
- virtual void OnGroupEnd(
- const TString& labelName, const TString& labelValue,
- const TDynamicCounters* group) = 0;
- virtual TCountableBase::EVisibility Visibility() const {
- return TCountableBase::EVisibility::Unspecified;
- }
- };
- #ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable : 4522) // multiple assignment operators specified
- #endif // _MSC_VER
- struct TCounterForPtr: public TDeprecatedCounter, public TCountableBase {
- TCounterForPtr(bool derivative = false, EVisibility vis = EVisibility::Public)
- : TDeprecatedCounter(0ULL, derivative)
- {
- Visibility_ = vis;
- }
- TCounterForPtr(const TCounterForPtr&) = delete;
- TCounterForPtr& operator=(const TCounterForPtr& other) = delete;
- void Accept(
- const TString& labelName, const TString& labelValue,
- ICountableConsumer& consumer) const override {
- if (IsVisible(Visibility(), consumer.Visibility())) {
- consumer.OnCounter(labelName, labelValue, this);
- }
- }
- TCountableBase::EVisibility Visibility() const override {
- return Visibility_;
- }
- using TDeprecatedCounter::operator++;
- using TDeprecatedCounter::operator--;
- using TDeprecatedCounter::operator+=;
- using TDeprecatedCounter::operator-=;
- using TDeprecatedCounter::operator=;
- using TDeprecatedCounter::operator!;
- };
- struct TExpiringCounter: public TCounterForPtr {
- explicit TExpiringCounter(bool derivative = false, EVisibility vis = EVisibility::Public)
- : TCounterForPtr{derivative}
- {
- Visibility_ = vis;
- }
- void Reset() {
- TDeprecatedCounter::operator=(0);
- }
- };
- struct THistogramCounter: public TCountableBase {
- explicit THistogramCounter(
- IHistogramCollectorPtr collector, bool derivative = true, EVisibility vis = EVisibility::Public)
- : Collector_(std::move(collector))
- , Derivative_(derivative)
- {
- Visibility_ = vis;
- }
- void Collect(i64 value) {
- Collector_->Collect(value);
- }
- void Collect(i64 value, ui64 count) {
- Collector_->Collect(value, count);
- }
- void Collect(double value, ui64 count) {
- Collector_->Collect(value, count);
- }
- void Collect(const IHistogramSnapshot& snapshot) {
- Collector_->Collect(snapshot);
- }
- void Accept(
- const TString& labelName, const TString& labelValue,
- ICountableConsumer& consumer) const override
- {
- if (IsVisible(Visibility(), consumer.Visibility())) {
- consumer.OnHistogram(labelName, labelValue, Collector_->Snapshot(), Derivative_);
- }
- }
- void Reset() {
- Collector_->Reset();
- }
- IHistogramSnapshotPtr Snapshot() const {
- return Collector_->Snapshot();
- }
- private:
- IHistogramCollectorPtr Collector_;
- bool Derivative_;
- };
- struct TExpiringHistogramCounter: public THistogramCounter {
- using THistogramCounter::THistogramCounter;
- };
- using THistogramPtr = TIntrusivePtr<THistogramCounter>;
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
- struct TDynamicCounters;
- typedef TIntrusivePtr<TDynamicCounters> TDynamicCounterPtr;
- struct TDynamicCounters: public TCountableBase {
- public:
- using TCounterPtr = TIntrusivePtr<TCounterForPtr>;
- using TOnLookupPtr = void (*)(const char *methodName, const TString &name, const TString &value);
- private:
- TRWMutex Lock;
- TCounterPtr LookupCounter; // Counts lookups by name
- TOnLookupPtr OnLookup = nullptr; // Called on each lookup if not nullptr, intended for lightweight tracing.
- typedef TIntrusivePtr<TCountableBase> TCountablePtr;
- struct TChildId {
- TString LabelName;
- TString LabelValue;
- TChildId() {
- }
- TChildId(const TString& labelName, const TString& labelValue)
- : LabelName(labelName)
- , LabelValue(labelValue)
- {
- }
- auto AsTuple() const {
- return std::make_tuple(std::cref(LabelName), std::cref(LabelValue));
- }
- friend bool operator <(const TChildId& x, const TChildId& y) {
- return x.AsTuple() < y.AsTuple();
- }
- friend bool operator ==(const TChildId& x, const TChildId& y) {
- return x.AsTuple() == y.AsTuple();
- }
- friend bool operator !=(const TChildId& x, const TChildId& y) {
- return x.AsTuple() != y.AsTuple();
- }
- };
- using TCounters = TMap<TChildId, TCountablePtr>;
- using TLabels = TVector<TChildId>;
- /// XXX: hack for deferred removal of expired counters. Remove once Output* functions are not used for serialization
- mutable TCounters Counters;
- mutable TAtomic ExpiringCount = 0;
- public:
- TDynamicCounters(TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
- TDynamicCounters(const TDynamicCounters *origin)
- : LookupCounter(origin->LookupCounter)
- , OnLookup(origin->OnLookup)
- {}
- ~TDynamicCounters() override;
- // This counter allows to track lookups by name within the whole subtree
- void SetLookupCounter(TCounterPtr lookupCounter) {
- TWriteGuard g(Lock);
- LookupCounter = lookupCounter;
- }
- void SetOnLookup(TOnLookupPtr onLookup) {
- TWriteGuard g(Lock);
- OnLookup = onLookup;
- }
- TWriteGuard LockForUpdate(const char *method, const TString& name, const TString& value) {
- auto res = TWriteGuard(Lock);
- if (LookupCounter) {
- ++*LookupCounter;
- }
- if (OnLookup) {
- OnLookup(method, name, value);
- }
- return res;
- }
- TStackVec<TCounters::value_type, 256> ReadSnapshot() const {
- RemoveExpired();
- TReadGuard g(Lock);
- TStackVec<TCounters::value_type, 256> items(Counters.begin(), Counters.end());
- return items;
- }
- TCounterPtr GetCounter(
- const TString& value,
- bool derivative = false,
- TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
- TCounterPtr GetNamedCounter(
- const TString& name,
- const TString& value,
- bool derivative = false,
- TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
- THistogramPtr GetHistogram(
- const TString& value,
- IHistogramCollectorPtr collector,
- bool derivative = true,
- TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
- THistogramPtr GetNamedHistogram(
- const TString& name,
- const TString& value,
- IHistogramCollectorPtr collector,
- bool derivative = true,
- TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
- // These counters will be automatically removed from the registry
- // when last reference to the counter expires.
- TCounterPtr GetExpiringCounter(
- const TString& value,
- bool derivative = false,
- TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
- TCounterPtr GetExpiringNamedCounter(
- const TString& name,
- const TString& value,
- bool derivative = false,
- TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
- THistogramPtr GetExpiringHistogram(
- const TString& value,
- IHistogramCollectorPtr collector,
- bool derivative = true,
- TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
- THistogramPtr GetExpiringNamedHistogram(
- const TString& name,
- const TString& value,
- IHistogramCollectorPtr collector,
- bool derivative = true,
- TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public);
- TCounterPtr FindCounter(const TString& value) const;
- TCounterPtr FindNamedCounter(const TString& name, const TString& value) const;
- THistogramPtr FindHistogram(const TString& value) const;
- THistogramPtr FindNamedHistogram(const TString& name,const TString& value) const;
- void RemoveCounter(const TString &value);
- bool RemoveNamedCounter(const TString& name, const TString &value);
- void RemoveSubgroupChain(const std::vector<std::pair<TString, TString>>& chain);
- TIntrusivePtr<TDynamicCounters> GetSubgroup(const TString& name, const TString& value);
- TIntrusivePtr<TDynamicCounters> FindSubgroup(const TString& name, const TString& value) const;
- bool RemoveSubgroup(const TString& name, const TString& value);
- void ReplaceSubgroup(const TString& name, const TString& value, TIntrusivePtr<TDynamicCounters> subgroup);
- // Move all counters from specified subgroup and remove the subgroup.
- void MergeWithSubgroup(const TString& name, const TString& value);
- // Recursively reset all/deriv counters to 0.
- void ResetCounters(bool derivOnly = false);
- void RegisterSubgroup(const TString& name,
- const TString& value,
- TIntrusivePtr<TDynamicCounters> subgroup);
- void OutputHtml(IOutputStream& os) const;
- void EnumerateSubgroups(const std::function<void(const TString& name, const TString& value)>& output) const;
- // mostly for debugging purposes -- use accept with encoder instead
- void OutputPlainText(IOutputStream& os, const TString& indent = "") const;
- void Accept(
- const TString& labelName, const TString& labelValue,
- ICountableConsumer& consumer) const override;
- private:
- TCounters Resign() {
- TCounters counters;
- TWriteGuard g(Lock);
- Counters.swap(counters);
- return counters;
- }
- void RegisterCountable(const TString& name, const TString& value, TCountablePtr countable);
- void RemoveExpired() const;
- template <bool expiring, class TCounterType, class... TArgs>
- TCountablePtr GetNamedCounterImpl(const TString& name, const TString& value, TArgs&&... args);
- template <class TCounterType>
- TCountablePtr FindNamedCounterImpl(const TString& name, const TString& value) const;
- };
- }
|