Re: [PATCH v7 05/10] ss: replaced old output with new generic output mechanisms

2015-10-27 Thread Phil Sutter
On Thu, Sep 10, 2015 at 09:35:03PM +0200, Matthias Tafelmeier wrote:
> This patch just adds the -j and --json flag to ss. Also it ensures proper
> stats components bracketization – that goes for ex. TCP, UDP, NETLINK etc.
> 
> Moreover, this patch prevents human readable headers to be printed.
> 
> Most importantly, with this patch, the new prepared interface to the
> generic output handlers is used to replace the accustomed output
> logic.
> 
> Signed-off-by: Matthias Tafelmeier 
> Suggested-by: Hagen Paul Pfeifer 
> ---
>  misc/ss.c | 487 
> ++
>  1 file changed, 266 insertions(+), 221 deletions(-)
> 
> diff --git a/misc/ss.c b/misc/ss.c
> index e7ea041..7a1b6eb 100644
> --- a/misc/ss.c
> +++ b/misc/ss.c
> @@ -26,6 +26,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "ss_types.h"
>  #include "utils.h"
> @@ -34,6 +35,9 @@
>  #include "libnetlink.h"
>  #include "namespace.h"
>  #include "SNAPSHOT.h"
> +#include "ss_out_fmt.h"
> +#include "ss_json_fmt.h"
> +#include "ss_types.h"
>  
>  #include 
>  #include 
> @@ -101,6 +105,7 @@ int show_sock_ctx = 0;
>  /* If show_users & show_proc_ctx only do user_ent_hash_build() once */
>  int user_ent_hash_build_init = 0;
>  int follow_events = 0;
> +int json_output = 0;
>  
>  int netid_width;
>  int state_width;
> @@ -109,11 +114,14 @@ int addr_width;
>  int serv_width;
>  int screen_width;
>  
> +enum out_fmt_type fmt_type = FMT_HR;
> +
>  static const char *TCP_PROTO = "tcp";
>  static const char *UDP_PROTO = "udp";
>  static const char *RAW_PROTO = "raw";
>  static const char *dg_proto = NULL;
>  
> +json_writer_t *json_wr;

Not sure if doable, but IMHO this should be hidden in ss_json_fmt.c.

>  #define PACKET_DBM ((1<  #define UNIX_DBM ((1< @@ -716,7 +724,6 @@ static int is_ephemeral(int port)
>   return (port >= ip_local_port_min && port<= ip_local_port_max);
>  }
>  
> -

Export changes like this one into a dedicated patch at the start of the
series?

>  static const char *__resolve_service(int port)
>  {
>   struct scache *c;
> @@ -790,7 +797,8 @@ do_numeric:
>   return buf;
>  }
>  
> -static void inet_addr_print(const inet_prefix *a, int port, unsigned int 
> ifindex)
> +static void inet_addr_print(const inet_prefix *a, int port,
> + unsigned int ifindex, char *peer_kind)
>  {
>   char buf[1024];
>   const char *ap = buf;
> @@ -818,8 +826,8 @@ static void inet_addr_print(const inet_prefix *a, int 
> port, unsigned int ifindex
>   est_len -= strlen(ifname) + 1;  /* +1 for percent char */
>   }
>  
> - sock_addr_print_width(est_len, ap, ":", serv_width, 
> resolve_service(port),
> - ifname);
> + sock_addr_fmt(ap, est_len, ":", serv_width, resolve_service(port),
> + ifname, peer_kind);
>  }
>  
>  static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
> @@ -1351,21 +1359,29 @@ static void inet_stats_print(struct sockstat *s, int 
> protocol)
>  {
>   char *buf = NULL;
>  
> - sock_state_print(s, proto_name(protocol));
> + sock_state_fmt(s, sstate_name, proto_name(protocol),
> + netid_width, state_width);
>  
> - inet_addr_print(>local, s->lport, s->iface);
> - inet_addr_print(>remote, s->rport, 0);
> + if (json_output) {
> + jsonw_name(json_wr, "peers");
> + jsonw_start_object(json_wr);
> + }

How about an additional callback:

fmt_new_object("peers");

The hr variant will be a no op, the json variant uses it's private (see
above) json_wr object.

