blob: 2c595b1d5ad93ecc44e58fe2c4c7a4aa6c109d5d [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>
#include <cstdlib>
#include <ts/ts.h>
namespace
{
#define PINAME "test_TSHttpSsnInfo"
char PIName[] = PINAME;
DbgCtl dbg_ctl{PIName};
// NOTE: It's important to flush this after writing so that a gold test using this plugin can examine the log before TS
// terminates.
//
std::fstream logFile;
void
handle_ssn_close(TSHttpSsn ssn)
{
if (TSHttpSsnClientProtocolStackContains(ssn, "h2")) {
TSMgmtInt count[11];
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[0], 0);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[1], 1);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[2], 2);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[3], 3);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[4], 4);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[5], 5);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[6], 6);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[7], 7);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[8], 8);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[9], 9);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[10], TS_SSN_INFO_RECEIVED_FRAME_COUNT_H2_UNKNOWN);
logFile << "H2 Frames Received:" << "D" << count[0] << "," << "H" << count[1] << "," << "PR" << count[2] << "," << "RS"
<< count[3] << "," << "S" << count[4] << "," << "PP" << count[5] << "," << "P" << count[6] << "," << "G" << count[7]
<< "," << "WU" << count[8] << "," << "C" << count[9] << "," << "U" << count[10] << std::endl;
} else {
TSMgmtInt count[15];
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[0], 0);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[1], 1);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[2], 2);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[3], 3);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[4], 4);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[5], 5);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[6], 6);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[7], 7);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[8], 8);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[9], 9);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[10], 10);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[11], 11);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[12], 12);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[13], 13);
TSHttpSsnInfoIntGet(ssn, TS_SSN_INFO_RECEIVED_FRAME_COUNT, &count[14], TS_SSN_INFO_RECEIVED_FRAME_COUNT_H2_UNKNOWN);
logFile << "H3 Frames Received:" << "D" << count[0] << "," << "H" << count[1] << "," << "Ra" << count[2] << "," << "CP"
<< count[3] << "," << "S" << count[4] << "," << "PP" << count[5] << "," << "Rb" << count[6] << "," << "G" << count[7]
<< "," << "Rc" << count[8] << "," << "Rd" << count[9] << "," << "UND" << count[10] << "," << "UND" << count[11] << ","
<< "UND" << count[12] << "," << "MPI" << count[13] << "," << "U" << count[14] << std::endl;
}
TSHttpSsnReenable(ssn, TS_EVENT_HTTP_CONTINUE);
}
int
globalContFunc(TSCont, TSEvent event, void *eventData)
{
logFile << "Global: event=" << TSHttpEventNameLookup(event) << std::endl;
Dbg(dbg_ctl, "Global: event=%s(%d) eventData=%p", TSHttpEventNameLookup(event), event, eventData);
switch (event) {
case TS_EVENT_HTTP_SSN_CLOSE:
handle_ssn_close(static_cast<TSHttpSsn>(eventData));
break;
default:
break;
} // end switch
return 0;
}
TSCont gCont;
} // end anonymous namespace
void
TSPluginInit(int /* argc ATS_UNUSED */, const char ** /* argv ATS_UNUSED */)
{
TSPluginRegistrationInfo info;
info.plugin_name = PIName;
info.vendor_name = "Apache Software Foundation";
info.support_email = "dev@trafficserver.apache.org";
if (TSPluginRegister(&info) != TS_SUCCESS) {
TSError(PINAME ": Plugin registration failed");
return;
}
const char *fileSpec = std::getenv("OUTPUT_FILE");
if (nullptr == fileSpec) {
TSError(PINAME ": Environment variable OUTPUT_FILE not found.");
return;
}
// Disable output buffering for logFile, so that explicit flushing is not necessary.
logFile.rdbuf()->pubsetbuf(nullptr, 0);
logFile.open(fileSpec, std::ios::out);
if (!logFile.is_open()) {
TSError(PINAME ": could not open log file \"%s\"", fileSpec);
return;
}
// Mutex to protect the logFile object.
TSMutex mtx = TSMutexCreate();
gCont = TSContCreate(globalContFunc, mtx);
TSHttpHookAdd(TS_HTTP_SSN_CLOSE_HOOK, gCont);
}