25#include <boost/container/small_vector.hpp>
30#include <unordered_map>
48using MetricTag = std::pair<std::string, std::string>;
78 int32 _overallStatusTimerInterval = 0;
79 bool _enabled =
false;
80 bool _overallStatusTimerTriggered =
false;
91 void ScheduleOverallStatusLog();
93 static std::string FormatInfluxDBValue(
bool value);
95 static std::string FormatInfluxDBValue(T value);
96 static std::string FormatInfluxDBValue(std::string
const& value);
97 static std::string FormatInfluxDBValue(
char const* value);
98 static std::string FormatInfluxDBValue(
double value);
99 static std::string FormatInfluxDBValue(
float value);
100 static std::string FormatInfluxDBValue(std::chrono::nanoseconds value);
102 static std::string FormatInfluxDBTagValue(std::string
const& value);
109 static Metric* instance();
111 void Initialize(std::string
const& realmName,
Trinity::Asio::IoContext& ioContext, std::function<
void()> overallStatusLogger);
112 void LoadFromConfigs();
114 bool ShouldLog(std::string
const& category,
int64 value)
const;
116 template<
class T,
class... Tags>
117 void LogValue(std::string category, T value, Tags&&... tags)
119 using namespace std::chrono;
122 data->
Category = std::move(category);
126 if constexpr (
sizeof...(tags) > 0)
127 (data->
Tags.emplace_back(std::move(tags)), ...);
129 _queuedData.Enqueue(data);
132 void LogEvent(std::string category, std::string title, std::string description);
138#define sMetric Metric::instance()
140template<
typename LoggerType>
145 _logger(
std::forward<LoggerType>(loggerFunc)),
160template<
typename LoggerType>
169#define TC_METRIC_TAG(name, value) MetricTag(name, value)
171#define TC_METRIC_DO_CONCAT(a, b) a ## b
172#define TC_METRIC_CONCAT(a, b) TC_METRIC_DO_CONCAT(a, b)
173#define TC_METRIC_UNIQUE_NAME(name) TC_METRIC_CONCAT(name, __LINE__)
175#if defined PERFORMANCE_PROFILING || defined WITHOUT_METRICS
176#define TC_METRIC_EVENT(category, title, description) ((void)0)
177#define TC_METRIC_VALUE(category, value, ...) ((void)0)
178#define TC_METRIC_TIMER(category, ...) ((void)0)
179#define TC_METRIC_DETAILED_EVENT(category, title, description) ((void)0)
180#define TC_METRIC_DETAILED_TIMER(category, ...) ((void)0)
181#define TC_METRIC_DETAILED_NO_THRESHOLD_TIMER(category, ...) ((void)0)
183# if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS
184#define TC_METRIC_EVENT(category, title, description) \
186 if (sMetric->IsEnabled()) \
187 sMetric->LogEvent(category, title, description); \
189#define TC_METRIC_VALUE(category, value, ...) \
191 if (sMetric->IsEnabled()) \
192 sMetric->LogValue(category, value, ##__VA_ARGS__); \
195#define TC_METRIC_EVENT(category, title, description) \
196 __pragma(warning(push)) \
197 __pragma(warning(disable:4127)) \
199 if (sMetric->IsEnabled()) \
200 sMetric->LogEvent(category, title, description); \
202 __pragma(warning(pop))
203#define TC_METRIC_VALUE(category, value, ...) \
204 __pragma(warning(push)) \
205 __pragma(warning(disable:4127)) \
207 if (sMetric->IsEnabled()) \
208 sMetric->LogValue(category, value, ##__VA_ARGS__); \
210 __pragma(warning(pop))
212#define TC_METRIC_TIMER(category, ...) \
213 auto TC_METRIC_UNIQUE_NAME(__tc_metric_stop_watch) = MakeMetricStopWatch([&](TimePoint start) \
215 sMetric->LogValue(category, std::chrono::steady_clock::now() - start, ##__VA_ARGS__); \
217# if defined WITH_DETAILED_METRICS
218#define TC_METRIC_DETAILED_TIMER(category, ...) \
219 auto TC_METRIC_UNIQUE_NAME(__tc_metric_stop_watch) = MakeMetricStopWatch([&](TimePoint start) \
221 int64 duration = int64(std::chrono::duration_cast<Milliseconds>(std::chrono::steady_clock::now() - start).count()); \
222 std::string category2 = category; \
223 if (sMetric->ShouldLog(category2, duration)) \
224 sMetric->LogValue(std::move(category2), duration, ##__VA_ARGS__); \
226#define TC_METRIC_DETAILED_NO_THRESHOLD_TIMER(category, ...) TC_METRIC_TIMER(category, ##__VA_ARGS__)
227#define TC_METRIC_DETAILED_EVENT(category, title, description) TC_METRIC_EVENT(category, title, description)
229#define TC_METRIC_DETAILED_EVENT(category, title, description) ((void)0)
230#define TC_METRIC_DETAILED_TIMER(category, ...) ((void)0)
231#define TC_METRIC_DETAILED_NO_THRESHOLD_TIMER(category, ...) ((void)0)
std::chrono::system_clock::time_point SystemTimePoint
std::chrono::steady_clock::time_point TimePoint
time_point shorthand typedefs
std::conditional_t< IntrusiveLink !=nullptr, Trinity::Impl::MPSCQueueIntrusive< T, IntrusiveLink >, Trinity::Impl::MPSCQueueNonIntrusive< T > > MPSCQueue
Optional< MetricStopWatch< LoggerType > > MakeMetricStopWatch(LoggerType &&loggerFunc)
std::pair< std::string, std::string > MetricTag
boost::container::small_vector< MetricTag, 2 > MetricTagsVector
std::optional< T > Optional
Optional helper class to wrap optional values within.
MetricStopWatch(LoggerType &&loggerFunc)
std::unique_ptr< std::iostream > _dataStream
void LogValue(std::string category, T value, Tags &&... tags)
std::string _databaseName
std::unique_ptr< Trinity::Asio::DeadlineTimer > _overallStatusTimer
std::iostream & GetDataStream()
std::function< void()> _overallStatusLogger
MPSCQueue< MetricData, &MetricData::QueueLink > _queuedData
std::unique_ptr< Trinity::Asio::DeadlineTimer > _batchTimer
std::unordered_map< std::string, int64 > _thresholds
SystemTimePoint Timestamp
std::string ValueOrEventText
std::atomic< MetricData * > QueueLink