11 typedef std::array<std::array<XrdHttpMon::HttpInfo, XrdHttpMon::StatusCodes::sc_Count>, XrdHttpReq::ReqType::rtCount>
18 std::chrono::seconds XrdHttpMon::flushPeriod{0};
20 bool XrdHttpMon::hasGStream =
false;
21 bool XrdHttpMon::hasMonRoll =
false;
22 bool XrdHttpMon::isInitialized =
false;
24 RAtomic_uint64_t XrdHttpMon::verbCounters[XrdHttpReq::ReqType::rtCount] = {0};
25 RAtomic_uint64_t XrdHttpMon::statusCounters[XrdHttpMon::StatusCodes::sc_Count] = {0};
29 std::vector<XrdMonRoll::Item> XrdHttpMon::statsSchema = {
76 XrdHttpMon::gStream = gStream;
77 XrdHttpMon::mrollP = mrollP;
79 if (gStream !=
nullptr){
81 flushPeriod = std::chrono::seconds(gStream->
GetAutoFlush());
84 if (mrollP !=
nullptr) {
92 void XrdHttpMon::Report() {
93 std::string
json = GetMonitoringJson();
95 eDest.
Emsg(
"HttpMon",
"Gstream Buffer Rejected");
101 std::this_thread::sleep_for(flushPeriod);
109 if (!isInitialized)
return;
112 if (code < 200)
return;
114 std::chrono::steady_clock::duration duration{};
116 const auto now = std::chrono::steady_clock::now();
123 if (req.
request >= XrdHttpReq::ReqType::rtCount || req.
request < 0) {
124 eDest.
Emsg(
"Record",
"ERROR: Record called with invalid request type");
130 RecordGStreamCount(req.
request, statusCode);
131 RecordMonRollVerb(req.
request);
136 RecordGStreamSuccess(req.
request, statusCode, duration);
137 RecordMonRollStatus(statusCode);
142 RecordGStreamErrNet(req.
request, statusCode, duration);
143 RecordMonRollStatus(statusCode);
148 RecordGStreamErrProt(req.
request, statusCode, duration);
149 RecordMonRollStatus(statusCode);
154 eDest.
Emsg(
"Record",
"ERROR: Record called after state was set to DONE");
160 auto& info = statsInfo[op][sc];
164 void XrdHttpMon::RecordSuccess(
XrdHttpReq::ReqType op, StatusCodes sc, std::chrono::steady_clock::duration duration) {
165 auto& info = statsInfo[op][sc];
167 info.duration_us += std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
170 void XrdHttpMon::RecordErrProt(
XrdHttpReq::ReqType op, StatusCodes sc, std::chrono::steady_clock::duration duration) {
171 auto& info = statsInfo[op][sc];
173 info.duration_us += std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
176 void XrdHttpMon::RecordErrNet(
XrdHttpReq::ReqType op, StatusCodes sc, std::chrono::steady_clock::duration duration) {
177 auto& info = statsInfo[op][sc];
178 info.error_network++;
179 info.duration_us += std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
184 std::string XrdHttpMon::GetMonitoringJson() {
185 std::ostringstream oss;
189 for (
size_t op = 0; op < XrdHttpReq::ReqType::rtCount; ++op) {
191 for (
size_t sc = 0; sc < StatusCodes::sc_Count; ++sc) {
192 auto& info = statsInfo[op][sc];
194 uint64_t total_count = info.count;
195 if (total_count == 0)
continue;
197 uint64_t error_count_network = info.error_network;
198 uint64_t error_count_xrootd = info.error_xrootd;
199 uint64_t success_count = info.success;
200 double duration_us = std::chrono::duration<double>(std::chrono::microseconds(
static_cast<uint64_t
>(info.duration_us))).count();
202 std::string key =
"HTTP_" + opName +
"_" + GetStatusCodeString(
static_cast<StatusCodes>(sc));
204 if (!first) oss <<
",";
207 oss <<
"\"" << key <<
"\":{";
208 oss <<
"\"count\":" << total_count <<
",";
209 oss <<
"\"errors_network\":" << error_count_network <<
",";
210 oss <<
"\"errors_xrootd\":" << error_count_xrootd <<
",";
211 oss <<
"\"success\":" << success_count <<
",";
212 oss <<
"\"duration_seconds\":" << duration_us;
223 case XrdHttpReq::ReqType::rtDELETE:
225 case XrdHttpReq::ReqType::rtHEAD:
227 case XrdHttpReq::ReqType::rtGET:
229 case XrdHttpReq::ReqType::rtMKCOL:
231 case XrdHttpReq::ReqType::rtMOVE:
233 case XrdHttpReq::ReqType::rtOPTIONS:
235 case XrdHttpReq::ReqType::rtPROPFIND:
237 case XrdHttpReq::ReqType::rtPUT:
239 case XrdHttpReq::ReqType::rtCOPY:
241 case XrdHttpReq::ReqType::rtMalformed:
248 std::string XrdHttpMon::GetStatusCodeString(StatusCodes sc) {
XrdSysError eDest(0, "HttpMon")
std::array< std::array< XrdHttpMon::HttpInfo, XrdHttpMon::StatusCodes::sc_Count >, XrdHttpReq::ReqType::rtCount > StatsMatrix
static void Record(XrdHttpReq &req, int code)
static void Initialize(XrdSysLogger *logP, XrdXrootdGStream *gStream, XrdMonRoll *mrollP)
static void * Start(void *)
ReqType request
The request we got.
ReqType
These are the HTTP/DAV requests that we support.
std::chrono::steady_clock::time_point startTime
bool Register(rollType setType, const char *setName, std::vector< Item > &iVec)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdSysLogger * logger(XrdSysLogger *lp=0)
bool Insert(const char *data, int dlen)