> + inet_addr_print(>local, s->lport, s->iface, "local");
> + inet_addr_print(>remote, s->rport, 0, "remote");
> + if (json_output)
> + jsonw_end_object(json_wr);
>  
>   if (show_proc_ctx || show_sock_ctx) {
>   if (find_entry(s->ino, ,
> - (show_proc_ctx & show_sock_ctx) ?
> - PROC_SOCK_CTX : PROC_CTX) > 0) {
> - printf(" users:(%s)", buf);
> +(show_proc_ctx & show_sock_ctx) ?
> +PROC_SOCK_CTX : PROC_CTX) > 0) {
> + sock_users_fmt(buf);
>   free(buf);
>   }
>   } else if (show_users) {
>   if (find_entry(s->ino, , USERS) > 0) {
> - printf(" users:(%s)", buf);
> + sock_users_fmt(buf);
>   free(buf);
>   }
>   }
> @@ -1469,16 +1485,16 @@ static int tcp_show_line(char *line, const struct 
> filter *f, int family)
>   inet_stats_print(, IPPROTO_TCP);
>  
>   if (show_options)
> - tcp_timer_print();
> + tcp_timer_fmt();
>  
>   if (show_details) {
> -

[PATCH v7 05/10] ss: replaced old output with new generic output mechanisms

2015-09-10 Thread Matthias Tafelmeier
This patch just adds the -j and --json flag to ss. Also it ensures proper
stats components bracketization – that goes for ex. TCP, UDP, NETLINK etc.

Moreover, this patch prevents human readable headers to be printed.

Most importantly, with this patch, the new prepared interface to the
generic output handlers is used to replace the accustomed output
logic.

Signed-off-by: Matthias Tafelmeier 
Suggested-by: Hagen Paul Pfeifer 
---
 misc/ss.c | 487 ++
 1 file changed, 266 insertions(+), 221 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index e7ea041..7a1b6eb 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "ss_types.h"
 #include "utils.h"
@@ -34,6 +35,9 @@
 #include "libnetlink.h"
 #include "namespace.h"
 #include "SNAPSHOT.h"
+#include "ss_out_fmt.h"
+#include "ss_json_fmt.h"
+#include "ss_types.h"
 
 #include 
 #include 
@@ -101,6 +105,7 @@ int show_sock_ctx = 0;
 /* If show_users & show_proc_ctx only do user_ent_hash_build() once */
 int user_ent_hash_build_init = 0;
 int follow_events = 0;
+int json_output = 0;
 
 int netid_width;
 int state_width;
@@ -109,11 +114,14 @@ int addr_width;
 int serv_width;
 int screen_width;
 
+enum out_fmt_type fmt_type = FMT_HR;
+
 static const char *TCP_PROTO = "tcp";
 static const char *UDP_PROTO = "udp";
 static const char *RAW_PROTO = "raw";
 static const char *dg_proto = NULL;
 
+json_writer_t *json_wr;
 
 #define PACKET_DBM ((1<= ip_local_port_min && port<= ip_local_port_max);
 }
 
-
 static const char *__resolve_service(int port)
 {
struct scache *c;
@@ -790,7 +797,8 @@ do_numeric:
return buf;
 }
 
-static void inet_addr_print(const inet_prefix *a, int port, unsigned int 
ifindex)
+static void inet_addr_print(const inet_prefix *a, int port,
+   unsigned int ifindex, char *peer_kind)
 {
char buf[1024];
const char *ap = buf;
@@ -818,8 +826,8 @@ static void inet_addr_print(const inet_prefix *a, int port, 
unsigned int ifindex
est_len -= strlen(ifname) + 1;  /* +1 for percent char */
}
 
-   sock_addr_print_width(est_len, ap, ":", serv_width, 
resolve_service(port),
-   ifname);
+   sock_addr_fmt(ap, est_len, ":", serv_width, resolve_service(port),
+   ifname, peer_kind);
 }
 
 static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
@@ -1351,21 +1359,29 @@ static void inet_stats_print(struct sockstat *s, int 
protocol)
 {
char *buf = NULL;
 
-   sock_state_print(s, proto_name(protocol));
+   sock_state_fmt(s, sstate_name, proto_name(protocol),
+   netid_width, state_width);
 
-   inet_addr_print(>local, s->lport, s->iface);
-   inet_addr_print(>remote, s->rport, 0);
+   if (json_output) {
+   jsonw_name(json_wr, "peers");
+   jsonw_start_object(json_wr);
+   }
+
+   inet_addr_print(>local, s->lport, s->iface, "local");
+   inet_addr_print(>remote, s->rport, 0, "remote");
+   if (json_output)
+   jsonw_end_object(json_wr);
 
if (show_proc_ctx || show_sock_ctx) {
if (find_entry(s->ino, ,
-   (show_proc_ctx & show_sock_ctx) ?
-   PROC_SOCK_CTX : PROC_CTX) > 0) {
-   printf(" users:(%s)", buf);
+  (show_proc_ctx & show_sock_ctx) ?
+  PROC_SOCK_CTX : PROC_CTX) > 0) {
+   sock_users_fmt(buf);
free(buf);
}
} else if (show_users) {
if (find_entry(s->ino, , USERS) > 0) {
-   printf(" users:(%s)", buf);
+   sock_users_fmt(buf);
free(buf);
}
}
@@ -1469,16 +1485,16 @@ static int tcp_show_line(char *line, const struct 
filter *f, int family)
inet_stats_print(, IPPROTO_TCP);
 
if (show_options)
-   tcp_timer_print();
+   tcp_timer_fmt();
 
if (show_details) {
-   sock_details_print();
+   sock_details_fmt(, GENERIC_DETAIL, 0, 0);
if (opt[0])
-   printf(" opt:\"%s\"", opt);
+   opt_fmt(opt);
}
 
if (show_tcpinfo)
-   tcp_stats_print();
+   tcp_stats_fmt();
 
printf("\n");
return 0;
@@ -1522,31 +1538,14 @@ static void print_skmeminfo(struct rtattr *tb[], int 
attrtype)
const struct inet_diag_meminfo *minfo =
RTA_DATA(tb[INET_DIAG_MEMINFO]);