diff mbox series

[iproute2-next] ss: add option to print socket information on one line

Message ID 1556227308-16057-1-git-send-email-johunt@akamai.com
State Changes Requested
Delegated to: David Ahern
Headers show
Series [iproute2-next] ss: add option to print socket information on one line | expand

Commit Message

Josh Hunt April 25, 2019, 9:21 p.m. UTC
Multi-line output in ss makes it difficult to search for things with
grep. This new option will make it easier to find sockets matching
certain criteria with simple grep commands.

Example without option:
$ ss -emoitn
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
ESTAB      0      0      127.0.0.1:13265              127.0.0.1:36743               uid:1974 ino:48271 sk:1 <->
	 skmem:(r0,rb2227595,t0,tb2626560,f0,w0,o0,bl0,d0) ts sack reno wscale:7,7 rto:211 rtt:10.245/16.616 ato:40 mss:65483 cwnd:10 bytes_acked:41865496 bytes_received:21580440 segs_out:242496 segs_in:351446 data_segs_out:242495 data_segs_in:242495 send 511.3Mbps lastsnd:2383 lastrcv:2383 lastack:2342 pacing_rate 1022.6Mbps rcv_rtt:92427.6 rcv_space:43725 minrtt:0.007

Example with new option:
$ ss -emoitnO
State    Recv-Q Send-Q          Local Address:Port            Peer Address:Port
ESTAB    0      0                   127.0.0.1:13265              127.0.0.1:36743 uid:1974 ino:48271 sk:1 <-> skmem:(r0,rb2227595,t0,tb2626560,f0,w0,o0,bl0,d0) ts sack reno wscale:7,7 rto:211 rtt:10.067/16.429 ato:40 mss:65483 pmtu:65535 rcvmss:536 advmss:65483 cwnd:10 bytes_sent:41868244 bytes_acked:41868244 bytes_received:21581866 segs_out:242512 segs_in:351469 data_segs_out:242511 data_segs_in:242511 send 520.4Mbps lastsnd:14355 lastrcv:14355 lastack:14314 pacing_rate 1040.7Mbps delivery_rate 74837.7Mbps delivered:242512 app_limited busy:1861946ms rcv_rtt:92427.6 rcv_space:43725 rcv_ssthresh:43690 minrtt:0.007

Signed-off-by: Josh Hunt <johunt@akamai.com>
---
 man/man8/ss.8 |  3 +++
 misc/ss.c     | 51 +++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 44 insertions(+), 10 deletions(-)

Comments

Stephen Hemminger April 25, 2019, 10:59 p.m. UTC | #1
On Thu, 25 Apr 2019 17:21:48 -0400
Josh Hunt <johunt@akamai.com> wrote:

> Multi-line output in ss makes it difficult to search for things with
> grep. This new option will make it easier to find sockets matching
> certain criteria with simple grep commands.
> 
> Example without option:
> $ ss -emoitn
> State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
> ESTAB      0      0      127.0.0.1:13265              127.0.0.1:36743               uid:1974 ino:48271 sk:1 <->
> 	 skmem:(r0,rb2227595,t0,tb2626560,f0,w0,o0,bl0,d0) ts sack reno wscale:7,7 rto:211 rtt:10.245/16.616 ato:40 mss:65483 cwnd:10 bytes_acked:41865496 bytes_received:21580440 segs_out:242496 segs_in:351446 data_segs_out:242495 data_segs_in:242495 send 511.3Mbps lastsnd:2383 lastrcv:2383 lastack:2342 pacing_rate 1022.6Mbps rcv_rtt:92427.6 rcv_space:43725 minrtt:0.007
> 
> Example with new option:
> $ ss -emoitnO
> State    Recv-Q Send-Q          Local Address:Port            Peer Address:Port
> ESTAB    0      0                   127.0.0.1:13265              127.0.0.1:36743 uid:1974 ino:48271 sk:1 <-> skmem:(r0,rb2227595,t0,tb2626560,f0,w0,o0,bl0,d0) ts sack reno wscale:7,7 rto:211 rtt:10.067/16.429 ato:40 mss:65483 pmtu:65535 rcvmss:536 advmss:65483 cwnd:10 bytes_sent:41868244 bytes_acked:41868244 bytes_received:21581866 segs_out:242512 segs_in:351469 data_segs_out:242511 data_segs_in:242511 send 520.4Mbps lastsnd:14355 lastrcv:14355 lastack:14314 pacing_rate 1040.7Mbps delivery_rate 74837.7Mbps delivered:242512 app_limited busy:1861946ms rcv_rtt:92427.6 rcv_space:43725 rcv_ssthresh:43690 minrtt:0.007
> 
> Signed-off-by: Josh Hunt <johunt@akamai.com>

