25#include <boost/algorithm/string/replace.hpp>
26#include <boost/asio/ip/tcp.hpp>
30 _dataStream = std::make_unique<boost::asio::ip::tcp::iostream>();
32 _batchTimer = std::make_unique<Trinity::Asio::DeadlineTimer>(ioContext);
40 auto& stream =
static_cast<boost::asio::ip::tcp::iostream&
>(
GetDataStream());
42 auto error = stream.error();
45 TC_LOG_ERROR(
"metric",
"Error connecting to '{}:{}', disabling Metric. Error message : {}",
73 std::vector<std::string> thresholdSettings =
sConfigMgr->GetKeysByString(
"Metric.Threshold.");
74 for (std::string
const& thresholdSetting : thresholdSettings)
76 int thresholdValue =
sConfigMgr->GetIntDefault(thresholdSetting, 0);
77 std::string thresholdName = thresholdSetting.substr(strlen(
"Metric.Threshold."));
85 std::string connectionInfo =
sConfigMgr->GetStringDefault(
"Metric.ConnectionInfo",
"");
86 if (connectionInfo.empty())
88 TC_LOG_ERROR(
"metric",
"'Metric.ConnectionInfo' not specified in configuration file.");
92 std::vector<std::string_view> tokens =
Trinity::Tokenize(connectionInfo,
';',
true);
93 if (tokens.size() != 3)
95 TC_LOG_ERROR(
"metric",
"'Metric.ConnectionInfo' specified with wrong format in configuration file.");
100 _port.assign(tokens[1]);
123 return value >= threshold->second;
128 using namespace std::chrono;
131 data->
Category = std::move(category);
134 data->
Title = std::move(title);
142 using namespace std::chrono;
144 std::stringstream batchedData;
146 bool firstLoop =
true;
173 batchedData << std::to_string(duration_cast<nanoseconds>(data->
Timestamp.time_since_epoch()).count());
180 if (batchedData.tellp() == std::streampos(0))
192 GetDataStream() <<
"Content-Type: application/octet-stream\r\n";
195 GetDataStream() <<
"Content-Length: " << std::to_string(batchedData.tellp()) <<
"\r\n\r\n";
198 std::string http_version;
200 unsigned int status_code = 0;
202 if (status_code != 204)
204 TC_LOG_ERROR(
"metric",
"Error sending data, returned HTTP code: {}", status_code);
208 std::string status_description;
212 while (std::getline(
GetDataStream(), header) && header !=
"\r")
213 if (header ==
"Connection: close\r")
214 static_cast<boost::asio::ip::tcp::iostream&
>(
GetDataStream()).close();
228 static_cast<boost::asio::ip::tcp::iostream&
>(
GetDataStream()).close();
264 return value ?
"t" :
"f";
270 return std::to_string(value) +
'i';
275 return '"' + boost::replace_all_copy(value,
"\"",
"\\\"") +
'"';
285 return std::to_string(value);
296 return boost::replace_all_copy(value,
" ",
"\\ ");
#define TC_LOG_ERROR(filterType__,...)
std::pair< std::string, std::string > MetricTag
std::unique_ptr< std::iostream > _dataStream
static std::string FormatInfluxDBTagValue(std::string const &value)
std::string _databaseName
static Metric * instance()
void ScheduleOverallStatusLog()
bool _overallStatusTimerTriggered
int32 _overallStatusTimerInterval
void Initialize(std::string const &realmName, Trinity::Asio::IoContext &ioContext, std::function< void()> overallStatusLogger)
std::unique_ptr< Trinity::Asio::DeadlineTimer > _overallStatusTimer
std::iostream & GetDataStream()
std::function< void()> _overallStatusLogger
MPSCQueue< MetricData, &MetricData::QueueLink > _queuedData
bool ShouldLog(std::string const &category, int64 value) const
static std::string FormatInfluxDBValue(bool value)
std::unique_ptr< Trinity::Asio::DeadlineTimer > _batchTimer
std::unordered_map< std::string, int64 > _thresholds
void LogEvent(std::string category, std::string title, std::string description)
decltype(auto) get_io_context(T &&ioObject)
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
SystemTimePoint Timestamp
std::string ValueOrEventText