#pragma once #include #include #include /** Позволяет считать количество одновременно происходящих событий или текущее значение какой-либо метрики. * - для высокоуровневого профайлинга. * * Также смотрите ProfileEvents.h * В ProfileEvents считается общее количество произошедших (точечных) событий - например, сколько раз были выполнены запросы. * В CurrentMetrics считается количество одновременных событий - например, сколько сейчас одновременно выполняется запросов, * или текущее значение метрики - например, величина отставания реплики в секундах. */ #define APPLY_FOR_METRICS(M) \ M(Query) \ M(Merge) \ M(ReplicatedFetch) \ M(ReplicatedSend) \ M(ReplicatedChecks) \ M(BackgroundPoolTask) \ M(DiskSpaceReservedForMerge) \ M(DistributedSend) \ M(QueryPreempted) \ M(TCPConnection) \ M(HTTPConnection) \ M(InterserverConnection) \ M(OpenFileForRead) \ M(OpenFileForWrite) \ M(Read) \ M(Write) \ M(SendExternalTables) \ M(QueryThread) \ M(ReadonlyReplica) \ M(MemoryTracking) \ \ M(END) namespace CurrentMetrics { /// Виды метрик. enum Metric { #define M(NAME) NAME, APPLY_FOR_METRICS(M) #undef M }; /// Получить текстовое описание метрики по его enum-у. inline const char * getDescription(Metric event) { static const char * descriptions[] = { #define M(NAME) #NAME, APPLY_FOR_METRICS(M) #undef M }; return descriptions[event]; } using Value = int64_t; /// Счётчики - текущие значения метрик. extern std::atomic values[END]; /// Выставить значение указанной метрики. inline void set(Metric metric, Value value) { values[metric] = value; } /// Прибавить величину к значению указанной метрики. Вы затем должны вычесть величину самостоятельно. Или см. ниже class Increment. inline void add(Metric metric, Value value = 1) { values[metric] += value; } inline void sub(Metric metric, Value value = 1) { add(metric, -value); } /// На время жизни объекта, увеличивает указанное значение на указанную величину. class Increment { private: std::atomic * what; Value amount; Increment(std::atomic * what, Value amount) : what(what), amount(amount) { *what += amount; } public: Increment(Metric metric, Value amount = 1) : Increment(&values[metric], amount) {} ~Increment() { if (what) *what -= amount; } Increment(Increment && old) { *this = std::move(old); } Increment & operator= (Increment && old) { what = old.what; amount = old.amount; old.what = nullptr; return *this; } void changeTo(Value new_amount) { *what += new_amount - amount; amount = new_amount; } /// Уменьшить значение раньше вызова деструктора. void destroy() { *what -= amount; what = nullptr; } }; } #undef APPLY_FOR_METRICS