I agree with this, but probably time to give ss a json output as well.
Josh Hunt April 25, 2019, 11:50 p.m. UTC | #2
On 4/25/19 3:59 PM, Stephen Hemminger wrote:
> On Thu, 25 Apr 2019 17:21:48 -0400
> Josh Hunt <johunt@akamai.com> wrote:
> 
>> Multi-line output in ss makes it difficult to search for things with
>> grep. This new option will make it easier to find sockets matching
>> certain criteria with simple grep commands.
>>
>> Example without option:
>> $ ss -emoitn
>> State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
>> ESTAB      0      0      127.0.0.1:13265              127.0.0.1:36743               uid:1974 ino:48271 sk:1 <->
>> 	 skmem:(r0,rb2227595,t0,tb2626560,f0,w0,o0,bl0,d0) ts sack reno wscale:7,7 rto:211 rtt:10.245/16.616 ato:40 mss:65483 cwnd:10 bytes_acked:41865496 bytes_received:21580440 segs_out:242496 segs_in:351446 data_segs_out:242495 data_segs_in:242495 send 511.3Mbps lastsnd:2383 lastrcv:2383 lastack:2342 pacing_rate 1022.6Mbps rcv_rtt:92427.6 rcv_space:43725 minrtt:0.007
>>
>> Example with new option:
>> $ ss -emoitnO
>> State    Recv-Q Send-Q          Local Address:Port            Peer Address:Port
>> ESTAB    0      0                   127.0.0.1:13265              127.0.0.1:36743 uid:1974 ino:48271 sk:1 <-> skmem:(r0,rb2227595,t0,tb2626560,f0,w0,o0,bl0,d0) ts sack reno wscale:7,7 rto:211 rtt:10.067/16.429 ato:40 mss:65483 pmtu:65535 rcvmss:536 advmss:65483 cwnd:10 bytes_sent:41868244 bytes_acked:41868244 bytes_received:21581866 segs_out:242512 segs_in:351469 data_segs_out:242511 data_segs_in:242511 send 520.4Mbps lastsnd:14355 lastrcv:14355 lastack:14314 pacing_rate 1040.7Mbps delivery_rate 74837.7Mbps delivered:242512 app_limited busy:1861946ms rcv_rtt:92427.6 rcv_space:43725 rcv_ssthresh:43690 minrtt:0.007
>>
>> Signed-off-by: Josh Hunt <johunt@akamai.com>
> 
> I agree with this, but probably time to give ss a json output as well.
> 

OK sure. Do you want to take both in a series or will you take this now 
with a separate json patch later?

Josh
Eric Dumazet April 25, 2019, 11:53 p.m. UTC | #3
On 4/25/19 3:59 PM, Stephen Hemminger wrote:

> I agree with this, but probably time to give ss a json output as well.

Yes, this might be quite nice.

(Although I am not sure of what extra cpu costs would be involved,
 when dealing with million of sockets per dump)
