h2load: Add qlog output support
This commit is contained in:
parent
1eb818b64c
commit
48e10c57da
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(¶ms);
|
||||
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue