29#include <unordered_map>
48using MetricTag = std::pair<std::string, std::string>;
77 int32 _overallStatusTimerInterval = 0;
78 bool _enabled =
false;
79 bool _overallStatusTimerTriggered =
false;
90 void ScheduleOverallStatusLog();
92 static std::string FormatInfluxDBValue(
bool value);
94 static std::string FormatInfluxDBValue(T value);
95 static std::string FormatInfluxDBValue(std::string
const& value);
96 static std::string FormatInfluxDBValue(
char const* value);
97 static std::string FormatInfluxDBValue(
double value);
98 static std::string FormatInfluxDBValue(
float value);
99 static std::string FormatInfluxDBValue(std::chrono::nanoseconds value);
101 static std::string FormatInfluxDBTagValue(std::string
const& value);
108 static Metric* instance();
111 void LoadFromConfigs();
113 bool ShouldLog(std::string
const& category,
int64 value)
const;
115 template<
class T,
class... TagsList>
116 void LogValue(std::string category, T value, TagsList&&... tags)
118 using namespace std::chrono;
121 data->
Category = std::move(category);
125 if constexpr (
sizeof...(tags) > 0)
127 data->
Tags.emplace();
128 if constexpr (
sizeof...(tags) > 2)
130 decltype(
auto) tagsVector = data->
Tags->emplace<1>();
131 (tagsVector.emplace_back(std::move(tags)), ...);
135 decltype(
auto) tagsArray = data->
Tags->emplace<0>();
136 tagsArray = { std::move(tags)... };
140 _queuedData.Enqueue(data);
143 void LogEvent(std::string category, std::string title, std::string description);
149#define sMetric Metric::instance()
151template<
typename LoggerType>
156 _logger(
std::forward<LoggerType>(loggerFunc)),
171template<
typename LoggerType>
180#define TC_METRIC_TAG(name, value) MetricTag(name, value)
182#define TC_METRIC_DO_CONCAT(a, b) a ## b
183#define TC_METRIC_CONCAT(a, b) TC_METRIC_DO_CONCAT(a, b)
184#define TC_METRIC_UNIQUE_NAME(name) TC_METRIC_CONCAT(name, __LINE__)
186#if defined PERFORMANCE_PROFILING || defined WITHOUT_METRICS
187#define TC_METRIC_EVENT(category, title, description) ((void)0)
188#define TC_METRIC_VALUE(category, value, ...) ((void)0)
189#define TC_METRIC_TIMER(category, ...) ((void)0)
190#define TC_METRIC_DETAILED_EVENT(category, title, description) ((void)0)
191#define TC_METRIC_DETAILED_TIMER(category, ...) ((void)0)
192#define TC_METRIC_DETAILED_NO_THRESHOLD_TIMER(category, ...) ((void)0)
194# if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS
195#define TC_METRIC_EVENT(category, title, description) \
197 if (sMetric->IsEnabled()) \
198 sMetric->LogEvent(category, title, description); \
200#define TC_METRIC_VALUE(category, value, ...) \
202 if (sMetric->IsEnabled()) \
203 sMetric->LogValue(category, value, ##__VA_ARGS__); \
206#define TC_METRIC_EVENT(category, title, description) \
207 __pragma(warning(push)) \
208 __pragma(warning(disable:4127)) \
210 if (sMetric->IsEnabled()) \
211 sMetric->LogEvent(category, title, description); \
213 __pragma(warning(pop))
214#define TC_METRIC_VALUE(category, value, ...) \
215 __pragma(warning(push)) \
216 __pragma(warning(disable:4127)) \
218 if (sMetric->IsEnabled()) \
219 sMetric->LogValue(category, value, ##__VA_ARGS__); \
221 __pragma(warning(pop))
223#define TC_METRIC_TIMER(category, ...) \
224 auto TC_METRIC_UNIQUE_NAME(__tc_metric_stop_watch) = MakeMetricStopWatch([&](TimePoint start) \
226 sMetric->LogValue(category, std::chrono::steady_clock::now() - start, ##__VA_ARGS__); \
228# if defined WITH_DETAILED_METRICS
229#define TC_METRIC_DETAILED_TIMER(category, ...) \
230 auto TC_METRIC_UNIQUE_NAME(__tc_metric_stop_watch) = MakeMetricStopWatch([&](TimePoint start) \
232 int64 duration = int64(std::chrono::duration_cast<Milliseconds>(std::chrono::steady_clock::now() - start).count()); \
233 std::string category2 = category; \
234 if (sMetric->ShouldLog(category2, duration)) \
235 sMetric->LogValue(std::move(category2), duration, ##__VA_ARGS__); \
237#define TC_METRIC_DETAILED_NO_THRESHOLD_TIMER(category, ...) TC_METRIC_TIMER(category, ##__VA_ARGS__)
238#define TC_METRIC_DETAILED_EVENT(category, title, description) TC_METRIC_EVENT(category, title, description)
240#define TC_METRIC_DETAILED_EVENT(category, title, description) ((void)0)
241#define TC_METRIC_DETAILED_TIMER(category, ...) ((void)0)
242#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
std::optional< T > Optional
Optional helper class to wrap optional values within.
MetricStopWatch(LoggerType &&loggerFunc)
std::unique_ptr< std::iostream > _dataStream
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
void LogValue(std::string category, T value, TagsList &&... tags)
std::unordered_map< std::string, int64 > _thresholds
void Update(VignetteData &vignette, WorldObject const *owner)
SystemTimePoint Timestamp
std::string ValueOrEventText
Optional< std::variant< std::array< MetricTag, 2 >, std::vector< MetricTag > > > Tags
std::atomic< MetricData * > QueueLink