David Ahern April 30, 2019, 6:30 p.m. UTC | #4
On 4/25/19 3:21 PM, Josh Hunt wrote:
> @@ -4877,6 +4903,7 @@ static void _usage(FILE *dest)
>  "\n"
>  "   -K, --kill          forcibly close sockets, display what was closed\n"
>  "   -H, --no-header     Suppress header line\n"
> +"   -O, --one-line      socket's data printed on a single line\n"
>  "\n"
>  "   -A, --query=QUERY, --socket=QUERY\n"
>  "       QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n"
> @@ -5003,6 +5030,7 @@ static const struct option long_opts[] = {
>  	{ "kill", 0, 0, 'K' },
>  	{ "no-header", 0, 0, 'H' },
>  	{ "xdp", 0, 0, OPT_XDPSOCK},
> +	{ "one-line", 0, 0, 'O' },

shame 'o' can not be used for consistency with ip, but we can have both
use 'oneline' as the long option without the '-'.
Josh Hunt April 30, 2019, 6:31 p.m. UTC | #5
On 4/30/19 11:30 AM, David Ahern wrote:
> On 4/25/19 3:21 PM, Josh Hunt wrote:
>> @@ -4877,6 +4903,7 @@ static void _usage(FILE *dest)
>>   "\n"
>>   "   -K, --kill          forcibly close sockets, display what was closed\n"
>>   "   -H, --no-header     Suppress header line\n"
>> +"   -O, --one-line      socket's data printed on a single line\n"
>>   "\n"
>>   "   -A, --query=QUERY, --socket=QUERY\n"
>>   "       QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n"
>> @@ -5003,6 +5030,7 @@ static const struct option long_opts[] = {
>>   	{ "kill", 0, 0, 'K' },
>>   	{ "no-header", 0, 0, 'H' },
>>   	{ "xdp", 0, 0, OPT_XDPSOCK},
>> +	{ "one-line", 0, 0, 'O' },
> 
> shame 'o' can not be used for consistency with ip, but we can have both
> use 'oneline' as the long option without the '-'.
> 

Yeah, thanks David. I saw that the other tools use --oneline, so I'll 
send an update with that changed.

Josh
Josh Hunt April 30, 2019, 6:55 p.m. UTC | #6
On 4/30/19 11:31 AM, Josh Hunt wrote:
> On 4/30/19 11:30 AM, David Ahern wrote:
>> On 4/25/19 3:21 PM, Josh Hunt wrote:
>>> @@ -4877,6 +4903,7 @@ static void _usage(FILE *dest)
>>>   "\n"
>>>   "   -K, --kill          forcibly close sockets, display what was 
>>> closed\n"
>>>   "   -H, --no-header     Suppress header line\n"
>>> +"   -O, --one-line      socket's data printed on a single line\n"
>>>   "\n"
>>>   "   -A, --query=QUERY, --socket=QUERY\n"
>>>   "       QUERY := 
>>> {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n" 
>>>
>>> @@ -5003,6 +5030,7 @@ static const struct option long_opts[] = {
>>>       { "kill", 0, 0, 'K' },
>>>       { "no-header", 0, 0, 'H' },
>>>       { "xdp", 0, 0, OPT_XDPSOCK},
>>> +    { "one-line", 0, 0, 'O' },
>>
>> shame 'o' can not be used for consistency with ip, but we can have both
>> use 'oneline' as the long option without the '-'.
>>
> 
> Yeah, thanks David. I saw that the other tools use --oneline, so I'll 
> send an update with that changed.
> 

Actually, David can you clarify what you meant by "use 'oneline' as the 
long option without the '-'."?

Thanks
Josh
David Ahern April 30, 2019, 7:41 p.m. UTC | #7
On 4/30/19 12:55 PM, Josh Hunt wrote:
> Actually, David can you clarify what you meant by "use 'oneline' as the
> long option without the '-'."?

for your patch:
1,$s/one-line/oneline/

ip has -oneline which is most likely used as 'ip -o'. having ss with
--one-line vs --oneline is at least consistent to the level it can be.
Josh Hunt April 30, 2019, 7:42 p.m. UTC | #8
On 4/30/19 12:41 PM, David Ahern wrote:
> On 4/30/19 12:55 PM, Josh Hunt wrote:
>> Actually, David can you clarify what you meant by "use 'oneline' as the
>> long option without the '-'."?
> 
> for your patch:
> 1,$s/one-line/oneline/
> 
> ip has -oneline which is most likely used as 'ip -o'. having ss with
> --one-line vs --oneline is at least consistent to the level it can be.
> 

OK, that's what I thought you meant, but wanted to confirm.

Thanks!
Josh
diff mbox series

Patch

diff --git a/man/man8/ss.8 b/man/man8/ss.8
index 03a3dcc6c9c3..dd5ebc96ec03 100644
--- a/man/man8/ss.8
+++ b/man/man8/ss.8
@@ -24,6 +24,9 @@  Output version information.
 .B \-H, \-\-no-header
 Suppress header line.
 .TP
+.B \-O, \-\-one-line
+Print each socket's data on a single line.
+.TP
 .B \-n, \-\-numeric
 Do not try to resolve service names.
 .TP
diff --git a/misc/ss.c b/misc/ss.c
index 9cb3ee19e542..3a193db7d17f 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -121,6 +121,7 @@  static int follow_events;
 static int sctp_ino;
 static int show_tipcinfo;
 static int show_tos;
+int oneline = 0;
 
 enum col_id {
 	COL_NETID,
@@ -3053,7 +3054,8 @@  static int inet_show_sock(struct nlmsghdr *nlh,
 	}
 
 	if (show_mem || (show_tcpinfo && s->type != IPPROTO_UDP)) {
-		out("\n\t");
+		if (!oneline)
+			out("\n\t");
 		if (s->type == IPPROTO_SCTP)
 			sctp_show_info(nlh, r, tb);
 		else
@@ -3973,7 +3975,10 @@  static int packet_show_sock(struct nlmsghdr *nlh, void *arg)
 
 	if (show_details) {
 		if (pinfo) {
-			out("\n\tver:%d", pinfo->pdi_version);
+			if (oneline)
+				out(" ver:%d", pinfo->pdi_version);
+			else
+				out("\n\tver:%d", pinfo->pdi_version);
 			out(" cpy_thresh:%d", pinfo->pdi_copy_thresh);
 			out(" flags( ");
 			if (pinfo->pdi_flags & PDI_RUNNING)
@@ -3991,19 +3996,28 @@  static int packet_show_sock(struct nlmsghdr *nlh, void *arg)
 			out(" )");
 		}
 		if (ring_rx) {
-			out("\n\tring_rx(");
+			if (oneline)
+				out(" ring_rx(");
+			else
+				out("\n\tring_rx(");
 			packet_show_ring(ring_rx);
 			out(")");
 		}
 		if (ring_tx) {
-			out("\n\tring_tx(");
+			if (oneline)
+				out(" ring_tx(");
+			else
+				out("\n\tring_tx(");
 			packet_show_ring(ring_tx);
 			out(")");
 		}
 		if (has_fanout) {
 			uint16_t type = (fanout >> 16) & 0xffff;
 
-			out("\n\tfanout(");
+			if (oneline)
+				out(" fanout(");
+			else
+				out("\n\tfanout(");
 			out("id:%d,", fanout & 0xffff);
 			out("type:");
 
@@ -4032,7 +4046,10 @@  static int packet_show_sock(struct nlmsghdr *nlh, void *arg)
 		int num = RTA_PAYLOAD(tb[PACKET_DIAG_FILTER]) /
 			  sizeof(struct sock_filter);
 
-		out("\n\tbpf filter (%d): ", num);
+		if (oneline)
+			out(" bpf filter (%d): ", num);
+		else
+			out("\n\tbpf filter (%d): ", num);
 		while (num) {
 			out(" 0x%02x %u %u %u,",
 			    fil->code, fil->jt, fil->jf, fil->k);
@@ -4144,7 +4161,10 @@  static int xdp_stats_print(struct sockstat *s, const struct filter *f)
 
 static void xdp_show_ring(const char *name, struct xdp_diag_ring *ring)
 {
-	out("\n\t%s(", name);
+	if (oneline)
+		out(" %s(", name);
+	else
+		out("\n\t%s(", name);
 	out("entries:%u", ring->entries);
 	out(")");
 }
@@ -4152,7 +4172,10 @@  static void xdp_show_ring(const char *name, struct xdp_diag_ring *ring)
 static void xdp_show_umem(struct xdp_diag_umem *umem, struct xdp_diag_ring *fr,
 			  struct xdp_diag_ring *cr)
 {
-	out("\n\tumem(");
+	if (oneline)
+		out(" tumem(");
+	else
+		out("\n\tumem(");
 	out("id:%u", umem->id);
 	out(",size:%llu", umem->size);
 	out(",num_pages:%u", umem->num_pages);
@@ -4574,7 +4597,10 @@  static int tipc_show_sock(struct nlmsghdr *nlh, void *arg)
 	proc_ctx_print(&ss);
 
 	if (show_tipcinfo) {
-		out("\n type:%s", stype_nameg[ss.type]);
+		if (oneline)
+			out(" type:%s", stype_nameg[ss.type]);
+		else
+			out("\n type:%s", stype_nameg[ss.type]);
 		out(" cong:%s ",
 		       stat[TIPC_NLA_SOCK_STAT_LINK_CONG] ? "link" :
 		       stat[TIPC_NLA_SOCK_STAT_CONN_CONG] ? "conn" : "none");
@@ -4877,6 +4903,7 @@  static void _usage(FILE *dest)
 "\n"
 "   -K, --kill          forcibly close sockets, display what was closed\n"
 "   -H, --no-header     Suppress header line\n"
+"   -O, --one-line      socket's data printed on a single line\n"
 "\n"
 "   -A, --query=QUERY, --socket=QUERY\n"
 "       QUERY := {all|inet|tcp|udp|raw|unix|unix_dgram|unix_stream|unix_seqpacket|packet|netlink|vsock_stream|vsock_dgram|tipc}[,QUERY]\n"
@@ -5003,6 +5030,7 @@  static const struct option long_opts[] = {
 	{ "kill", 0, 0, 'K' },
 	{ "no-header", 0, 0, 'H' },
 	{ "xdp", 0, 0, OPT_XDPSOCK},
+	{ "one-line", 0, 0, 'O' },
 	{ 0 }
 
 };
@@ -5018,7 +5046,7 @@  int main(int argc, char *argv[])
 	int state_filter = 0;
 
 	while ((ch = getopt_long(argc, argv,
-				 "dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHS",
+				 "dhaletuwxnro460spbEf:miA:D:F:vVzZN:KHSO",
 				 long_opts, NULL)) != EOF) {
 		switch (ch) {
 		case 'n':
@@ -5192,6 +5220,9 @@  int main(int argc, char *argv[])
 		case 'H':
 			show_header = 0;
 			break;
+		case 'O':
+			oneline = 1;
+			break;
 		case 'h':
 			help();
 		case '?':