first try for a top like view

pull/291/head
lordrasmus 2 years ago
parent 8dc0b7f39a
commit f5a6f75168

@ -2,7 +2,7 @@ AM_CFLAGS = -Wall -Wextra -Wno-sign-compare
sbin_PROGRAMS = fping
fping_SOURCES = fping.c seqmap.c socket4.c fping.h options.h seqmap.h optparse.c optparse.h
fping_SOURCES = fping.c seqmap.c socket4.c fping.h options.h seqmap.h optparse.c optparse.h top_view.c
fping_DEPENDENCIES = ../config.h
if IPV6

@ -0,0 +1,45 @@
#ifndef FPING_DATA_TYPES_H
#define FPING_DATA_TYPES_H
#include <inttypes.h>
#include <sys/socket.h>
struct event;
typedef struct host_entry {
int i; /* index into array */
char *name; /* name as given by user */
char *host; /* text description of host */
struct sockaddr_storage saddr; /* internet address */
socklen_t saddr_len;
int64_t timeout; /* time to wait for response */
int64_t last_send_time; /* time of last packet sent */
int num_sent; /* number of ping packets sent (for statistics) */
int num_recv; /* number of pings received (duplicates ignored) */
int num_recv_total; /* number of pings received, including duplicates */
int64_t max_reply; /* longest response time */
int64_t min_reply; /* shortest response time */
int64_t total_time; /* sum of response times */
/* _i -> splits (reset on every report interval) */
int num_sent_i; /* number of ping packets sent */
int num_recv_i; /* number of pings received */
int64_t max_reply_i; /* longest response time */
int64_t min_reply_i; /* shortest response time */
int64_t total_time_i; /* sum of response times */
int64_t *resp_times; /* individual response times */
int top_view_print_pos;
int top_view_last_timeouts;
int top_view_last_timeouts_count;
int top_view_last_timeouts_seq;
char last_timeout_time[100];
/* to avoid allocating two struct events each time that we send a ping, we
* preallocate here two struct events for each ping that we might send for
* this host. */
struct event *event_storage_ping;
struct event *event_storage_timeout;
} HOST_ENTRY;
#endif

