Browse Source

etcpmon: add tooltips for all metrics fields with variable names and descriptions

congestion
Evgeny 5 months ago
parent
commit
6127409c04
  1. 213
      tools/etcpmon/etcpmon_gui.c
  2. 1
      tools/etcpmon/etcpmon_gui.h

213
tools/etcpmon/etcpmon_gui.c

@ -32,6 +32,8 @@ static void OnDisconnect(struct etcpmon_app* app);
static void OnConnectionSelect(struct etcpmon_app* app); static void OnConnectionSelect(struct etcpmon_app* app);
static void OnTimer(struct etcpmon_app* app); static void OnTimer(struct etcpmon_app* app);
static void UpdateUIState(struct etcpmon_app* app); static void UpdateUIState(struct etcpmon_app* app);
static void AddTooltip(HWND hTip, HWND hCtrl, const char* text);
static void CreateTooltips(struct etcpmon_app* app);
/* Callback functions for client events */ /* Callback functions for client events */
static void on_connected(void* user_data); static void on_connected(void* user_data);
static void on_disconnected(void* user_data); static void on_disconnected(void* user_data);
@ -139,7 +141,8 @@ HWND etcpmon_gui_create_window(struct etcpmon_app* app) {
} }
CreateControls(app); CreateControls(app);
CreateTooltips(app);
for (int i = 0; i < GRAPH_METRICS_COUNT; i++) { for (int i = 0; i < GRAPH_METRICS_COUNT; i++) {
app->hGraphPens[i] = CreatePen(PS_SOLID, 2, graph_colors[i]); app->hGraphPens[i] = CreatePen(PS_SOLID, 2, graph_colors[i]);
} }
@ -695,6 +698,205 @@ static void CreateControls(struct etcpmon_app* app) {
} }
} }
static void AddTooltip(HWND hTip, HWND hCtrl, const char* text)
{
if (!hTip || !hCtrl || !text) return;
TOOLINFOA ti;
memset(&ti, 0, sizeof(ti));
ti.cbSize = sizeof(ti);
ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
ti.hwnd = GetParent(hCtrl);
ti.uId = (UINT_PTR)hCtrl;
ti.lpszText = (LPSTR)text;
SendMessageA(hTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
}
static void CreateTooltips(struct etcpmon_app* app)
{
if (!app || !app->hWndMain) return;
app->hToolTip = CreateWindowExA(
WS_EX_TOPMOST, TOOLTIPS_CLASSA, NULL,
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
app->hWndMain, NULL, app->hInstance, NULL
);
if (!app->hToolTip) return;
SendMessageA(app->hToolTip, TTM_SETMAXTIPWIDTH, 0, 400);
/* ETCP Metrics */
AddTooltip(app->hToolTip, app->hEditEtcpRttLast,
"etcp.rtt_last / ETCP Connection\r\nВремя приема-передачи последнего пакета (RTT), единицы 0.1 мс");
AddTooltip(app->hToolTip, app->hEditEtcpRttAvg10,
"etcp.rtt_avg_10 / ETCP Connection\r\nСредний RTT за последние 10 пакетов, единицы 0.1 мс");
AddTooltip(app->hToolTip, app->hEditEtcpRttAvg100,
"etcp.rtt_avg_100 / ETCP Connection\r\nСредний RTT за последние 100 пакетов, единицы 0.1 мс");
AddTooltip(app->hToolTip, app->hEditEtcpJitter,
"etcp.jitter / ETCP Connection\r\nРазброс RTT (макс - мин), единицы 0.1 мс");
AddTooltip(app->hToolTip, app->hEditEtcpBytesSent,
"etcp.bytes_sent_total / ETCP Connection\r\nОбщий объем отправленных байт за все время");
AddTooltip(app->hToolTip, app->hEditEtcpRetrans,
"etcp.retrans_count / ETCP Connection\r\nКоличество ретрансляций (повторных отправок пакетов)");
AddTooltip(app->hToolTip, app->hEditEtcpAcks,
"etcp.ack_count / ETCP Connection\r\nКоличество полученных ACK-пакетов (подтверждений)");
AddTooltip(app->hToolTip, app->hEditEtcpInflight,
"etcp.unacked_bytes / ETCP Connection\r\nБайт в полете: отправлено, но еще не подтверждено");
AddTooltip(app->hToolTip, app->hEditEtcpLinks,
"etcp.links_count / ETCP Connection\r\nКоличество активных линков (физических соединений)");
/* TUN Metrics */
AddTooltip(app->hToolTip, app->hEditTunReadBytes,
"tun.bytes_read / TUN Interface\r\nВсего байт прочитано из TUN-интерфейса");
AddTooltip(app->hToolTip, app->hEditTunWriteBytes,
"tun.bytes_written / TUN Interface\r\nВсего байт записано в TUN-интерфейс");
AddTooltip(app->hToolTip, app->hEditTunReadPkts,
"tun.packets_read / TUN Interface\r\nВсего пакетов прочитано из TUN-интерфейса");
AddTooltip(app->hToolTip, app->hEditTunWritePkts,
"tun.packets_written / TUN Interface\r\nВсего пакетов записано в TUN-интерфейс");
AddTooltip(app->hToolTip, app->hEditTunReadErrs,
"tun.read_errors / TUN Interface\r\nОшибок чтения из TUN-интерфейса");
AddTooltip(app->hToolTip, app->hEditTunWriteErrs,
"tun.write_errors / TUN Interface\r\nОшибок записи в TUN-интерфейс");
/* Routing Metrics */
AddTooltip(app->hToolTip, app->hEditRtRouted,
"tun.routed_packets / Routing\r\nКоличество успешно маршрутизированных пакетов");
AddTooltip(app->hToolTip, app->hEditRtDropped,
"tun.dropped_packets / Routing\r\nКоличество отброшенных (не маршрутизированных) пакетов");
AddTooltip(app->hToolTip, app->hEditRtTunInQPkts,
"tun.tun_in_q_packets / Routing\r\nПакетов во входной очереди TUN");
AddTooltip(app->hToolTip, app->hEditRtTunInQBytes,
"tun.tun_in_q_bytes / Routing\r\nБайт во входной очереди TUN");
AddTooltip(app->hToolTip, app->hEditRtTunOutQPkts,
"tun.tun_out_q_packets / Routing\r\nПакетов в выходной очереди TUN");
AddTooltip(app->hToolTip, app->hEditRtTunOutQBytes,
"tun.tun_out_q_bytes / Routing\r\nБайт в выходной очереди TUN");
AddTooltip(app->hToolTip, app->hEditRtCount,
"tun.rt_count / Routing\r\nОбщее количество записей в таблице маршрутизации");
AddTooltip(app->hToolTip, app->hEditRtLocal,
"tun.rt_local / Routing\r\nЛокальных (статических) маршрутов");
AddTooltip(app->hToolTip, app->hEditRtLearned,
"tun.rt_learned / Routing\r\nИзученных (динамических/BGP) маршрутов");
AddTooltip(app->hToolTip, app->hEditRtBgpSenders,
"tun.rt_bgp_senders / Routing BGP\r\nКоличество BGP-отправителей в списке");
AddTooltip(app->hToolTip, app->hEditRtBgpNodes,
"tun.rt_bgp_nodes / Routing BGP\r\nКоличество BGP-узлов");
/* Queue Metrics */
AddTooltip(app->hToolTip, app->hEditQInQBytes,
"etcp.input_queue_bytes / ETCP Queue\r\nБайт во входной очереди (принято от TUN, ожидает отправки)");
AddTooltip(app->hToolTip, app->hEditQInQPkts,
"etcp.input_queue_packets / ETCP Queue\r\nПакетов во входной очереди");
AddTooltip(app->hToolTip, app->hEditQInSendBytes,
"etcp.input_send_q_bytes / ETCP Queue\r\nБайт в очереди отправки (готовы к отправке по линкам)");
AddTooltip(app->hToolTip, app->hEditQInSendPkts,
"etcp.input_send_q_packets / ETCP Queue\r\nПакетов в очереди отправки");
AddTooltip(app->hToolTip, app->hEditQWaitAckBytes,
"etcp.input_wait_ack_bytes / ETCP Queue\r\nБайт в очереди ожидания ACK (отправлено, ждем подтверждения)");
AddTooltip(app->hToolTip, app->hEditQWaitAckPkts,
"etcp.input_wait_ack_packets / ETCP Queue\r\nПакетов в очереди ожидания ACK");
AddTooltip(app->hToolTip, app->hEditQWaitAckOptInfl,
"etcp.optimal_inflight / ETCP Congestion Control\r\nЦелевое (оптимальное) окно перегрузки в байтах");
AddTooltip(app->hToolTip, app->hEditQAckBytes,
"etcp.ack_q_bytes / ETCP Queue\r\nБайт в очереди ACK (подтверждения, готовы к отправке)");
AddTooltip(app->hToolTip, app->hEditQAckPkts,
"etcp.ack_q_packets / ETCP Queue\r\nПакетов в очереди ACK");
AddTooltip(app->hToolTip, app->hEditQRecvBytes,
"etcp.recv_q_bytes / ETCP Queue\r\nБайт в очереди приема (принято, ожидает доставки в TUN)");
AddTooltip(app->hToolTip, app->hEditQRecvPkts,
"etcp.recv_q_packets / ETCP Queue\r\nПакетов в очереди приема");
AddTooltip(app->hToolTip, app->hEditQOutBytes,
"etcp.output_queue_bytes / ETCP Queue\r\nБайт в выходной очереди (готовы к записи в TUN)");
AddTooltip(app->hToolTip, app->hEditQOutPkts,
"etcp.output_queue_packets / ETCP Queue\r\nПакетов в выходной очереди");
/* Error Counters */
AddTooltip(app->hToolTip, app->hEditErrReinit,
"etcp.reinit_count / ETCP Errors\r\nСчетчик реинициализаций соединения");
AddTooltip(app->hToolTip, app->hEditErrReset,
"etcp.reset_count / ETCP Errors\r\nСчетчик сбросов (reset) соединения");
AddTooltip(app->hToolTip, app->hEditErrPktFmt,
"etcp.pkt_format_errors / ETCP Errors\r\nОшибок формата пакета (невалидные заголовки)");
/* Timer Flags */
AddTooltip(app->hToolTip, app->hEditTimerRetrans,
"etcp.retrans_timer_active / ETCP Timers\r\nАктивен ли таймер ретрансляции (ON/OFF)");
AddTooltip(app->hToolTip, app->hEditTimerAckResp,
"etcp.ack_resp_timer_active / ETCP Timers\r\nАктивен ли таймер отложенных ACK");
/* WaitAck queue state */
AddTooltip(app->hToolTip, app->hEditWaitAckSuspend,
"etcp.wait_ack_cb_suspended / ETCP WaitAck\r\nCallback приостановлен (ожидание ACK блокирует передачу)");
AddTooltip(app->hToolTip, app->hEditWaitAckCb,
"etcp.wait_ack_cb_set / ETCP WaitAck\r\nCallback установлен (есть обработчик ожидания ACK)");
AddTooltip(app->hToolTip, app->hEditWaitAckTimer,
"etcp.wait_ack_resume_timeout / ETCP WaitAck\r\nТаймер возобновления передачи активен");
/* ID Metrics */
AddTooltip(app->hToolTip, app->hEditIdNextTx,
"etcp.next_tx_id / ETCP Sequence\r\nСледующий ID для передачи (Sequence Number TX)");
AddTooltip(app->hToolTip, app->hEditIdLastRx,
"etcp.last_rx_id / ETCP Sequence\r\nПоследний принятый ID (Sequence Number RX)");
AddTooltip(app->hToolTip, app->hEditIdLastDel,
"etcp.last_delivered_id / ETCP Sequence\r\nПоследний доставленный ID (в TUN)");
AddTooltip(app->hToolTip, app->hEditIdRxAckTill,
"etcp.rx_ack_till / ETCP Sequence\r\nДо какого ID подтвержден прием (ACK от получателя)");
/* Normalizer */
AddTooltip(app->hToolTip, app->hEditNormInPkts,
"etcp.norm_input_pkts / Packet Normalizer\r\nПакетов на входе нормализатора (текущие)");
AddTooltip(app->hToolTip, app->hEditNormInBytes,
"etcp.norm_input_bytes / Packet Normalizer\r\nБайт на входе нормализатора (текущие)");
AddTooltip(app->hToolTip, app->hEditNormOutPkts,
"etcp.norm_output_pkts / Packet Normalizer\r\nПакетов на выходе нормализатора (текущие)");
AddTooltip(app->hToolTip, app->hEditNormOutBytes,
"etcp.norm_output_bytes / Packet Normalizer\r\nБайт на выходе нормализатора (текущие)");
AddTooltip(app->hToolTip, app->hEditNormAllocErr,
"etcp.norm_alloc_errors / Packet Normalizer\r\nОшибок выделения памяти в нормализаторе");
AddTooltip(app->hToolTip, app->hEditNormLogicErr,
"etcp.norm_logic_errors / Packet Normalizer\r\nЛогических ошибок в нормализаторе");
AddTooltip(app->hToolTip, app->hEditNormFragSize,
"etcp.norm_frag_size / Packet Normalizer\r\nРазмер текущего фрагмента");
AddTooltip(app->hToolTip, app->hEditNormDataPtr,
"etcp.norm_data_ptr / Packet Normalizer\r\nУказатель на данные в буфере");
AddTooltip(app->hToolTip, app->hEditNormDataSize,
"etcp.norm_data_size / Packet Normalizer\r\nРазмер данных в буфере");
AddTooltip(app->hToolTip, app->hEditNormInTotPkts,
"etcp.norm_in_total_pkts / Packet Normalizer\r\nВсего пакетов обработано на входе (накопительно)");
AddTooltip(app->hToolTip, app->hEditNormInTotBytes,
"etcp.norm_in_total_bytes / Packet Normalizer\r\nВсего байт обработано на входе (накопительно)");
AddTooltip(app->hToolTip, app->hEditNormOutTotPkts,
"etcp.norm_out_total_pkts / Packet Normalizer\r\nВсего пакетов обработано на выходе (накопительно)");
AddTooltip(app->hToolTip, app->hEditNormOutTotBytes,
"etcp.norm_out_total_bytes / Packet Normalizer\r\nВсего байт обработано на выходе (накопительно)");
/* ACK Debug counters */
AddTooltip(app->hToolTip, app->hEditAckHitInf,
"etcp.cnt_ack_hit_inf / ETCP ACK Debug\r\nACK попал в inflight-окно (ожидаемый ACK)");
AddTooltip(app->hToolTip, app->hEditAckHitSndq,
"etcp.cnt_ack_hit_sndq / ETCP ACK Debug\r\nACK попал в send-очередь");
AddTooltip(app->hToolTip, app->hEditAckMiss,
"etcp.cnt_ack_miss / ETCP ACK Debug\r\nACK не найден (неожиданный ACK)");
AddTooltip(app->hToolTip, app->hEditCntLinkWait,
"etcp.cnt_link_wait / ETCP ACK Debug\r\nСчетчик ожидания линка");
AddTooltip(app->hToolTip, app->hEditTxState,
"etcp.tx_state / ETCP ACK Debug\r\nСостояние передачи (битовая маска)");
/* Debug counters */
for (int i = 0; i < 8; i++) {
char buf[256];
snprintf(buf, sizeof(buf),
"etcp.debug[%d] / ETCP Debug\r\nОтладочное поле (зависит от версии)", i);
AddTooltip(app->hToolTip, app->hEditDebug[i], buf);
}
/* System resources */
AddTooltip(app->hToolTip, app->hEditActiveTimeouts,
"etcp.active_timeouts / System Resources\r\nАктивных таймаутов в системе (async)");
AddTooltip(app->hToolTip, app->hEditBusyMemory,
"etcp.busy_memory_blocks / System Resources\r\nЗанятых блоков памяти (memory pool)");
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
struct etcpmon_app* app = NULL; struct etcpmon_app* app = NULL;
@ -918,10 +1120,15 @@ int etcpmon_gui_run(struct etcpmon_app* app) {
} }
void etcpmon_gui_cleanup(struct etcpmon_app* app) { void etcpmon_gui_cleanup(struct etcpmon_app* app) {
if (!app) return; if (!app) return;
if (app->hToolTip) {
DestroyWindow(app->hToolTip);
app->hToolTip = NULL;
}
for (int i = 0; i < GRAPH_METRICS_COUNT; i++) { for (int i = 0; i < GRAPH_METRICS_COUNT; i++) {
if (app->hGraphPens[i]) DeleteObject(app->hGraphPens[i]); if (app->hGraphPens[i]) DeleteObject(app->hGraphPens[i]);
} }
if (app->client) { if (app->client) {
etcpmon_client_cleanup(app->client); etcpmon_client_cleanup(app->client);
free(app->client); free(app->client);

1
tools/etcpmon/etcpmon_gui.h

@ -184,6 +184,7 @@ struct etcpmon_app {
HINSTANCE hInstance; HINSTANCE hInstance;
HWND hWndMain; HWND hWndMain;
HWND hWndStatus; HWND hWndStatus;
HWND hToolTip;
HPEN hGraphPens[GRAPH_METRICS_COUNT]; HPEN hGraphPens[GRAPH_METRICS_COUNT];

Loading…
Cancel
Save