ss: Allow selection of columns to be displayed
Subsystems (2)
cover ss: Allow selection of columns to be displayed
Now that we have an abstraction for columns, it's relatively easy to selectively display only some of them, and Yoann has a use case for it.
Patch 1/3 fixes a rendering issue that shows up only when display of arbitrary columns is disabled. Patch 2/3 implements the relevant option, and patch 3/3 makes the output more readable when some columns are disabled.
Stefano Brivio (3):
ss: Discard empty descriptor at the end of buffer, if any, before
rendering
ss: Introduce option to display selected columns only
ss: Beautify output when arbitrary columns are hidden
man/man8/ss.8 | 5 +++ misc/ss.c | 85 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 13 deletions(-)
Signature · 1 line
2.19.1
PATCH 1/3 ss: Discard empty descriptor at the end of buffer, if any, before rendering
This will allow us to disable display of any given column.
--- misc/ss.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
misc/ss.c +9 -2
@@ -1245,8 +1245,15 @@ static void render(void) token = (struct buf_token *)buffer.head->data; -/* Ensure end alignment of last token, it wasn't necessarily flushed */ - buffer.tail->end += buffer.cur->len %2 ; +if (!buffer.cur->len) { +/* Last token was flushed, a new empty descriptor was appended: +* discard it +*/ + buffer.tail->end -=sizeof (buffer.cur->len); + }else { +/* Last token wasn't flushed: ensure end alignment */ + buffer.tail->end += buffer.cur->len %2 ; + }render_calc_width ();
Signature · 1 line
2.19.1
PATCH 2/3 ss: Introduce option to display selected columns only
In reply to Stefano BrivioThe new option --columns (short: -c) allows to select columns to be displayed. Note that this doesn't affect the order in which columns are displayed.
--- man/man8/ss.8 | 5 +++++ misc/ss.c | 62 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 57 insertions(+), 10 deletions(-)
man/man8/ss.8 +5 -0
@@ -24,6 +24,11 @@ Output version information. .B \-H, \-\-no-header Suppress header line. .TP +.B \-c COLS, \-\-columns=COLS +Only display selected columns, separated by commas. The following column names +are understood: netid, state, local, lport, peer, pport, ext. This does not +define the order of columns. +.TP .B \-n, \-\-numeric Do not try to resolve service names. .TP
misc/ss.c +52 -10
104 lines not on this page · raw message
Signature · 1 line
2.19.1
PATCH 3/3 ss: Beautify output when arbitrary columns are hidden
In reply to Stefano BrivioDefine a secondary alignment for columns in case the next column is hidden, this avoids awkward outputs if e.g. the local address is shown, but not the local port.
Omit embedded delimiter in socket specifiers if the port or service field is hidden.
--- misc/ss.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-)
misc/ss.c +20 -10
@@ -131,7 +131,8 @@ enum col_align { };struct column { -const enum col_align align; +enum col_align align; +const enum col_align align_without_next;const char *optname;const char *header;const char *ldelim;
@@ -141,15 +142,15 @@ struct column { };static struct column columns[] = { - {ALIGN_LEFT ,"netid" ,"Netid" ,"" ,0 ,0 ,0 }, - {ALIGN_LEFT ,"state" ,"State" ," " ,0 ,0 ,0 }, - {ALIGN_LEFT ,"recvq" ,"Recv-Q" ," " ,0 ,0 ,0 }, - {ALIGN_LEFT ,"sendq" ,"Send-Q" ," " ,0 ,0 ,0 }, - {ALIGN_RIGHT ,"local" ,"Local Address:" ," " ,0 ,0 ,0 }, - {ALIGN_LEFT ,"lport" ,"Port" ,"" ,0 ,0 ,0 }, - {ALIGN_RIGHT ,"peer" ,"Peer Address:" ," " ,0 ,0 ,0 }, - {ALIGN_LEFT ,"pport" ,"Port" ,"" ,0 ,0 ,0 }, - {ALIGN_LEFT ,"ext" ,"" ,"" ,0 ,0 ,0 }, + {ALIGN_LEFT ,ALIGN_LEFT ,"netid" ,"Netid" ,"" ,0 ,0 ,0 }, + {ALIGN_LEFT ,ALIGN_LEFT ,"state" ,"State" ," " ,0 ,0 ,0 }, + {ALIGN_LEFT ,ALIGN_LEFT ,"recvq" ,"Recv-Q" ," " ,0 ,0 ,0 }, + {ALIGN_LEFT ,ALIGN_LEFT ,"sendq" ,"Send-Q" ," " ,0 ,0 ,0 }, + {ALIGN_RIGHT ,ALIGN_LEFT ,"local" ,"Local Address:" ," " ,0 ,0 ,0 }, + {ALIGN_LEFT ,ALIGN_LEFT ,"lport" ,"Port" ,"" ,0 ,0 ,0 }, + {ALIGN_RIGHT ,ALIGN_LEFT ,"peer" ,"Peer Address:" ," " ,0 ,0 ,0 }, + {ALIGN_LEFT ,ALIGN_LEFT ,"pport" ,"Port" ,"" ,0 ,0 ,0 }, + {ALIGN_LEFT ,ALIGN_LEFT ,"ext" ,"" ,"" ,0 ,0 ,0 }, };static struct column *current_field = columns;
@@ -1374,6 +1375,9 @@ static void sock_details_print(struct sockstat *s)static void sock_addr_print (const char *addr,char *delim,const char *port,const char *ifname) { +if ((current_field +1 )->disabled) + delim ="" ; +if (ifname)out ("%s" "%%" "%s%s" , addr, ifname, delim);else
@@ -5006,6 +5010,12 @@ int main(int argc, char *argv[]) } p = p1 +1 ; }while (p1); + +for (f = columns;field_is_valid (f +1 ); f++) { +if ((f +1 )->disabled) + f->align = f->align_without_next; + } +break ; }case 'h' :
Signature · 1 line
2.19.1
Quoted 9 lines · Stefano Brivio
Now that we have an abstraction for columns, it's relatively easy to selectively display only some of them, and Yoann has a use case for it.
Patch 1/3 fixes a rendering issue that shows up only when display of arbitrary columns is disabled. Patch 2/3 implements the relevant option, and patch 3/3 makes the output more readable when some columns are disabled.
I like the intent, and I have prototyped something similar for 'ip'.
A more flexible approach is to use format strings to allow users to customize the output order and whitespace as well. So for ss and your column list (winging it here):
netid = %N
state = %S
recv Q = %Qr
send Q = %Qs
local address = %Al
lport port = %Pl remote address = %Ar
remote port = %Pr
process data = %p
...
then a format string could be: "%S %Qr %Qs %Al:%Pl %Ar:%Pr %p\n"
or for csv output: "%S,%Qr,%Qs,%Al,%Pl,%Ar,%Pr,%p\n"
I have not had time to look into an implementation for ip. Conceptually
- and scanning the kernel's vsprintf code - it does not look that difficult, just time consuming on the frontend with the initial setup.
Quoted 28 lines · On Tue, 30 Oct 2018 10:34:45 -0600 David Ahern <[email protected]> wrote:
Quoted 9 lines · Stefano Brivio
Now that we have an abstraction for columns, it's relatively easy to selectively display only some of them, and Yoann has a use case for it.
Patch 1/3 fixes a rendering issue that shows up only when display of arbitrary columns is disabled. Patch 2/3 implements the relevant option, and patch 3/3 makes the output more readable when some columns are disabled.
I like the intent, and I have prototyped something similar for 'ip'.
A more flexible approach is to use format strings to allow users to customize the output order and whitespace as well. So for ss and your column list (winging it here):
netid = %N state = %S recv Q = %Qr send Q = %Qs local address = %Al lport port = %Plremote address = %Ar
remote port = %Pr
process data = %p
...
Quoted 7 lines
then a format string could be: "%S %Qr %Qs %Al:%Pl %Ar:%Pr %p\n"
or for csv output: "%S,%Qr,%Qs,%Al,%Pl,%Ar,%Pr,%p\n"
I have not had time to look into an implementation for ip. Conceptually
- and scanning the kernel's vsprintf code - it does not look that difficult, just time consuming on the frontend with the initial setup.
The problem with custom formats is that you lose all ability for Gcc to check format strings.
Quoted 33 lines · Stephen Hemminger
Quoted 30 lines · On Tue, 30 Oct 2018 10:34:45 -0600 David Ahern <[email protected]> wrote:
Quoted 9 lines · Stefano Brivio
Now that we have an abstraction for columns, it's relatively easy to selectively display only some of them, and Yoann has a use case for it.
Patch 1/3 fixes a rendering issue that shows up only when display of arbitrary columns is disabled. Patch 2/3 implements the relevant option, and patch 3/3 makes the output more readable when some columns are disabled.
I like the intent, and I have prototyped something similar for 'ip'.
A more flexible approach is to use format strings to allow users to customize the output order and whitespace as well. So for ss and your column list (winging it here):
netid = %N state = %S recv Q = %Qr send Q = %Qs local address = %Al lport port = %Plremote address = %Ar
remote port = %Pr
process data = %p
...then a format string could be: "%S %Qr %Qs %Al:%Pl %Ar:%Pr %p\n"
Quoted 9 lines
Quoted 5 lines
or for csv output: "%S,%Qr,%Qs,%Al,%Pl,%Ar,%Pr,%p\n"
I have not had time to look into an implementation for ip. Conceptually
- and scanning the kernel's vsprintf code - it does not look that difficult, just time consuming on the frontend with the initial setup.The problem with custom formats is that you lose all ability for Gcc to check format strings.
Sure, trade-offs. A custom print string is powerful.
While selecting columns is an improvement, column ordering is also important - even handling other output formats (csv).
Quoted 10 lines · On Tue, 30 Oct 2018 10:34:45 -0600 David Ahern <[email protected]> wrote:
A more flexible approach is to use format strings to allow users to customize the output order and whitespace as well. So for ss and your column list (winging it here):
netid = %N state = %S recv Q = %Qr send Q = %Qs local address = %Al lport port = %Pl
Quoted 6 lines
remote address = %Ar
remote port = %Pr
process data = %p
...then a format string could be: "%S %Qr %Qs %Al:%Pl %Ar:%Pr %p\n"
I like the idea indeed, but I see two issues with ss:
- the current column abstraction is rather lightweight, things are already buffered in the defined column order so we don't have to jump back and forth in the buffer while rendering. Doing that needs some extra care to avoid a performance hit, but it's probably doable, I can put that on my to-do list
- how would you model automatic spacing in a format string? Should we support width specifiers? Disable automatic spacing if a format string is given? It might even make sense to allow partial automatic spacing with a special character in the format string, that is:
"%S.%Qr.%Qs %Al:%Pl %Ar:%Pr %p\n"
would mean "align everything to the right, distribute remaining whitespace between %S, %Qr and %Qs". But it looks rather complicated at a glance.
Signature · 1 line
Stefano
[ sorry, too many distractions and I forgot to respond ]
Quoted 20 lines · Stefano Brivio
Quoted 10 lines · On Tue, 30 Oct 2018 10:34:45 -0600 David Ahern <[email protected]> wrote:
A more flexible approach is to use format strings to allow users to customize the output order and whitespace as well. So for ss and your column list (winging it here):
netid = %N state = %S recv Q = %Qr send Q = %Qs local address = %Al lport port = %PlQuoted 6 lines
remote address = %Ar
remote port = %Pr
process data = %p
...then a format string could be: "%S %Qr %Qs %Al:%Pl %Ar:%Pr %p\n"
Quoted 7 lines
I like the idea indeed, but I see two issues with ss:
- the current column abstraction is rather lightweight, things are already buffered in the defined column order so we don't have to jump back and forth in the buffer while rendering. Doing that needs some extra care to avoid a performance hit, but it's probably doable, I can put that on my to-do list
The ss command is always a pain; it's much better in newer releases but I am always having to adjust terminal width.
Quoted 4 lines
- how would you model automatic spacing in a format string? Should we support width specifiers? Disable automatic spacing if a format string is given? It might even make sense to allow partial automatic
Follow the format string for whitespace and order, and yes, on the width specifiers if possible.
Quoted 8 lines
spacing with a special character in the format string, that is:
"%S.%Qr.%Qs %Al:%Pl %Ar:%Pr %p\n"would mean "align everything to the right, distribute remaining whitespace between %S, %Qr and %Qs". But it looks rather complicated at a glance.
My concern here is that once this goes in for 1 command, the others in iproute2 need to follow suit - meaning same syntax style for all commands. Given that I'd prefer we get a reasonable consensus on syntax that will work across commands -- ss, ip, tc. If it is as simple as column names with a fixed order, that is fine but just give proper consideration given the impact.
The 'ip' syntax for example gets ugly quick with the various link types and their options. We don't need to allow every detail of each link type to be customized, but there are common attributes for links (e.g., mtu, ifindex, link flags, lladdr), addresses, and link types such as bridges and bonds where we can improve the amount of data thrown at a user -- a better, more customizable version of what the brief option targeted.
Quoted 9 lines · David Ahern
Quoted 8 lines
spacing with a special character in the format string, that is:
"%S.%Qr.%Qs %Al:%Pl %Ar:%Pr %p\n"would mean "align everything to the right, distribute remaining whitespace between %S, %Qr and %Qs". But it looks rather complicated at a glance.
Quoted 6 lines
My concern here is that once this goes in for 1 command, the others in iproute2 need to follow suit - meaning same syntax style for all commands. Given that I'd prefer we get a reasonable consensus on syntax that will work across commands -- ss, ip, tc. If it is as simple as column names with a fixed order, that is fine but just give proper consideration given the impact.
FWIW I just started piping iproute2 commands to jq. Example:
tc -s -j qdisc show dev em1 | \ jq -r '.[] | [.kind,.parent,.handle,.offloaded,.bytes,.packets,.drops,.overlimits,.requeues,.backlog,.qlen,.marked] | @tsv'
JSONification would probably be quite an undertaking for ss :(
Quoted 17 lines · Jakub Kicinski
Quoted 9 lines · David Ahern
Quoted 8 lines
spacing with a special character in the format string, that is:
"%S.%Qr.%Qs %Al:%Pl %Ar:%Pr %p\n"would mean "align everything to the right, distribute remaining whitespace between %S, %Qr and %Qs". But it looks rather complicated at a glance.
Quoted 6 lines
My concern here is that once this goes in for 1 command, the others in iproute2 need to follow suit - meaning same syntax style for all commands. Given that I'd prefer we get a reasonable consensus on syntax that will work across commands -- ss, ip, tc. If it is as simple as column names with a fixed order, that is fine but just give proper consideration given the impact.
Quoted 7 lines
FWIW I just started piping iproute2 commands to jq. Example:
tc -s -j qdisc show dev em1 | \ jq -r '.[] | [.kind,.parent,.handle,.offloaded,.bytes,.packets,.drops,.overlimits,.requeues,.backlog,.qlen,.marked] | @tsv'JSONification would probably be quite an undertaking for ss :(
Right, that is used in some of the scripts under tools/testing/selftests. I would put that in the 'heavyweight solution' category.
A number of key commands offer the capability to control the output via command line argument (e.g., ps, perf script). Given the amount of data iproute2 commands throw at a user by default, it would be a good usability feature to allow a user to customize the output without having to pipe it into other commands.
Quoted 30 lines · On Thu, 1 Nov 2018 15:18:03 -0600 David Ahern <[email protected]> wrote:
Quoted 17 lines · Jakub Kicinski
Quoted 9 lines · David Ahern
Quoted 8 lines
spacing with a special character in the format string, that is:
"%S.%Qr.%Qs %Al:%Pl %Ar:%Pr %p\n"would mean "align everything to the right, distribute remaining whitespace between %S, %Qr and %Qs". But it looks rather complicated at a glance.
Quoted 6 lines
My concern here is that once this goes in for 1 command, the others in iproute2 need to follow suit - meaning same syntax style for all commands. Given that I'd prefer we get a reasonable consensus on syntax that will work across commands -- ss, ip, tc. If it is as simple as column names with a fixed order, that is fine but just give proper consideration given the impact.
Quoted 7 lines
FWIW I just started piping iproute2 commands to jq. Example:
tc -s -j qdisc show dev em1 | \ jq -r '.[] | [.kind,.parent,.handle,.offloaded,.bytes,.packets,.drops,.overlimits,.requeues,.backlog,.qlen,.marked] | @tsv'JSONification would probably be quite an undertaking for ss :(
Right, that is used in some of the scripts under
tools/testing/selftests. I would put that in the 'heavyweight solution' category.
Quoted 5 lines
A number of key commands offer the capability to control the output via command line argument (e.g., ps, perf script). Given the amount of data iproute2 commands throw at a user by default, it would be a good usability feature to allow a user to customize the output without having to pipe it into other commands.
I would rather see ss grow json support than having to make the output formatting of every iproute2 command grow a new format management.
The jq tool looks cool, and I can see how someone could easily have a bunch of mini-scripts to do what they want.
Quoted 10 lines · On Wed, 31 Oct 2018 20:48:05 -0600 David Ahern <[email protected]> wrote:
Quoted 6 lines · Stefano Brivio
- the current column abstraction is rather lightweight, things are already buffered in the defined column order so we don't have to jump back and forth in the buffer while rendering. Doing that needs some extra care to avoid a performance hit, but it's probably doable, I can put that on my to-do list
The ss command is always a pain; it's much better in newer releases but I am always having to adjust terminal width.
Ouch. Do you have some examples?
Signature · 1 line
Stefano
Quoted 1 line · On Thu, 1 Nov 2018 14:06:23 -0700 Jakub Kicinski <[email protected]> wrote:
JSONification would probably be quite an undertaking for ss :(
Probably not too much, and we would skip buffering for JSON as we don't need to print columns, so we don't have to care about buffering and rendering performance too much.
All it takes is to extend a bit the out() function and pass the right arguments to it -- it looks way easier than implementing format strings, even though I'd like the latter more.
Signature · 1 line
Stefano