h2load: Add qlog output support

This commit is contained in:
Hajime Fujita 2021-03-12 19:12:46 +00:00 committed by Tatsuhiro Tsujikawa
parent 1eb818b64c
commit 48e10c57da
3 changed files with 60 additions and 1 deletions

View File

@ -111,6 +111,7 @@ Config::Config()
encoder_header_table_size(4_k),
data_fd(-1),
log_fd(-1),
qlog_file_base(),
port(0),
default_port(0),
connect_to_port(0),
@ -2200,6 +2201,13 @@ Options:
response time when using one worker thread, but may
appear slightly out of order with multiple threads due
to buffering. Status code is -1 for failed streams.
--qlog-file-base=<PATH>
Enable qlog output and specify base file name for qlogs.
Qlog is emitted for each connection.
For a given base name "base", each output file name
becomes "base.M.N.qlog" where M is worker ID and N is
client ID (e.g. "base.0.3.qlog").
Only effective in QUIC runs.
--connect-to=<HOST>[:<PORT>]
Host and port to connect instead of using the authority
in <URI>.
@ -2238,6 +2246,7 @@ int main(int argc, char **argv) {
std::string datafile;
std::string logfile;
std::string qlog_base;
bool nreqs_set_manually = false;
while (1) {
static int flag = 0;
@ -2274,6 +2283,7 @@ int main(int argc, char **argv) {
{"groups", required_argument, &flag, 13},
{"tls13-ciphers", required_argument, &flag, 14},
{"no-udp-gso", no_argument, &flag, 15},
{"qlog-file-base", required_argument, &flag, 16},
{nullptr, 0, nullptr, 0}};
int option_index = 0;
auto c = getopt_long(argc, argv,
@ -2536,6 +2546,10 @@ int main(int argc, char **argv) {
// --no-udp-gso
config.no_udp_gso = true;
break;
case 16:
// --qlog-file-base
qlog_base = optarg;
break;
}
break;
default:
@ -2720,6 +2734,14 @@ int main(int argc, char **argv) {
}
}
if (!qlog_base.empty()) {
if (!config.is_quic()) {
std::cerr << "Warning: --qlog-file-base: only effective in quic, ignoring." << std::endl;
} else {
config.qlog_file_base = qlog_base;
}
}
struct sigaction act {};
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, nullptr);

View File

@ -109,6 +109,8 @@ struct Config {
int data_fd;
// file descriptor to write per-request stats to.
int log_fd;
// base file name of qlog output files
std::string qlog_file_base;
uint16_t port;
uint16_t default_port;
uint16_t connect_to_port;
@ -340,6 +342,7 @@ struct Client {
std::array<Crypto, 2> crypto;
size_t max_pktlen;
bool close_requested;
FILE *qlog_file;
} quic;
ev_timer request_timeout_watcher;
addrinfo *next_addr;
@ -481,6 +484,7 @@ struct Client {
const uint8_t *data, size_t datalen);
int quic_pkt_timeout();
void quic_restart_pkt_timer();
void quic_write_qlog(const void *data, size_t datalen);
};
} // namespace h2load

View File

@ -34,6 +34,8 @@
#include "h2load_http3_session.h"
#include <sstream>
namespace h2load {
namespace {
@ -284,6 +286,20 @@ auto quic_method = SSL_QUIC_METHOD{
};
} // namespace
// qlog write callback -- excerpted from ngtcp2/examples/client_base.cc
namespace {
void qlog_write_cb(void *user_data, uint32_t flags, const void *data,
size_t datalen) {
auto c = static_cast<Client *>(user_data);
c->quic_write_qlog(data, datalen);
}
} // namespace
void Client::quic_write_qlog(const void *data, size_t datalen) {
assert(quic.qlog_file != nullptr);
fwrite(data, 1, datalen, quic.qlog_file);
}
int Client::quic_init(const sockaddr *local_addr, socklen_t local_addrlen,
const sockaddr *remote_addr, socklen_t remote_addrlen) {
int rv;
@ -354,6 +370,17 @@ int Client::quic_init(const sockaddr *local_addr, socklen_t local_addrlen,
settings.log_printf = debug_log_printf;
}
settings.initial_ts = timestamp(worker->loop);
if (!config->qlog_file_base.empty()) {
assert(quic.qlog_file == nullptr);
std::ostringstream oss(config->qlog_file_base, std::ios::app);
oss << '.' << worker->id << '.' << id << ".qlog";
quic.qlog_file = fopen(oss.str().c_str(), "w");
if (quic.qlog_file == nullptr) {
std::cerr << "Failed to open a qlog file: " << oss.str() << std::endl;
return -1;
}
settings.qlog.write = qlog_write_cb;
}
ngtcp2_transport_params params;
ngtcp2_transport_params_default(&params);
@ -393,7 +420,13 @@ int Client::quic_init(const sockaddr *local_addr, socklen_t local_addrlen,
return 0;
}
void Client::quic_free() { ngtcp2_conn_del(quic.conn); }
void Client::quic_free() {
ngtcp2_conn_del(quic.conn);
if (quic.qlog_file != nullptr) {
fclose(quic.qlog_file);
quic.qlog_file = nullptr;
}
}
void Client::quic_close_connection() {
if (!quic.conn) {