@ -38,6 +38,8 @@ extern "C" {
#include "config.h"
#include "options.h"
#include "optparse.h"
#include "top_view.h"
#include "data_types.h"
#include <errno.h>
#include <inttypes.h>
@ -213,35 +215,7 @@ char *icmp_unreach_str[16] = {
#define ICMP_UNREACH_MAXTYPE 15
struct event;
typedef struct host_entry {
int i; /* index into array */
char *name; /* name as given by user */
char *host; /* text description of host */
struct sockaddr_storage saddr; /* internet address */
socklen_t saddr_len;
int64_t timeout; /* time to wait for response */
int64_t last_send_time; /* time of last packet sent */
int num_sent; /* number of ping packets sent (for statistics) */
int num_recv; /* number of pings received (duplicates ignored) */
int num_recv_total; /* number of pings received, including duplicates */
int64_t max_reply; /* longest response time */
int64_t min_reply; /* shortest response time */
int64_t total_time; /* sum of response times */
/* _i -> splits (reset on every report interval) */
int num_sent_i; /* number of ping packets sent */
int num_recv_i; /* number of pings received */
int64_t max_reply_i; /* longest response time */
int64_t min_reply_i; /* shortest response time */
int64_t total_time_i; /* sum of response times */
int64_t *resp_times; /* individual response times */
/* to avoid allocating two struct events each time that we send a ping, we
* preallocate here two struct events for each ping that we might send for
* this host. */
struct event *event_storage_ping;
struct event *event_storage_timeout;
} HOST_ENTRY;
int event_storage_count; /* how many events can be stored in host_entry->event_storage_xxx */
@ -357,6 +331,7 @@ int multif_flag, timeout_flag;
int outage_flag = 0;
int timestamp_flag = 0;
int random_data_flag = 0;
int top_view = 0;
#if defined(DEBUG) || defined(_DEBUG)
int randomly_lose_flag, trace_flag, print_per_system_flag;
int lose_factor;
@ -535,6 +510,7 @@ int main(int argc, char **argv)
{ NULL, 'T', OPTPARSE_REQUIRED },
{ "unreach", 'u', OPTPARSE_NONE },
{ "version", 'v', OPTPARSE_NONE },
{ "top", 'k', OPTPARSE_NONE },
{ "reachable", 'x', OPTPARSE_REQUIRED },
#if defined(DEBUG) || defined(_DEBUG)
{ NULL, 'z', OPTPARSE_REQUIRED },
@ -825,6 +801,9 @@ int main(int argc, char **argv)
outage_flag = 1;
break;
case 'k':
top_view = 1;
break;
case '?':
fprintf(stderr, "%s: %s\n", argv[0], optparse_state.errmsg);
fprintf(stderr, "see 'fping -h' for usage information\n");
@ -833,6 +812,7 @@ int main(int argc, char **argv)
}
}
/* permanently drop privileges */
if (suid != getuid() && setuid(getuid())) {
perror("fatal: failed to permanently drop privileges");
@ -1303,8 +1283,11 @@ void main_loop()
struct event *event;
struct host_entry *h;
while (event_queue_ping.first || event_queue_timeout.first) {
dbg_printf("%s", "# main_loop\n");
/* timeout event ? */
if (event_queue_timeout.first && event_queue_timeout.first->ev_time - current_time_ns <= 0) {
@ -1319,23 +1302,28 @@ void main_loop()
if (timestamp_flag) {
printf("[%.5f] ", (double)current_time_ns / 1e9);
}
printf("%-*s : [%d], timed out",
max_hostname_len, h->host, event->ping_index);
if (h->num_recv > 0) {
printf(" (%s avg, ", sprint_tm(h->total_time / h->num_recv));
}
else {
printf(" (NaN avg, ");
}
if (h->num_recv <= h->num_sent) {
printf("%d%% loss)",
((h->num_sent - h->num_recv) * 100) / h->num_sent);
}
else {
printf("%d%% return)",
(h->num_recv_total * 100) / h->num_sent);
if( top_view == 0 ){
printf("%-*s : [%d], timed out",
max_hostname_len, h->host, event->ping_index);
if (h->num_recv > 0) {
printf(" (%s avg, ", sprint_tm(h->total_time / h->num_recv));
}
else {
printf(" (NaN avg, ");
}
if (h->num_recv <= h->num_sent) {
printf("%d%% loss)",
((h->num_sent - h->num_recv) * 100) / h->num_sent);
}
else {
printf("%d%% return)",
(h->num_recv_total * 100) / h->num_sent);
}
printf("\n");
}else{
print_top_view( h, 1 );
}
printf("\n");
}
/* do we need to send a retry? */
@ -1355,6 +1343,7 @@ void main_loop()
continue;
}
/* ping event ? */
if (event_queue_ping.first && event_queue_ping.first->ev_time - current_time_ns <= 0) {
/* Make sure that we don't ping more than once every "interval" */
@ -1410,6 +1399,7 @@ void main_loop()
dbg_printf("next timeout event in %.0f ms (%s)\n", wait_time_timeout / 1e6, event_queue_timeout.first->host->host);
}
/* When is the next report due? */
if (report_interval && (loop_flag || count_flag)) {
int64_t wait_time_next_report = next_report_time - current_time_ns;
@ -1441,8 +1431,10 @@ void main_loop()
; /* process other replies in the queue */
}
update_current_time();
if (status_snapshot) {
status_snapshot = 0;
print_per_system_splits();
@ -1450,6 +1442,7 @@ void main_loop()
/* Print report */
if (report_interval && (loop_flag || count_flag) && (current_time_ns >= next_report_time)) {
if (netdata_flag)
print_netdata();
else
@ -1460,6 +1453,10 @@ void main_loop()
}
}
}
if ( top_view == 1 ){
top_view_end();
}
}
/************************************************************
@ -2272,6 +2269,8 @@ int decode_icmp_ipv6(
}
#endif
int wait_for_reply(int64_t wait_time)
{
int result;
@ -2430,26 +2429,34 @@ int wait_for_reply(int64_t wait_time)
printf("[%.5f] ", (double)recv_time / 1e9);
}
avg = h->total_time / h->num_recv;
printf("%-*s : [%d], %d bytes, %s ms",
max_hostname_len, h->host, this_count, result, sprint_tm(this_reply));
printf(" (%s avg, ", sprint_tm(avg));
if (h->num_recv <= h->num_sent) {
printf("%d%% loss)",
((h->num_sent - h->num_recv) * 100) / h->num_sent);
}
else {
printf("%d%% return)",
(h->num_recv_total * 100) / h->num_sent);
}
if (addr_cmp((struct sockaddr *)&response_addr, (struct sockaddr *)&h->saddr)) {
char buf[INET6_ADDRSTRLEN];
getnameinfo((struct sockaddr *)&response_addr, sizeof(response_addr), buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
fprintf(stderr, " [<- %s]", buf);
}
if ( top_view == 0 ){
printf("%-*s : [%d], %d bytes, %s ms",
max_hostname_len, h->host, this_count, result, sprint_tm(this_reply));
printf(" (%s avg, ", sprint_tm(avg));
if (h->num_recv <= h->num_sent) {
printf("%d%% loss)",
((h->num_sent - h->num_recv) * 100) / h->num_sent);
}
else {
printf("%d%% return)",
(h->num_recv_total * 100) / h->num_sent);
}
printf("\n");
if (addr_cmp((struct sockaddr *)&response_addr, (struct sockaddr *)&h->saddr)) {
char buf[INET6_ADDRSTRLEN];
getnameinfo((struct sockaddr *)&response_addr, sizeof(response_addr), buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
fprintf(stderr, " [<- %s]", buf);
}
printf("\n");
}else{
print_top_view( h, 0 );
}
}
return 1;

@ -0,0 +1,139 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "top_view.h"
static char out_buffer[1000];
static int print_top_view_init_printed = 0;
static int next_view_pos = 1;
extern int64_t perhost_interval;
static void pos_printf(uint8_t col, uint8_t row, char* format, ...)
{
int pos = 0;
va_list argp;
va_start(argp, format);
memset(out_buffer, 0, sizeof(out_buffer));
pos += sprintf(&out_buffer[pos], "\033[%d;%df", col, row);
pos += vsnprintf(&out_buffer[pos], sizeof(out_buffer) - pos, format, argp);
puts( out_buffer );
}
static void line_clear(uint8_t col)
{
int pos = 0;
memset(out_buffer, 0, sizeof(out_buffer));
pos += sprintf(&out_buffer[pos], "\033[%d;%df\033[2K", col, 1);
//pos += vsnprintf(&out_buffer[pos], sizeof(out_buffer) - pos, format, argp);
puts( out_buffer );
}
#define HOST_POS 2
#define SEND_POS 20
#define RECV_POS 30
#define LOST_POS 40
#define TIMEOUT_POS 50
#define TIMEOUT_TOTAL_POS 60
#define TIMEOUT_SEQ_POS 70
#define TIMEOUT_TIME_POS 80
void top_view_end( void ){
// Cursor deaktivieren
puts( "\033[?25h");
}
static void print_top_view_init( void ){
if ( print_top_view_init_printed == 1 ) return;
print_top_view_init_printed = 1;
int pos = 0;
// Screen löschen und Farbe deaktivieren
pos += sprintf(&out_buffer[pos], "\033[00m\033[2J");
// Cursor deaktivieren
pos += sprintf(&out_buffer[pos], "\033[?25l");
puts( out_buffer );
pos_printf( 2 , 10 , "fping top view ( period : %d ms )", ( perhost_interval / 1000 / 1000 ));
pos_printf( 4 , HOST_POS , "host");
pos_printf( 4 , SEND_POS , "send");
pos_printf( 4 , RECV_POS , "recv");
pos_printf( 4 , LOST_POS , "lost");
pos_printf( 4 , TIMEOUT_POS , "timeouts: ");
pos_printf( 4 , TIMEOUT_TOTAL_POS , "total");
pos_printf( 4 , TIMEOUT_SEQ_POS , "seq");
pos_printf( 4 , TIMEOUT_TIME_POS , "time");
}
void print_top_view( HOST_ENTRY *h, int timeout ){
print_top_view_init();
if ( h->top_view_print_pos == 0 ){
h->top_view_print_pos = next_view_pos++;
sprintf(h->last_timeout_time, "0 ms" );
}
if ( timeout == 1 ){
h->top_view_last_timeouts++;
h->top_view_last_timeouts_seq = h->top_view_last_timeouts;
sprintf(h->last_timeout_time, "%d ms ", h->top_view_last_timeouts * ( perhost_interval / 1000 / 1000 ) );
}else{
if ( h->top_view_last_timeouts > 0 ){
h->top_view_last_timeouts_count++;
}
h->top_view_last_timeouts = 0;
}
line_clear( 5 + h->top_view_print_pos );
pos_printf( 5 + h->top_view_print_pos, HOST_POS , "%s", h->host);
pos_printf( 5 + h->top_view_print_pos, SEND_POS , "%d", h->num_sent);
pos_printf( 5 + h->top_view_print_pos, RECV_POS , "%d", h->num_recv);
pos_printf( 5 + h->top_view_print_pos, LOST_POS , "%d", ( h->num_sent - h->num_recv ));
pos_printf( 5 + h->top_view_print_pos, TIMEOUT_TOTAL_POS , "%d", h->top_view_last_timeouts_count);
pos_printf( 5 + h->top_view_print_pos, TIMEOUT_SEQ_POS , "%d", h->top_view_last_timeouts_seq);
pos_printf( 5 + h->top_view_print_pos, TIMEOUT_TIME_POS , "%s", h->last_timeout_time);
//pos_printf( 5 + h->top_view_print_pos, 2 , "%*d %*d lost: %*d %s ", , h->last_timeout_time );
}

@ -0,0 +1,8 @@
#include "data_types.h"
void print_top_view( HOST_ENTRY *h, int timeout );
void top_view_end( void );
Loading…
Cancel
Save