]> granicus.if.org Git - sysstat/blob - json_stats.c
Starting sysstat-12.5.4
[sysstat] / json_stats.c
1 /*
2  * json_stats.c: Funtions used by sadf to display statistics in JSON format.
3  * (C) 1999-2021 by Sebastien GODARD (sysstat <at> orange.fr)
4  *
5  ***************************************************************************
6  * This program is free software; you can redistribute it and/or modify it *
7  * under the terms of the GNU General Public License as published  by  the *
8  * Free Software Foundation; either version 2 of the License, or (at  your *
9  * option) any later version.                                              *
10  *                                                                         *
11  * This program is distributed in the hope that it  will  be  useful,  but *
12  * WITHOUT ANY WARRANTY; without the implied warranty  of  MERCHANTABILITY *
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
14  * for more details.                                                       *
15  *                                                                         *
16  * You should have received a copy of the GNU General Public License along *
17  * with this program; if not, write to the Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA              *
19  ***************************************************************************
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdarg.h>
25
26 #include "sa.h"
27 #include "ioconf.h"
28 #include "json_stats.h"
29
30 #ifdef USE_NLS
31 #include <locale.h>
32 #include <libintl.h>
33 #define _(string) gettext(string)
34 #else
35 #define _(string) (string)
36 #endif
37
38 extern uint64_t flags;
39
40 /*
41  ***************************************************************************
42  * Open or close "network" markup.
43  *
44  * IN:
45  * @tab         Number of tabulations.
46  * @action      Open or close action.
47  ***************************************************************************
48  */
49 void json_markup_network(int tab, int action)
50 {
51         static int markup_state = CLOSE_JSON_MARKUP;
52
53         if (action == markup_state)
54                 return;
55         markup_state = action;
56
57         if (action == OPEN_JSON_MARKUP) {
58                 /* Open markup */
59                 xprintf(tab, "\"network\": {");
60         }
61         else {
62                 /* Close markup */
63                 printf("\n");
64                 xprintf0(tab, "}");
65         }
66 }
67
68 /*
69  ***************************************************************************
70  * Open or close "power-management" markup.
71  *
72  * IN:
73  * @tab         Number of tabulations.
74  * @action      Open or close action.
75  ***************************************************************************
76  */
77 void json_markup_power_management(int tab, int action)
78 {
79         static int markup_state = CLOSE_JSON_MARKUP;
80
81         if (action == markup_state)
82                 return;
83         markup_state = action;
84
85         if (action == OPEN_JSON_MARKUP) {
86                 /* Open markup */
87                 xprintf(tab, "\"power-management\": {");
88         }
89         else {
90                 /* Close markup */
91                 printf("\n");
92                 xprintf0(tab, "}");
93         }
94 }
95
96 /*
97  ***************************************************************************
98  * Open or close "psi" markup.
99  *
100  * IN:
101  * @tab         Number of tabulations.
102  * @action      Open or close action.
103  ***************************************************************************
104  */
105 void json_markup_psi(int tab, int action)
106 {
107         static int markup_state = CLOSE_JSON_MARKUP;
108
109         if (action == markup_state)
110                 return;
111         markup_state = action;
112
113         if (action == OPEN_JSON_MARKUP) {
114                 /* Open markup */
115                 xprintf(tab, "\"psi\": {");
116         }
117         else {
118                 /* Close markup */
119                 printf("\n");
120                 xprintf0(tab, "}");
121         }
122 }
123
124 /*
125  ***************************************************************************
126  * Display CPU statistics in JSON.
127  *
128  * IN:
129  * @a           Activity structure with statistics.
130  * @curr        Index in array for current sample statistics.
131  * @tab         Indentation in output.
132  * @itv         Interval of time in 1/100th of a second (independent of the
133  *              number of processors). Unused here.
134  ***************************************************************************
135  */
136 __print_funct_t json_print_cpu_stats(struct activity *a, int curr, int tab,
137                                      unsigned long long itv)
138 {
139         int i;
140         int sep = FALSE;
141         unsigned long long deltot_jiffies = 1;
142         struct stats_cpu *scc, *scp;
143         unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
144         char cpuno[16];
145
146         xprintf(tab++, "\"cpu-load\": [");
147
148         /* @nr[curr] cannot normally be greater than @nr_ini */
149         if (a->nr[curr] > a->nr_ini) {
150                 a->nr_ini = a->nr[curr];
151         }
152
153         /*
154          * Compute CPU "all" as sum of all individual CPU (on SMP machines)
155          * and look for offline CPU.
156          */
157         if (a->nr_ini > 1) {
158                 deltot_jiffies = get_global_cpu_statistics(a, !curr, curr,
159                                                            flags, offline_cpu_bitmap);
160         }
161
162         for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
163
164                 /* Should current CPU (including CPU "all") be displayed? */
165                 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) ||
166                     offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07)))
167                         /* Don't display CPU */
168                         continue;
169
170                 scc = (struct stats_cpu *) ((char *) a->buf[curr]  + i * a->msize);
171                 scp = (struct stats_cpu *) ((char *) a->buf[!curr] + i * a->msize);
172
173                 if (sep) {
174                         printf(",\n");
175                 }
176                 sep = TRUE;
177
178                 if (!i) {
179                         /* This is CPU "all" */
180                         strcpy(cpuno, "all");
181
182                         if (a->nr_ini == 1) {
183                                 /*
184                                  * This is a UP machine. In this case
185                                  * interval has still not been calculated.
186                                  */
187                                 deltot_jiffies = get_per_cpu_interval(scc, scp);
188                         }
189                         if (!deltot_jiffies) {
190                                 /* CPU "all" cannot be tickless */
191                                 deltot_jiffies = 1;
192                         }
193                 }
194                 else {
195                         sprintf(cpuno, "%d", i - 1);
196
197                         /*
198                          * Recalculate interval for current proc.
199                          * If result is 0 then current CPU is a tickless one.
200                          */
201                         deltot_jiffies = get_per_cpu_interval(scc, scp);
202
203                         if (!deltot_jiffies) {
204                                 /* Current CPU is tickless */
205                                 if (DISPLAY_CPU_DEF(a->opt_flags)) {
206                                         xprintf0(tab, "{\"cpu\": \"%d\", "
207                                                  "\"user\": %.2f, "
208                                                  "\"nice\": %.2f, "
209                                                  "\"system\": %.2f, "
210                                                  "\"iowait\": %.2f, "
211                                                  "\"steal\": %.2f, "
212                                                  "\"idle\": %.2f}",
213                                                  i - 1, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0);
214                                 }
215                                 else if (DISPLAY_CPU_ALL(a->opt_flags)) {
216                                         xprintf0(tab, "{\"cpu\": \"%d\", "
217                                                  "\"usr\": %.2f, "
218                                                  "\"nice\": %.2f, "
219                                                  "\"sys\": %.2f, "
220                                                  "\"iowait\": %.2f, "
221                                                  "\"steal\": %.2f, "
222                                                  "\"irq\": %.2f, "
223                                                  "\"soft\": %.2f, "
224                                                  "\"guest\": %.2f, "
225                                                  "\"gnice\": %.2f, "
226                                                  "\"idle\": %.2f}",
227                                                  i - 1, 0.0, 0.0, 0.0, 0.0,
228                                                  0.0, 0.0, 0.0, 0.0, 0.0, 100.0);
229                                 }
230                                 continue;
231                         }
232                 }
233
234                 if (DISPLAY_CPU_DEF(a->opt_flags)) {
235                         xprintf0(tab, "{\"cpu\": \"%s\", "
236                                  "\"user\": %.2f, "
237                                  "\"nice\": %.2f, "
238                                  "\"system\": %.2f, "
239                                  "\"iowait\": %.2f, "
240                                  "\"steal\": %.2f, "
241                                  "\"idle\": %.2f}",
242                                  cpuno,
243                                  ll_sp_value(scp->cpu_user, scc->cpu_user, deltot_jiffies),
244                                  ll_sp_value(scp->cpu_nice, scc->cpu_nice, deltot_jiffies),
245                                  ll_sp_value(scp->cpu_sys + scp->cpu_hardirq + scp->cpu_softirq,
246                                              scc->cpu_sys + scc->cpu_hardirq + scc->cpu_softirq,
247                                              deltot_jiffies),
248                                  ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies),
249                                  ll_sp_value(scp->cpu_steal, scc->cpu_steal, deltot_jiffies),
250                                  scc->cpu_idle < scp->cpu_idle ?
251                                  0.0 :
252                                  ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies));
253                 }
254                 else if (DISPLAY_CPU_ALL(a->opt_flags)) {
255                         xprintf0(tab, "{\"cpu\": \"%s\", "
256                                  "\"usr\": %.2f, "
257                                  "\"nice\": %.2f, "
258                                  "\"sys\": %.2f, "
259                                  "\"iowait\": %.2f, "
260                                  "\"steal\": %.2f, "
261                                  "\"irq\": %.2f, "
262                                  "\"soft\": %.2f, "
263                                  "\"guest\": %.2f, "
264                                  "\"gnice\": %.2f, "
265                                  "\"idle\": %.2f}",
266                                  cpuno,
267                                  (scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest) ?
268                                  0.0 :
269                                  ll_sp_value(scp->cpu_user - scp->cpu_guest,
270                                              scc->cpu_user - scc->cpu_guest, deltot_jiffies),
271                                  (scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice) ?
272                                  0.0 :
273                                  ll_sp_value(scp->cpu_nice - scp->cpu_guest_nice,
274                                              scc->cpu_nice - scc->cpu_guest_nice, deltot_jiffies),
275                                  ll_sp_value(scp->cpu_sys, scc->cpu_sys, deltot_jiffies),
276                                  ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies),
277                                  ll_sp_value(scp->cpu_steal, scc->cpu_steal, deltot_jiffies),
278                                  ll_sp_value(scp->cpu_hardirq, scc->cpu_hardirq, deltot_jiffies),
279                                  ll_sp_value(scp->cpu_softirq, scc->cpu_softirq, deltot_jiffies),
280                                  ll_sp_value(scp->cpu_guest, scc->cpu_guest, deltot_jiffies),
281                                  ll_sp_value(scp->cpu_guest_nice, scc->cpu_guest_nice, deltot_jiffies),
282                                  scc->cpu_idle < scp->cpu_idle ?
283                                  0.0 :
284                                  ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies));
285                 }
286         }
287
288         printf("\n");
289         xprintf0(--tab, "]");
290 }
291
292 /*
293  ***************************************************************************
294  * Display task creation and context switch statistics in JSON.
295  *
296  * IN:
297  * @a           Activity structure with statistics.
298  * @curr        Index in array for current sample statistics.
299  * @tab         Indentation in output.
300  * @itv         Interval of time in 1/100th of a second.
301  ***************************************************************************
302  */
303 __print_funct_t json_print_pcsw_stats(struct activity *a, int curr, int tab,
304                                       unsigned long long itv)
305 {
306         struct stats_pcsw
307                 *spc = (struct stats_pcsw *) a->buf[curr],
308                 *spp = (struct stats_pcsw *) a->buf[!curr];
309
310         /* proc/s and cswch/s */
311         xprintf0(tab, "\"process-and-context-switch\": {"
312                  "\"proc\": %.2f, "
313                  "\"cswch\": %.2f}",
314                  S_VALUE(spp->processes, spc->processes, itv),
315                  S_VALUE(spp->context_switch, spc->context_switch, itv));
316 }
317
318 /*
319  ***************************************************************************
320  * Display interrupts statistics in JSON.
321  *
322  * IN:
323  * @a           Activity structure with statistics.
324  * @curr        Index in array for current sample statistics.
325  * @tab         Indentation in output.
326  * @itv         Interval of time in 1/100th of a second.
327  ***************************************************************************
328  */
329 __print_funct_t json_print_irq_stats(struct activity *a, int curr, int tab,
330                                      unsigned long long itv)
331 {
332         int i;
333         struct stats_irq *sic, *sip;
334         int sep = FALSE;
335         char irqno[16];
336
337         xprintf(tab++, "\"interrupts\": [");
338
339         for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
340
341                 sic = (struct stats_irq *) ((char *) a->buf[curr]  + i * a->msize);
342                 sip = (struct stats_irq *) ((char *) a->buf[!curr] + i * a->msize);
343
344                 /* Should current interrupt (including int "sum") be displayed? */
345                 if (a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) {
346
347                         /* Yes: Display it */
348
349                         if (sep) {
350                                 printf(",\n");
351                         }
352                         sep = TRUE;
353
354                         if (!i) {
355                                 /* This is interrupt "sum" */
356                                 strcpy(irqno, "sum");
357                         }
358                         else {
359                                 sprintf(irqno, "%d", i - 1);
360                         }
361
362                         xprintf0(tab, "{\"intr\": \"%s\", "
363                                  "\"value\": %.2f}",
364                                  irqno,
365                                  S_VALUE(sip->irq_nr, sic->irq_nr, itv));
366                 }
367         }
368
369         printf("\n");
370         xprintf0(--tab, "]");
371 }
372
373 /*
374  ***************************************************************************
375  * Display swapping statistics in JSON.
376  *
377  * IN:
378  * @a           Activity structure with statistics.
379  * @curr        Index in array for current sample statistics.
380  * @tab         Indentation in output.
381  * @itv         Interval of time in 1/100th of a second.
382  ***************************************************************************
383  */
384 __print_funct_t json_print_swap_stats(struct activity *a, int curr, int tab,
385                                       unsigned long long itv)
386 {
387         struct stats_swap
388                 *ssc = (struct stats_swap *) a->buf[curr],
389                 *ssp = (struct stats_swap *) a->buf[!curr];
390
391         xprintf0(tab, "\"swap-pages\": {"
392                  "\"pswpin\": %.2f, "
393                  "\"pswpout\": %.2f}",
394                  S_VALUE(ssp->pswpin,  ssc->pswpin,  itv),
395                  S_VALUE(ssp->pswpout, ssc->pswpout, itv));
396 }
397
398 /*
399  ***************************************************************************
400  * Display paging statistics in JSON.
401  *
402  * IN:
403  * @a           Activity structure with statistics.
404  * @curr        Index in array for current sample statistics.
405  * @tab         Indentation in output.
406  * @itv         Interval of time in 1/100th of a second.
407  ***************************************************************************
408  */
409 __print_funct_t json_print_paging_stats(struct activity *a, int curr, int tab,
410                                         unsigned long long itv)
411 {
412         struct stats_paging
413                 *spc = (struct stats_paging *) a->buf[curr],
414                 *spp = (struct stats_paging *) a->buf[!curr];
415
416         xprintf0(tab, "\"paging\": {"
417                  "\"pgpgin\": %.2f, "
418                  "\"pgpgout\": %.2f, "
419                  "\"fault\": %.2f, "
420                  "\"majflt\": %.2f, "
421                  "\"pgfree\": %.2f, "
422                  "\"pgscank\": %.2f, "
423                  "\"pgscand\": %.2f, "
424                  "\"pgsteal\": %.2f, "
425                  "\"vmeff-percent\": %.2f}",
426                  S_VALUE(spp->pgpgin,        spc->pgpgin,        itv),
427                  S_VALUE(spp->pgpgout,       spc->pgpgout,       itv),
428                  S_VALUE(spp->pgfault,       spc->pgfault,       itv),
429                  S_VALUE(spp->pgmajfault,    spc->pgmajfault,    itv),
430                  S_VALUE(spp->pgfree,        spc->pgfree,        itv),
431                  S_VALUE(spp->pgscan_kswapd, spc->pgscan_kswapd, itv),
432                  S_VALUE(spp->pgscan_direct, spc->pgscan_direct, itv),
433                  S_VALUE(spp->pgsteal,       spc->pgsteal,       itv),
434                  (spc->pgscan_kswapd + spc->pgscan_direct -
435                   spp->pgscan_kswapd - spp->pgscan_direct) ?
436                  SP_VALUE(spp->pgsteal, spc->pgsteal,
437                           spc->pgscan_kswapd + spc->pgscan_direct -
438                           spp->pgscan_kswapd - spp->pgscan_direct) : 0.0);
439 }
440
441 /*
442  ***************************************************************************
443  * Display I/O and transfer rate statistics in JSON.
444  *
445  * IN:
446  * @a           Activity structure with statistics.
447  * @curr        Index in array for current sample statistics.
448  * @tab         Indentation in output.
449  * @itv         Interval of time in 1/100th of a second.
450  ***************************************************************************
451  */
452 __print_funct_t json_print_io_stats(struct activity *a, int curr, int tab,
453                                     unsigned long long itv)
454 {
455         struct stats_io
456                 *sic = (struct stats_io *) a->buf[curr],
457                 *sip = (struct stats_io *) a->buf[!curr];
458
459         xprintf0(tab, "\"io\": {"
460                  "\"tps\": %.2f, "
461                  "\"io-reads\": {"
462                  "\"rtps\": %.2f, "
463                  "\"bread\": %.2f}, "
464                  "\"io-writes\": {"
465                  "\"wtps\": %.2f, "
466                  "\"bwrtn\": %.2f}, "
467                  "\"io-discard\": {"
468                  "\"dtps\": %.2f, "
469                  "\"bdscd\": %.2f}}",
470                  /*
471                   * If we get negative values, this is probably because
472                   * one or more devices/filesystems have been unmounted.
473                   * We display 0.0 in this case though we should rather tell
474                   * the user that the value cannot be calculated here.
475                   */
476                  sic->dk_drive < sip->dk_drive ? 0.0 :
477                  S_VALUE(sip->dk_drive, sic->dk_drive, itv),
478                  sic->dk_drive_rio < sip->dk_drive_rio ? 0.0 :
479                  S_VALUE(sip->dk_drive_rio, sic->dk_drive_rio, itv),
480                  sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 :
481                  S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv),
482                  sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 :
483                  S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv),
484                  sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 :
485                  S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv),
486                  sic->dk_drive_dio < sip->dk_drive_dio ? 0.0 :
487                  S_VALUE(sip->dk_drive_dio, sic->dk_drive_dio, itv),
488                  sic->dk_drive_dblk < sip->dk_drive_dblk ? 0.0 :
489                  S_VALUE(sip->dk_drive_dblk, sic->dk_drive_dblk, itv));
490 }
491
492 /*
493  ***************************************************************************
494  * Display memory statistics in JSON.
495  *
496  * IN:
497  * @a           Activity structure with statistics.
498  * @curr        Index in array for current sample statistics.
499  * @tab         Indentation in output.
500  * @itv         Interval of time in 1/100th of a second.
501  ***************************************************************************
502  */
503 __print_funct_t json_print_memory_stats(struct activity *a, int curr, int tab,
504                                         unsigned long long itv)
505 {
506         struct stats_memory
507                 *smc = (struct stats_memory *) a->buf[curr];
508         int sep = FALSE;
509         unsigned long long nousedmem;
510
511         xprintf0(tab, "\"memory\": {");
512
513         if (DISPLAY_MEMORY(a->opt_flags)) {
514
515                 sep = TRUE;
516
517                 nousedmem = smc->frmkb + smc->bufkb + smc->camkb + smc->slabkb;
518                 if (nousedmem > smc->tlmkb) {
519                         nousedmem = smc->tlmkb;
520                 }
521
522                 printf("\"memfree\": %llu, "
523                        "\"avail\": %llu, "
524                        "\"memused\": %llu, "
525                        "\"memused-percent\": %.2f, "
526                        "\"buffers\": %llu, "
527                        "\"cached\": %llu, "
528                        "\"commit\": %llu, "
529                        "\"commit-percent\": %.2f, "
530                        "\"active\": %llu, "
531                        "\"inactive\": %llu, "
532                        "\"dirty\": %llu",
533                        smc->frmkb,
534                        smc->availablekb,
535                        smc->tlmkb - nousedmem,
536                        smc->tlmkb ?
537                        SP_VALUE(nousedmem, smc->tlmkb, smc->tlmkb) :
538                        0.0,
539                        smc->bufkb,
540                        smc->camkb,
541                        smc->comkb,
542                        (smc->tlmkb + smc->tlskb) ?
543                        SP_VALUE(0, smc->comkb, smc->tlmkb + smc->tlskb) :
544                        0.0,
545                        smc->activekb,
546                        smc->inactkb,
547                        smc->dirtykb);
548
549                 if (DISPLAY_MEM_ALL(a->opt_flags)) {
550                         /* Display extended memory stats */
551                         printf(", \"anonpg\": %llu, "
552                                "\"slab\": %llu, "
553                                "\"kstack\": %llu, "
554                                "\"pgtbl\": %llu, "
555                                "\"vmused\": %llu",
556                                smc->anonpgkb,
557                                smc->slabkb,
558                                smc->kstackkb,
559                                smc->pgtblkb,
560                                smc->vmusedkb);
561                 }
562         }
563
564         if (DISPLAY_SWAP(a->opt_flags)) {
565
566                 if (sep) {
567                         printf(", ");
568                 }
569                 sep = TRUE;
570
571                 printf("\"swpfree\": %llu, "
572                        "\"swpused\": %llu, "
573                        "\"swpused-percent\": %.2f, "
574                        "\"swpcad\": %llu, "
575                        "\"swpcad-percent\": %.2f",
576                        smc->frskb,
577                        smc->tlskb - smc->frskb,
578                        smc->tlskb ?
579                        SP_VALUE(smc->frskb, smc->tlskb, smc->tlskb) :
580                        0.0,
581                        smc->caskb,
582                        (smc->tlskb - smc->frskb) ?
583                        SP_VALUE(0, smc->caskb, smc->tlskb - smc->frskb) :
584                        0.0);
585         }
586
587         printf("}");
588 }
589
590 /*
591  ***************************************************************************
592  * Display kernel tables statistics in JSON.
593  *
594  * IN:
595  * @a           Activity structure with statistics.
596  * @curr        Index in array for current sample statistics.
597  * @tab         Indentation in output.
598  * @itv         Interval of time in 1/100th of a second.
599  ***************************************************************************
600  */
601 __print_funct_t json_print_ktables_stats(struct activity *a, int curr, int tab,
602                                          unsigned long long itv)
603 {
604         struct stats_ktables
605                 *skc = (struct stats_ktables *) a->buf[curr];
606
607         xprintf0(tab, "\"kernel\": {"
608                  "\"dentunusd\": %llu, "
609                  "\"file-nr\": %llu, "
610                  "\"inode-nr\": %llu, "
611                  "\"pty-nr\": %llu}",
612                  skc->dentry_stat,
613                  skc->file_used,
614                  skc->inode_used,
615                  skc->pty_nr);
616 }
617
618 /*
619  ***************************************************************************
620  * Display queue and load statistics in JSON.
621  *
622  * IN:
623  * @a           Activity structure with statistics.
624  * @curr        Index in array for current sample statistics.
625  * @tab         Indentation in output.
626  * @itv         Interval of time in 1/100th of a second.
627  ***************************************************************************
628  */
629 __print_funct_t json_print_queue_stats(struct activity *a, int curr, int tab,
630                                        unsigned long long itv)
631 {
632         struct stats_queue
633                 *sqc = (struct stats_queue *) a->buf[curr];
634
635         xprintf0(tab, "\"queue\": {"
636                  "\"runq-sz\": %llu, "
637                  "\"plist-sz\": %llu, "
638                  "\"ldavg-1\": %.2f, "
639                  "\"ldavg-5\": %.2f, "
640                  "\"ldavg-15\": %.2f, "
641                  "\"blocked\": %llu}",
642                  sqc->nr_running,
643                  sqc->nr_threads,
644                  (double) sqc->load_avg_1 / 100,
645                  (double) sqc->load_avg_5 / 100,
646                  (double) sqc->load_avg_15 / 100,
647                  sqc->procs_blocked);
648 }
649
650 /*
651  ***************************************************************************
652  * Display serial lines statistics in JSON.
653  *
654  * IN:
655  * @a           Activity structure with statistics.
656  * @curr        Index in array for current sample statistics.
657  * @tab         Indentation in output.
658  * @itv         Interval of time in 1/100th of a second.
659  ***************************************************************************
660  */
661 __print_funct_t json_print_serial_stats(struct activity *a, int curr, int tab,
662                                         unsigned long long itv)
663 {
664         int i, j, j0, found;
665         struct stats_serial *ssc, *ssp;
666         int sep = FALSE;
667
668         xprintf(tab++, "\"serial\": [");
669
670         for (i = 0; i < a->nr[curr]; i++) {
671
672                 found = FALSE;
673
674                 if (a->nr[!curr] > 0) {
675                         ssc = (struct stats_serial *) ((char *) a->buf[curr] + i * a->msize);
676
677                         /* Look for corresponding serial line in previous iteration */
678                         j = i;
679
680                         if (j >= a->nr[!curr]) {
681                                 j = a->nr[!curr] - 1;
682                         }
683
684                         j0 = j;
685
686                         do {
687                                 ssp = (struct stats_serial *) ((char *) a->buf[!curr] + j * a->msize);
688                                 if (ssc->line == ssp->line) {
689                                         found = TRUE;
690                                         break;
691                                 }
692                                 if (++j >= a->nr[!curr]) {
693                                         j = 0;
694                                 }
695                         }
696                         while (j != j0);
697                 }
698
699                 if (!found)
700                         continue;
701
702                 if (sep) {
703                         printf(",\n");
704                 }
705                 sep = TRUE;
706
707                 xprintf0(tab, "{\"line\": %d, "
708                          "\"rcvin\": %.2f, "
709                          "\"xmtin\": %.2f, "
710                          "\"framerr\": %.2f, "
711                          "\"prtyerr\": %.2f, "
712                          "\"brk\": %.2f, "
713                          "\"ovrun\": %.2f}",
714                          ssc->line,
715                          S_VALUE(ssp->rx,      ssc->rx,      itv),
716                          S_VALUE(ssp->tx,      ssc->tx,      itv),
717                          S_VALUE(ssp->frame,   ssc->frame,   itv),
718                          S_VALUE(ssp->parity,  ssc->parity,  itv),
719                          S_VALUE(ssp->brk,     ssc->brk,     itv),
720                          S_VALUE(ssp->overrun, ssc->overrun, itv));
721         }
722
723         printf("\n");
724         xprintf0(--tab, "]");
725 }
726
727 /*
728  ***************************************************************************
729  * Display disks statistics in JSON.
730  *
731  * IN:
732  * @a           Activity structure with statistics.
733  * @curr        Index in array for current sample statistics.
734  * @tab         Indentation in output.
735  * @itv         Interval of time in 1/100th of a second.
736  ***************************************************************************
737  */
738 __print_funct_t json_print_disk_stats(struct activity *a, int curr, int tab,
739                                       unsigned long long itv)
740 {
741         int i, j;
742         struct stats_disk *sdc, *sdp, sdpzero;
743         struct ext_disk_stats xds;
744         int sep = FALSE;
745         char *dev_name;
746
747         memset(&sdpzero, 0, STATS_DISK_SIZE);
748
749         xprintf(tab++, "\"disk\": [");
750
751         for (i = 0; i < a->nr[curr]; i++) {
752
753                 sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
754
755                 j = check_disk_reg(a, curr, !curr, i);
756                 if (j < 0) {
757                         /* This is a newly registered interface. Previous stats are zero */
758                         sdp = &sdpzero;
759                 }
760                 else {
761                         sdp = (struct stats_disk *) ((char *) a->buf[!curr] + j * a->msize);
762                 }
763
764                 /* Get device name */
765                 dev_name = get_device_name(sdc->major, sdc->minor, sdc->wwn, sdc->part_nr,
766                                            DISPLAY_PRETTY(flags), DISPLAY_PERSIST_NAME_S(flags),
767                                            USE_STABLE_ID(flags), NULL);
768
769                 if (a->item_list != NULL) {
770                         /* A list of devices has been entered on the command line */
771                         if (!search_list_item(a->item_list, dev_name))
772                                 /* Device not found */
773                                 continue;
774                 }
775
776                 /* Compute extended statistics values */
777                 compute_ext_disk_stats(sdc, sdp, itv, &xds);
778
779                 if (sep) {
780                         printf(",\n");
781                 }
782                 sep = TRUE;
783
784                 xprintf0(tab, "{\"disk-device\": \"%s\", "
785                          "\"tps\": %.2f, "
786                          "\"rd_sec\": %.2f, "
787                          "\"wr_sec\": %.2f, "
788                          "\"dc_sec\": %.2f, "
789                          "\"rkB\": %.2f, "
790                          "\"wkB\": %.2f, "
791                          "\"dkB\": %.2f, "
792                          "\"avgrq-sz\": %.2f, "
793                          "\"areq-sz\": %.2f, "
794                          "\"avgqu-sz\": %.2f, "
795                          "\"aqu-sz\": %.2f, "
796                          "\"await\": %.2f, "
797                          "\"util-percent\": %.2f}",
798                          /* Confusion possible here between index and minor numbers */
799                          dev_name,
800                          S_VALUE(sdp->nr_ios, sdc->nr_ios, itv),
801                          S_VALUE(sdp->rd_sect, sdc->rd_sect, itv), /* Unit = sectors (for backward compatibility) */
802                          S_VALUE(sdp->wr_sect, sdc->wr_sect, itv),
803                          S_VALUE(sdp->dc_sect, sdc->dc_sect, itv),
804                          S_VALUE(sdp->rd_sect, sdc->rd_sect, itv) / 2,
805                          S_VALUE(sdp->wr_sect, sdc->wr_sect, itv) / 2,
806                          S_VALUE(sdp->dc_sect, sdc->dc_sect, itv) / 2,
807                          /* See iostat for explanations */
808                          xds.arqsz,     /* Unit = sectors (for backward compatibility) */
809                          xds.arqsz / 2,
810                          S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0,   /* For backward compatibility */
811                          S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0,
812                          xds.await,
813                          xds.util / 10.0);
814         }
815
816         printf("\n");
817         xprintf0(--tab, "]");
818 }
819
820 /*
821  ***************************************************************************
822  * Display network interfaces statistics in JSON.
823  *
824  * IN:
825  * @a           Activity structure with statistics.
826  * @curr        Index in array for current sample statistics.
827  * @tab         Indentation in output.
828  * @itv         Interval of time in 1/100th of a second.
829  ***************************************************************************
830  */
831 __print_funct_t json_print_net_dev_stats(struct activity *a, int curr, int tab,
832                                          unsigned long long itv)
833 {
834         int i, j;
835         struct stats_net_dev *sndc, *sndp, sndzero;
836         int sep = FALSE;
837         double rxkb, txkb, ifutil;
838
839         memset(&sndzero, 0, STATS_NET_DEV_SIZE);
840
841         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
842                 goto close_json_markup;
843
844         json_markup_network(tab, OPEN_JSON_MARKUP);
845         tab++;
846
847         xprintf(tab++, "\"net-dev\": [");
848
849         for (i = 0; i < a->nr[curr]; i++) {
850
851                 sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize);
852
853                 if (a->item_list != NULL) {
854                         /* A list of devices has been entered on the command line */
855                         if (!search_list_item(a->item_list, sndc->interface))
856                                 /* Device not found */
857                                 continue;
858                 }
859
860                 j = check_net_dev_reg(a, curr, !curr, i);
861                 if (j < 0) {
862                         /* This is a newly registered interface. Previous stats are zero */
863                         sndp = &sndzero;
864                 }
865                 else {
866                         sndp = (struct stats_net_dev *) ((char *) a->buf[!curr] + j * a->msize);
867                 }
868
869                 if (sep) {
870                         printf(",\n");
871                 }
872                 sep = TRUE;
873
874                 rxkb = S_VALUE(sndp->rx_bytes, sndc->rx_bytes, itv);
875                 txkb = S_VALUE(sndp->tx_bytes, sndc->tx_bytes, itv);
876                 ifutil = compute_ifutil(sndc, rxkb, txkb);
877
878                 xprintf0(tab, "{\"iface\": \"%s\", "
879                          "\"rxpck\": %.2f, "
880                          "\"txpck\": %.2f, "
881                          "\"rxkB\": %.2f, "
882                          "\"txkB\": %.2f, "
883                          "\"rxcmp\": %.2f, "
884                          "\"txcmp\": %.2f, "
885                          "\"rxmcst\": %.2f, "
886                          "\"ifutil-percent\": %.2f}",
887                          sndc->interface,
888                          S_VALUE(sndp->rx_packets,    sndc->rx_packets,    itv),
889                          S_VALUE(sndp->tx_packets,    sndc->tx_packets,    itv),
890                          rxkb / 1024,
891                          txkb / 1024,
892                          S_VALUE(sndp->rx_compressed, sndc->rx_compressed, itv),
893                          S_VALUE(sndp->tx_compressed, sndc->tx_compressed, itv),
894                          S_VALUE(sndp->multicast,     sndc->multicast,     itv),
895                          ifutil);
896         }
897
898         printf("\n");
899         xprintf0(--tab, "]");
900
901         tab--;
902
903 close_json_markup:
904         if (CLOSE_MARKUP(a->options)) {
905                 json_markup_network(tab, CLOSE_JSON_MARKUP);
906         }
907 }
908
909 /*
910  ***************************************************************************
911  * Display network interfaces errors statistics in JSON.
912  *
913  * IN:
914  * @a           Activity structure with statistics.
915  * @curr        Index in array for current sample statistics.
916  * @tab         Indentation in output.
917  * @itv         Interval of time in 1/100th of a second.
918  ***************************************************************************
919  */
920 __print_funct_t json_print_net_edev_stats(struct activity *a, int curr, int tab,
921                                           unsigned long long itv)
922 {
923         int i, j;
924         struct stats_net_edev *snedc, *snedp, snedzero;
925         int sep = FALSE;
926
927         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
928                 goto close_json_markup;
929
930         memset(&snedzero, 0, STATS_NET_EDEV_SIZE);
931
932         json_markup_network(tab, OPEN_JSON_MARKUP);
933         tab++;
934
935         xprintf(tab++, "\"net-edev\": [");
936
937         for (i = 0; i < a->nr[curr]; i++) {
938
939                 snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize);
940
941                 if (a->item_list != NULL) {
942                         /* A list of devices has been entered on the command line */
943                         if (!search_list_item(a->item_list, snedc->interface))
944                                 /* Device not found */
945                                 continue;
946                 }
947
948                 j = check_net_edev_reg(a, curr, !curr, i);
949                 if (j < 0) {
950                         /* This is a newly registered interface. Previous stats are zero */
951                         snedp = &snedzero;
952                 }
953                 else {
954                         snedp = (struct stats_net_edev *) ((char *) a->buf[!curr] + j * a->msize);
955                 }
956
957                 if (sep) {
958                         printf(",\n");
959                 }
960                 sep = TRUE;
961
962                 xprintf0(tab, "{\"iface\": \"%s\", "
963                          "\"rxerr\": %.2f, "
964                          "\"txerr\": %.2f, "
965                          "\"coll\": %.2f, "
966                          "\"rxdrop\": %.2f, "
967                          "\"txdrop\": %.2f, "
968                          "\"txcarr\": %.2f, "
969                          "\"rxfram\": %.2f, "
970                          "\"rxfifo\": %.2f, "
971                          "\"txfifo\": %.2f}",
972                          snedc->interface,
973                          S_VALUE(snedp->rx_errors,         snedc->rx_errors,         itv),
974                          S_VALUE(snedp->tx_errors,         snedc->tx_errors,         itv),
975                          S_VALUE(snedp->collisions,        snedc->collisions,        itv),
976                          S_VALUE(snedp->rx_dropped,        snedc->rx_dropped,        itv),
977                          S_VALUE(snedp->tx_dropped,        snedc->tx_dropped,        itv),
978                          S_VALUE(snedp->tx_carrier_errors, snedc->tx_carrier_errors, itv),
979                          S_VALUE(snedp->rx_frame_errors,   snedc->rx_frame_errors,   itv),
980                          S_VALUE(snedp->rx_fifo_errors,    snedc->rx_fifo_errors,    itv),
981                          S_VALUE(snedp->tx_fifo_errors,    snedc->tx_fifo_errors,    itv));
982         }
983
984         printf("\n");
985         xprintf0(--tab, "]");
986
987         tab--;
988
989 close_json_markup:
990         if (CLOSE_MARKUP(a->options)) {
991                 json_markup_network(tab, CLOSE_JSON_MARKUP);
992         }
993 }
994
995 /*
996  ***************************************************************************
997  * Display NFS client statistics in JSON.
998  *
999  * IN:
1000  * @a           Activity structure with statistics.
1001  * @curr        Index in array for current sample statistics.
1002  * @tab         Indentation in output.
1003  * @itv         Interval of time in 1/100th of a second.
1004  ***************************************************************************
1005  */
1006 __print_funct_t json_print_net_nfs_stats(struct activity *a, int curr, int tab,
1007                                          unsigned long long itv)
1008 {
1009         struct stats_net_nfs
1010                 *snnc = (struct stats_net_nfs *) a->buf[curr],
1011                 *snnp = (struct stats_net_nfs *) a->buf[!curr];
1012
1013         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1014                 goto close_json_markup;
1015
1016         json_markup_network(tab, OPEN_JSON_MARKUP);
1017         tab++;
1018
1019         xprintf0(tab, "\"net-nfs\": {"
1020                  "\"call\": %.2f, "
1021                  "\"retrans\": %.2f, "
1022                  "\"read\": %.2f, "
1023                  "\"write\": %.2f, "
1024                  "\"access\": %.2f, "
1025                  "\"getatt\": %.2f}",
1026                  S_VALUE(snnp->nfs_rpccnt,     snnc->nfs_rpccnt,     itv),
1027                  S_VALUE(snnp->nfs_rpcretrans, snnc->nfs_rpcretrans, itv),
1028                  S_VALUE(snnp->nfs_readcnt,    snnc->nfs_readcnt,    itv),
1029                  S_VALUE(snnp->nfs_writecnt,   snnc->nfs_writecnt,   itv),
1030                  S_VALUE(snnp->nfs_accesscnt,  snnc->nfs_accesscnt,  itv),
1031                  S_VALUE(snnp->nfs_getattcnt,  snnc->nfs_getattcnt,  itv));
1032         tab--;
1033
1034 close_json_markup:
1035         if (CLOSE_MARKUP(a->options)) {
1036                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1037         }
1038 }
1039
1040 /*
1041  ***************************************************************************
1042  * Display NFS server statistics in JSON.
1043  *
1044  * IN:
1045  * @a           Activity structure with statistics.
1046  * @curr        Index in array for current sample statistics.
1047  * @tab         Indentation in output.
1048  * @itv         Interval of time in 1/100th of a second.
1049  ***************************************************************************
1050  */
1051 __print_funct_t json_print_net_nfsd_stats(struct activity *a, int curr, int tab,
1052                                           unsigned long long itv)
1053 {
1054         struct stats_net_nfsd
1055                 *snndc = (struct stats_net_nfsd *) a->buf[curr],
1056                 *snndp = (struct stats_net_nfsd *) a->buf[!curr];
1057
1058         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1059                 goto close_json_markup;
1060
1061         json_markup_network(tab, OPEN_JSON_MARKUP);
1062         tab++;
1063
1064         xprintf0(tab, "\"net-nfsd\": {"
1065                  "\"scall\": %.2f, "
1066                  "\"badcall\": %.2f, "
1067                  "\"packet\": %.2f, "
1068                  "\"udp\": %.2f, "
1069                  "\"tcp\": %.2f, "
1070                  "\"hit\": %.2f, "
1071                  "\"miss\": %.2f, "
1072                  "\"sread\": %.2f, "
1073                  "\"swrite\": %.2f, "
1074                  "\"saccess\": %.2f, "
1075                  "\"sgetatt\": %.2f}",
1076                  S_VALUE(snndp->nfsd_rpccnt,    snndc->nfsd_rpccnt,    itv),
1077                  S_VALUE(snndp->nfsd_rpcbad,    snndc->nfsd_rpcbad,    itv),
1078                  S_VALUE(snndp->nfsd_netcnt,    snndc->nfsd_netcnt,    itv),
1079                  S_VALUE(snndp->nfsd_netudpcnt, snndc->nfsd_netudpcnt, itv),
1080                  S_VALUE(snndp->nfsd_nettcpcnt, snndc->nfsd_nettcpcnt, itv),
1081                  S_VALUE(snndp->nfsd_rchits,    snndc->nfsd_rchits,    itv),
1082                  S_VALUE(snndp->nfsd_rcmisses,  snndc->nfsd_rcmisses,  itv),
1083                  S_VALUE(snndp->nfsd_readcnt,   snndc->nfsd_readcnt,   itv),
1084                  S_VALUE(snndp->nfsd_writecnt,  snndc->nfsd_writecnt,  itv),
1085                  S_VALUE(snndp->nfsd_accesscnt, snndc->nfsd_accesscnt, itv),
1086                  S_VALUE(snndp->nfsd_getattcnt, snndc->nfsd_getattcnt, itv));
1087         tab--;
1088
1089 close_json_markup:
1090         if (CLOSE_MARKUP(a->options)) {
1091                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1092         }
1093 }
1094
1095 /*
1096  ***************************************************************************
1097  * Display network socket statistics in JSON.
1098  *
1099  * IN:
1100  * @a           Activity structure with statistics.
1101  * @curr        Index in array for current sample statistics.
1102  * @tab         Indentation in output.
1103  * @itv         Interval of time in 1/100th of a second.
1104  ***************************************************************************
1105  */
1106 __print_funct_t json_print_net_sock_stats(struct activity *a, int curr, int tab,
1107                                           unsigned long long itv)
1108 {
1109         struct stats_net_sock
1110                 *snsc = (struct stats_net_sock *) a->buf[curr];
1111
1112         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1113                 goto close_json_markup;
1114
1115         json_markup_network(tab, OPEN_JSON_MARKUP);
1116         tab++;
1117
1118         xprintf0(tab, "\"net-sock\": {"
1119                  "\"totsck\": %u, "
1120                  "\"tcpsck\": %u, "
1121                  "\"udpsck\": %u, "
1122                  "\"rawsck\": %u, "
1123                  "\"ip-frag\": %u, "
1124                  "\"tcp-tw\": %u}",
1125                  snsc->sock_inuse,
1126                  snsc->tcp_inuse,
1127                  snsc->udp_inuse,
1128                  snsc->raw_inuse,
1129                  snsc->frag_inuse,
1130                  snsc->tcp_tw);
1131         tab--;
1132
1133 close_json_markup:
1134         if (CLOSE_MARKUP(a->options)) {
1135                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1136         }
1137 }
1138
1139 /*
1140  ***************************************************************************
1141  * Display IP network statistics in JSON.
1142  *
1143  * IN:
1144  * @a           Activity structure with statistics.
1145  * @curr        Index in array for current sample statistics.
1146  * @tab         Indentation in output.
1147  * @itv         Interval of time in 1/100th of a second.
1148  ***************************************************************************
1149  */
1150 __print_funct_t json_print_net_ip_stats(struct activity *a, int curr, int tab,
1151                                         unsigned long long itv)
1152 {
1153         struct stats_net_ip
1154                 *snic = (struct stats_net_ip *) a->buf[curr],
1155                 *snip = (struct stats_net_ip *) a->buf[!curr];
1156
1157         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1158                 goto close_json_markup;
1159
1160         json_markup_network(tab, OPEN_JSON_MARKUP);
1161         tab++;
1162
1163         xprintf0(tab, "\"net-ip\": {"
1164                  "\"irec\": %.2f, "
1165                  "\"fwddgm\": %.2f, "
1166                  "\"idel\": %.2f, "
1167                  "\"orq\": %.2f, "
1168                  "\"asmrq\": %.2f, "
1169                  "\"asmok\": %.2f, "
1170                  "\"fragok\": %.2f, "
1171                  "\"fragcrt\": %.2f}",
1172                  S_VALUE(snip->InReceives,    snic->InReceives,    itv),
1173                  S_VALUE(snip->ForwDatagrams, snic->ForwDatagrams, itv),
1174                  S_VALUE(snip->InDelivers,    snic->InDelivers,    itv),
1175                  S_VALUE(snip->OutRequests,   snic->OutRequests,   itv),
1176                  S_VALUE(snip->ReasmReqds,    snic->ReasmReqds,    itv),
1177                  S_VALUE(snip->ReasmOKs,      snic->ReasmOKs,      itv),
1178                  S_VALUE(snip->FragOKs,       snic->FragOKs,       itv),
1179                  S_VALUE(snip->FragCreates,   snic->FragCreates,   itv));
1180         tab--;
1181
1182 close_json_markup:
1183         if (CLOSE_MARKUP(a->options)) {
1184                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1185         }
1186 }
1187
1188 /*
1189  ***************************************************************************
1190  * Display IP network errors statistics in JSON.
1191  *
1192  * IN:
1193  * @a           Activity structure with statistics.
1194  * @curr        Index in array for current sample statistics.
1195  * @tab         Indentation in output.
1196  * @itv         Interval of time in 1/100th of a second.
1197  ***************************************************************************
1198  */
1199 __print_funct_t json_print_net_eip_stats(struct activity *a, int curr, int tab,
1200                                          unsigned long long itv)
1201 {
1202         struct stats_net_eip
1203                 *sneic = (struct stats_net_eip *) a->buf[curr],
1204                 *sneip = (struct stats_net_eip *) a->buf[!curr];
1205
1206         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1207                 goto close_json_markup;
1208
1209         json_markup_network(tab, OPEN_JSON_MARKUP);
1210         tab++;
1211
1212         xprintf0(tab, "\"net-eip\": {"
1213                  "\"ihdrerr\": %.2f, "
1214                  "\"iadrerr\": %.2f, "
1215                  "\"iukwnpr\": %.2f, "
1216                  "\"idisc\": %.2f, "
1217                  "\"odisc\": %.2f, "
1218                  "\"onort\": %.2f, "
1219                  "\"asmf\": %.2f, "
1220                  "\"fragf\": %.2f}",
1221                  S_VALUE(sneip->InHdrErrors,     sneic->InHdrErrors,     itv),
1222                  S_VALUE(sneip->InAddrErrors,    sneic->InAddrErrors,    itv),
1223                  S_VALUE(sneip->InUnknownProtos, sneic->InUnknownProtos, itv),
1224                  S_VALUE(sneip->InDiscards,      sneic->InDiscards,      itv),
1225                  S_VALUE(sneip->OutDiscards,     sneic->OutDiscards,     itv),
1226                  S_VALUE(sneip->OutNoRoutes,     sneic->OutNoRoutes,     itv),
1227                  S_VALUE(sneip->ReasmFails,      sneic->ReasmFails,      itv),
1228                  S_VALUE(sneip->FragFails,       sneic->FragFails,       itv));
1229         tab--;
1230
1231 close_json_markup:
1232         if (CLOSE_MARKUP(a->options)) {
1233                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1234         }
1235 }
1236
1237 /*
1238  ***************************************************************************
1239  * Display ICMP network statistics in JSON.
1240  *
1241  * IN:
1242  * @a           Activity structure with statistics.
1243  * @curr        Index in array for current sample statistics.
1244  * @tab         Indentation in output.
1245  * @itv         Interval of time in 1/100th of a second.
1246  ***************************************************************************
1247  */
1248 __print_funct_t json_print_net_icmp_stats(struct activity *a, int curr, int tab,
1249                                           unsigned long long itv)
1250 {
1251         struct stats_net_icmp
1252                 *snic = (struct stats_net_icmp *) a->buf[curr],
1253                 *snip = (struct stats_net_icmp *) a->buf[!curr];
1254
1255         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1256                 goto close_json_markup;
1257
1258         json_markup_network(tab, OPEN_JSON_MARKUP);
1259         tab++;
1260
1261         xprintf0(tab, "\"net-icmp\": {"
1262                  "\"imsg\": %.2f, "
1263                  "\"omsg\": %.2f, "
1264                  "\"iech\": %.2f, "
1265                  "\"iechr\": %.2f, "
1266                  "\"oech\": %.2f, "
1267                  "\"oechr\": %.2f, "
1268                  "\"itm\": %.2f, "
1269                  "\"itmr\": %.2f, "
1270                  "\"otm\": %.2f, "
1271                  "\"otmr\": %.2f, "
1272                  "\"iadrmk\": %.2f, "
1273                  "\"iadrmkr\": %.2f, "
1274                  "\"oadrmk\": %.2f, "
1275                  "\"oadrmkr\": %.2f}",
1276                  S_VALUE(snip->InMsgs,           snic->InMsgs,           itv),
1277                  S_VALUE(snip->OutMsgs,          snic->OutMsgs,          itv),
1278                  S_VALUE(snip->InEchos,          snic->InEchos,          itv),
1279                  S_VALUE(snip->InEchoReps,       snic->InEchoReps,       itv),
1280                  S_VALUE(snip->OutEchos,         snic->OutEchos,         itv),
1281                  S_VALUE(snip->OutEchoReps,      snic->OutEchoReps,      itv),
1282                  S_VALUE(snip->InTimestamps,     snic->InTimestamps,     itv),
1283                  S_VALUE(snip->InTimestampReps,  snic->InTimestampReps,  itv),
1284                  S_VALUE(snip->OutTimestamps,    snic->OutTimestamps,    itv),
1285                  S_VALUE(snip->OutTimestampReps, snic->OutTimestampReps, itv),
1286                  S_VALUE(snip->InAddrMasks,      snic->InAddrMasks,      itv),
1287                  S_VALUE(snip->InAddrMaskReps,   snic->InAddrMaskReps,   itv),
1288                  S_VALUE(snip->OutAddrMasks,     snic->OutAddrMasks,     itv),
1289                  S_VALUE(snip->OutAddrMaskReps,  snic->OutAddrMaskReps,  itv));
1290         tab--;
1291
1292 close_json_markup:
1293         if (CLOSE_MARKUP(a->options)) {
1294                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1295         }
1296 }
1297
1298 /*
1299  ***************************************************************************
1300  * Display ICMP errors message statistics in JSON.
1301  *
1302  * IN:
1303  * @a           Activity structure with statistics.
1304  * @curr        Index in array for current sample statistics.
1305  * @tab         Indentation in output.
1306  * @itv         Interval of time in 1/100th of a second.
1307  ***************************************************************************
1308  */
1309 __print_funct_t json_print_net_eicmp_stats(struct activity *a, int curr, int tab,
1310                                            unsigned long long itv)
1311 {
1312         struct stats_net_eicmp
1313                 *sneic = (struct stats_net_eicmp *) a->buf[curr],
1314                 *sneip = (struct stats_net_eicmp *) a->buf[!curr];
1315
1316         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1317                 goto close_json_markup;
1318
1319         json_markup_network(tab, OPEN_JSON_MARKUP);
1320         tab++;
1321
1322         xprintf0(tab, "\"net-eicmp\": {"
1323                  "\"ierr\": %.2f, "
1324                  "\"oerr\": %.2f, "
1325                  "\"idstunr\": %.2f, "
1326                  "\"odstunr\": %.2f, "
1327                  "\"itmex\": %.2f, "
1328                  "\"otmex\": %.2f, "
1329                  "\"iparmpb\": %.2f, "
1330                  "\"oparmpb\": %.2f, "
1331                  "\"isrcq\": %.2f, "
1332                  "\"osrcq\": %.2f, "
1333                  "\"iredir\": %.2f, "
1334                  "\"oredir\": %.2f}",
1335                  S_VALUE(sneip->InErrors,        sneic->InErrors,        itv),
1336                  S_VALUE(sneip->OutErrors,       sneic->OutErrors,       itv),
1337                  S_VALUE(sneip->InDestUnreachs,  sneic->InDestUnreachs,  itv),
1338                  S_VALUE(sneip->OutDestUnreachs, sneic->OutDestUnreachs, itv),
1339                  S_VALUE(sneip->InTimeExcds,     sneic->InTimeExcds,     itv),
1340                  S_VALUE(sneip->OutTimeExcds,    sneic->OutTimeExcds,    itv),
1341                  S_VALUE(sneip->InParmProbs,     sneic->InParmProbs,     itv),
1342                  S_VALUE(sneip->OutParmProbs,    sneic->OutParmProbs,    itv),
1343                  S_VALUE(sneip->InSrcQuenchs,    sneic->InSrcQuenchs,    itv),
1344                  S_VALUE(sneip->OutSrcQuenchs,   sneic->OutSrcQuenchs,   itv),
1345                  S_VALUE(sneip->InRedirects,     sneic->InRedirects,     itv),
1346                  S_VALUE(sneip->OutRedirects,    sneic->OutRedirects,    itv));
1347         tab--;
1348
1349 close_json_markup:
1350         if (CLOSE_MARKUP(a->options)) {
1351                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1352         }
1353 }
1354
1355 /*
1356  ***************************************************************************
1357  * Display TCP network statistics in JSON.
1358  *
1359  * IN:
1360  * @a           Activity structure with statistics.
1361  * @curr        Index in array for current sample statistics.
1362  * @tab         Indentation in output.
1363  * @itv         Interval of time in 1/100th of a second.
1364  ***************************************************************************
1365  */
1366 __print_funct_t json_print_net_tcp_stats(struct activity *a, int curr, int tab,
1367                                          unsigned long long itv)
1368 {
1369         struct stats_net_tcp
1370                 *sntc = (struct stats_net_tcp *) a->buf[curr],
1371                 *sntp = (struct stats_net_tcp *) a->buf[!curr];
1372
1373         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1374                 goto close_json_markup;
1375
1376         json_markup_network(tab, OPEN_JSON_MARKUP);
1377         tab++;
1378
1379         xprintf0(tab, "\"net-tcp\": {"
1380                  "\"active\": %.2f, "
1381                  "\"passive\": %.2f, "
1382                  "\"iseg\": %.2f, "
1383                  "\"oseg\": %.2f}",
1384                  S_VALUE(sntp->ActiveOpens,  sntc->ActiveOpens,  itv),
1385                  S_VALUE(sntp->PassiveOpens, sntc->PassiveOpens, itv),
1386                  S_VALUE(sntp->InSegs,       sntc->InSegs,       itv),
1387                  S_VALUE(sntp->OutSegs,      sntc->OutSegs,      itv));
1388         tab--;
1389
1390 close_json_markup:
1391         if (CLOSE_MARKUP(a->options)) {
1392                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1393         }
1394 }
1395
1396 /*
1397  ***************************************************************************
1398  * Display TCP network errors statistics in JSON.
1399  *
1400  * IN:
1401  * @a           Activity structure with statistics.
1402  * @curr        Index in array for current sample statistics.
1403  * @tab         Indentation in XML output.
1404  * @itv         Interval of time in 1/100th of a second.
1405  ***************************************************************************
1406  */
1407 __print_funct_t json_print_net_etcp_stats(struct activity *a, int curr, int tab,
1408                                           unsigned long long itv)
1409 {
1410         struct stats_net_etcp
1411                 *snetc = (struct stats_net_etcp *) a->buf[curr],
1412                 *snetp = (struct stats_net_etcp *) a->buf[!curr];
1413
1414         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1415                 goto close_json_markup;
1416
1417         json_markup_network(tab, OPEN_JSON_MARKUP);
1418         tab++;
1419
1420         xprintf0(tab, "\"net-etcp\": {"
1421                  "\"atmptf\": %.2f, "
1422                  "\"estres\": %.2f, "
1423                  "\"retrans\": %.2f, "
1424                  "\"isegerr\": %.2f, "
1425                  "\"orsts\": %.2f}",
1426                  S_VALUE(snetp->AttemptFails, snetc->AttemptFails,  itv),
1427                  S_VALUE(snetp->EstabResets,  snetc->EstabResets,  itv),
1428                  S_VALUE(snetp->RetransSegs,  snetc->RetransSegs,  itv),
1429                  S_VALUE(snetp->InErrs,       snetc->InErrs,  itv),
1430                  S_VALUE(snetp->OutRsts,      snetc->OutRsts,  itv));
1431         tab--;
1432
1433 close_json_markup:
1434         if (CLOSE_MARKUP(a->options)) {
1435                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1436         }
1437 }
1438
1439 /*
1440  ***************************************************************************
1441  * Display UDP network statistics in JSON.
1442  *
1443  * IN:
1444  * @a           Activity structure with statistics.
1445  * @curr        Index in array for current sample statistics.
1446  * @tab         Indentation in output.
1447  * @itv         Interval of time in 1/100th of a second.
1448  ***************************************************************************
1449  */
1450 __print_funct_t json_print_net_udp_stats(struct activity *a, int curr, int tab,
1451                                          unsigned long long itv)
1452 {
1453         struct stats_net_udp
1454                 *snuc = (struct stats_net_udp *) a->buf[curr],
1455                 *snup = (struct stats_net_udp *) a->buf[!curr];
1456
1457         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1458                 goto close_json_markup;
1459
1460         json_markup_network(tab, OPEN_JSON_MARKUP);
1461         tab++;
1462
1463         xprintf0(tab, "\"net-udp\": {"
1464                  "\"idgm\": %.2f, "
1465                  "\"odgm\": %.2f, "
1466                  "\"noport\": %.2f, "
1467                  "\"idgmerr\": %.2f}",
1468                  S_VALUE(snup->InDatagrams,  snuc->InDatagrams,  itv),
1469                  S_VALUE(snup->OutDatagrams, snuc->OutDatagrams, itv),
1470                  S_VALUE(snup->NoPorts,      snuc->NoPorts,      itv),
1471                  S_VALUE(snup->InErrors,     snuc->InErrors,     itv));
1472         tab--;
1473
1474 close_json_markup:
1475         if (CLOSE_MARKUP(a->options)) {
1476                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1477         }
1478 }
1479
1480 /*
1481  ***************************************************************************
1482  * Display IPv6 network socket statistics in JSON.
1483  *
1484  * IN:
1485  * @a           Activity structure with statistics.
1486  * @curr        Index in array for current sample statistics.
1487  * @tab         Indentation in output.
1488  * @itv         Interval of time in 1/100th of a second.
1489  ***************************************************************************
1490  */
1491 __print_funct_t json_print_net_sock6_stats(struct activity *a, int curr, int tab,
1492                                            unsigned long long itv)
1493 {
1494         struct stats_net_sock6
1495                 *snsc = (struct stats_net_sock6 *) a->buf[curr];
1496
1497         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1498                 goto close_json_markup;
1499
1500         json_markup_network(tab, OPEN_JSON_MARKUP);
1501         tab++;
1502
1503         xprintf0(tab, "\"net-sock6\": {"
1504                  "\"tcp6sck\": %u, "
1505                  "\"udp6sck\": %u, "
1506                  "\"raw6sck\": %u, "
1507                  "\"ip6-frag\": %u}",
1508                  snsc->tcp6_inuse,
1509                  snsc->udp6_inuse,
1510                  snsc->raw6_inuse,
1511                  snsc->frag6_inuse);
1512         tab--;
1513
1514 close_json_markup:
1515         if (CLOSE_MARKUP(a->options)) {
1516                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1517         }
1518 }
1519
1520 /*
1521  ***************************************************************************
1522  * Display IPv6 network statistics in JSON.
1523  *
1524  * IN:
1525  * @a           Activity structure with statistics.
1526  * @curr        Index in array for current sample statistics.
1527  * @tab         Indentation in output.
1528  * @itv         Interval of time in 1/100th of a second.
1529  ***************************************************************************
1530  */
1531 __print_funct_t json_print_net_ip6_stats(struct activity *a, int curr, int tab,
1532                                          unsigned long long itv)
1533 {
1534         struct stats_net_ip6
1535                 *snic = (struct stats_net_ip6 *) a->buf[curr],
1536                 *snip = (struct stats_net_ip6 *) a->buf[!curr];
1537
1538         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1539                 goto close_json_markup;
1540
1541         json_markup_network(tab, OPEN_JSON_MARKUP);
1542         tab++;
1543
1544         xprintf0(tab, "\"net-ip6\": {"
1545                  "\"irec6\": %.2f, "
1546                  "\"fwddgm6\": %.2f, "
1547                  "\"idel6\": %.2f, "
1548                  "\"orq6\": %.2f, "
1549                  "\"asmrq6\": %.2f, "
1550                  "\"asmok6\": %.2f, "
1551                  "\"imcpck6\": %.2f, "
1552                  "\"omcpck6\": %.2f, "
1553                  "\"fragok6\": %.2f, "
1554                  "\"fragcr6\": %.2f}",
1555                  S_VALUE(snip->InReceives6,       snic->InReceives6,       itv),
1556                  S_VALUE(snip->OutForwDatagrams6, snic->OutForwDatagrams6, itv),
1557                  S_VALUE(snip->InDelivers6,       snic->InDelivers6,       itv),
1558                  S_VALUE(snip->OutRequests6,      snic->OutRequests6,      itv),
1559                  S_VALUE(snip->ReasmReqds6,       snic->ReasmReqds6,       itv),
1560                  S_VALUE(snip->ReasmOKs6,         snic->ReasmOKs6,         itv),
1561                  S_VALUE(snip->InMcastPkts6,      snic->InMcastPkts6,      itv),
1562                  S_VALUE(snip->OutMcastPkts6,     snic->OutMcastPkts6,     itv),
1563                  S_VALUE(snip->FragOKs6,          snic->FragOKs6,          itv),
1564                  S_VALUE(snip->FragCreates6,      snic->FragCreates6,      itv));
1565         tab--;
1566
1567 close_json_markup:
1568         if (CLOSE_MARKUP(a->options)) {
1569                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1570         }
1571 }
1572
1573 /*
1574  ***************************************************************************
1575  * Display IPv6 network errors statistics in JSON.
1576  *
1577  * IN:
1578  * @a           Activity structure with statistics.
1579  * @curr        Index in array for current sample statistics.
1580  * @tab         Indentation in output.
1581  * @itv         Interval of time in 1/100th of a second.
1582  ***************************************************************************
1583  */
1584 __print_funct_t json_print_net_eip6_stats(struct activity *a, int curr, int tab,
1585                                           unsigned long long itv)
1586 {
1587         struct stats_net_eip6
1588                 *sneic = (struct stats_net_eip6 *) a->buf[curr],
1589                 *sneip = (struct stats_net_eip6 *) a->buf[!curr];
1590
1591         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1592                 goto close_json_markup;
1593
1594         json_markup_network(tab, OPEN_JSON_MARKUP);
1595         tab++;
1596
1597         xprintf0(tab, "\"net-eip6\": {"
1598                  "\"ihdrer6\": %.2f, "
1599                  "\"iadrer6\": %.2f, "
1600                  "\"iukwnp6\": %.2f, "
1601                  "\"i2big6\": %.2f, "
1602                  "\"idisc6\": %.2f, "
1603                  "\"odisc6\": %.2f, "
1604                  "\"inort6\": %.2f, "
1605                  "\"onort6\": %.2f, "
1606                  "\"asmf6\": %.2f, "
1607                  "\"fragf6\": %.2f, "
1608                  "\"itrpck6\": %.2f}",
1609                  S_VALUE(sneip->InHdrErrors6,     sneic->InHdrErrors6,     itv),
1610                  S_VALUE(sneip->InAddrErrors6,    sneic->InAddrErrors6,    itv),
1611                  S_VALUE(sneip->InUnknownProtos6, sneic->InUnknownProtos6, itv),
1612                  S_VALUE(sneip->InTooBigErrors6,  sneic->InTooBigErrors6,  itv),
1613                  S_VALUE(sneip->InDiscards6,      sneic->InDiscards6,      itv),
1614                  S_VALUE(sneip->OutDiscards6,     sneic->OutDiscards6,     itv),
1615                  S_VALUE(sneip->InNoRoutes6,      sneic->InNoRoutes6,      itv),
1616                  S_VALUE(sneip->OutNoRoutes6,     sneic->OutNoRoutes6,     itv),
1617                  S_VALUE(sneip->ReasmFails6,      sneic->ReasmFails6,      itv),
1618                  S_VALUE(sneip->FragFails6,       sneic->FragFails6,       itv),
1619                  S_VALUE(sneip->InTruncatedPkts6, sneic->InTruncatedPkts6, itv));
1620         tab--;
1621
1622 close_json_markup:
1623         if (CLOSE_MARKUP(a->options)) {
1624                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1625         }
1626 }
1627
1628 /*
1629  ***************************************************************************
1630  * Display ICMPv6 network statistics in JSON.
1631  *
1632  * IN:
1633  * @a           Activity structure with statistics.
1634  * @curr        Index in array for current sample statistics.
1635  * @tab         Indentation in output.
1636  * @itv         Interval of time in 1/100th of a second.
1637  ***************************************************************************
1638  */
1639 __print_funct_t json_print_net_icmp6_stats(struct activity *a, int curr, int tab,
1640                                            unsigned long long itv)
1641 {
1642         struct stats_net_icmp6
1643                 *snic = (struct stats_net_icmp6 *) a->buf[curr],
1644                 *snip = (struct stats_net_icmp6 *) a->buf[!curr];
1645
1646         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1647                 goto close_json_markup;
1648
1649         json_markup_network(tab, OPEN_JSON_MARKUP);
1650         tab++;
1651
1652         xprintf0(tab, "\"net-icmp6\": {"
1653                  "\"imsg6\": %.2f, "
1654                  "\"omsg6\": %.2f, "
1655                  "\"iech6\": %.2f, "
1656                  "\"iechr6\": %.2f, "
1657                  "\"oechr6\": %.2f, "
1658                  "\"igmbq6\": %.2f, "
1659                  "\"igmbr6\": %.2f, "
1660                  "\"ogmbr6\": %.2f, "
1661                  "\"igmbrd6\": %.2f, "
1662                  "\"ogmbrd6\": %.2f, "
1663                  "\"irtsol6\": %.2f, "
1664                  "\"ortsol6\": %.2f, "
1665                  "\"irtad6\": %.2f, "
1666                  "\"inbsol6\": %.2f, "
1667                  "\"onbsol6\": %.2f, "
1668                  "\"inbad6\": %.2f, "
1669                  "\"onbad6\": %.2f}",
1670                  S_VALUE(snip->InMsgs6,                    snic->InMsgs6,                    itv),
1671                  S_VALUE(snip->OutMsgs6,                   snic->OutMsgs6,                   itv),
1672                  S_VALUE(snip->InEchos6,                   snic->InEchos6,                   itv),
1673                  S_VALUE(snip->InEchoReplies6,             snic->InEchoReplies6,             itv),
1674                  S_VALUE(snip->OutEchoReplies6,            snic->OutEchoReplies6,            itv),
1675                  S_VALUE(snip->InGroupMembQueries6,        snic->InGroupMembQueries6,        itv),
1676                  S_VALUE(snip->InGroupMembResponses6,      snic->InGroupMembResponses6,      itv),
1677                  S_VALUE(snip->OutGroupMembResponses6,     snic->OutGroupMembResponses6,     itv),
1678                  S_VALUE(snip->InGroupMembReductions6,     snic->InGroupMembReductions6,     itv),
1679                  S_VALUE(snip->OutGroupMembReductions6,    snic->OutGroupMembReductions6,    itv),
1680                  S_VALUE(snip->InRouterSolicits6,          snic->InRouterSolicits6,          itv),
1681                  S_VALUE(snip->OutRouterSolicits6,         snic->OutRouterSolicits6,         itv),
1682                  S_VALUE(snip->InRouterAdvertisements6,    snic->InRouterAdvertisements6,    itv),
1683                  S_VALUE(snip->InNeighborSolicits6,        snic->InNeighborSolicits6,        itv),
1684                  S_VALUE(snip->OutNeighborSolicits6,       snic->OutNeighborSolicits6,       itv),
1685                  S_VALUE(snip->InNeighborAdvertisements6,  snic->InNeighborAdvertisements6,  itv),
1686                  S_VALUE(snip->OutNeighborAdvertisements6, snic->OutNeighborAdvertisements6, itv));
1687         tab--;
1688
1689 close_json_markup:
1690         if (CLOSE_MARKUP(a->options)) {
1691                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1692         }
1693 }
1694
1695 /*
1696  ***************************************************************************
1697  * Display ICMPv6 error messages statistics in JSON.
1698  *
1699  * IN:
1700  * @a           Activity structure with statistics.
1701  * @curr        Index in array for current sample statistics.
1702  * @tab         Indentation in output.
1703  * @itv         Interval of time in 1/100th of a second.
1704  ***************************************************************************
1705  */
1706 __print_funct_t json_print_net_eicmp6_stats(struct activity *a, int curr, int tab,
1707                                             unsigned long long itv)
1708 {
1709         struct stats_net_eicmp6
1710                 *sneic = (struct stats_net_eicmp6 *) a->buf[curr],
1711                 *sneip = (struct stats_net_eicmp6 *) a->buf[!curr];
1712
1713         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1714                 goto close_json_markup;
1715
1716         json_markup_network(tab, OPEN_JSON_MARKUP);
1717         tab++;
1718
1719         xprintf0(tab, "\"net-eicmp6\": {"
1720                  "\"ierr6\": %.2f, "
1721                  "\"idtunr6\": %.2f, "
1722                  "\"odtunr6\": %.2f, "
1723                  "\"itmex6\": %.2f, "
1724                  "\"otmex6\": %.2f, "
1725                  "\"iprmpb6\": %.2f, "
1726                  "\"oprmpb6\": %.2f, "
1727                  "\"iredir6\": %.2f, "
1728                  "\"oredir6\": %.2f, "
1729                  "\"ipck2b6\": %.2f, "
1730                  "\"opck2b6\": %.2f}",
1731                  S_VALUE(sneip->InErrors6,        sneic->InErrors6,        itv),
1732                  S_VALUE(sneip->InDestUnreachs6,  sneic->InDestUnreachs6,  itv),
1733                  S_VALUE(sneip->OutDestUnreachs6, sneic->OutDestUnreachs6, itv),
1734                  S_VALUE(sneip->InTimeExcds6,     sneic->InTimeExcds6,     itv),
1735                  S_VALUE(sneip->OutTimeExcds6,    sneic->OutTimeExcds6,    itv),
1736                  S_VALUE(sneip->InParmProblems6,  sneic->InParmProblems6,  itv),
1737                  S_VALUE(sneip->OutParmProblems6, sneic->OutParmProblems6, itv),
1738                  S_VALUE(sneip->InRedirects6,     sneic->InRedirects6,     itv),
1739                  S_VALUE(sneip->OutRedirects6,    sneic->OutRedirects6,    itv),
1740                  S_VALUE(sneip->InPktTooBigs6,    sneic->InPktTooBigs6,    itv),
1741                  S_VALUE(sneip->OutPktTooBigs6,   sneic->OutPktTooBigs6,   itv));
1742         tab--;
1743
1744 close_json_markup:
1745         if (CLOSE_MARKUP(a->options)) {
1746                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1747         }
1748 }
1749
1750 /*
1751  ***************************************************************************
1752  * Display UDPv6 network statistics in JSON.
1753  *
1754  * IN:
1755  * @a           Activity structure with statistics.
1756  * @curr        Index in array for current sample statistics.
1757  * @tab         Indentation in output.
1758  * @itv         Interval of time in 1/100th of a second.
1759  ***************************************************************************
1760  */
1761 __print_funct_t json_print_net_udp6_stats(struct activity *a, int curr, int tab,
1762                                           unsigned long long itv)
1763 {
1764         struct stats_net_udp6
1765                 *snuc = (struct stats_net_udp6 *) a->buf[curr],
1766                 *snup = (struct stats_net_udp6 *) a->buf[!curr];
1767
1768         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1769                 goto close_json_markup;
1770
1771         json_markup_network(tab, OPEN_JSON_MARKUP);
1772         tab++;
1773
1774         xprintf0(tab, "\"net-udp6\": {"
1775                  "\"idgm6\": %.2f, "
1776                  "\"odgm6\": %.2f, "
1777                  "\"noport6\": %.2f, "
1778                  "\"idgmer6\": %.2f}",
1779                  S_VALUE(snup->InDatagrams6,  snuc->InDatagrams6,  itv),
1780                  S_VALUE(snup->OutDatagrams6, snuc->OutDatagrams6, itv),
1781                  S_VALUE(snup->NoPorts6,      snuc->NoPorts6,      itv),
1782                  S_VALUE(snup->InErrors6,     snuc->InErrors6,     itv));
1783         tab--;
1784
1785 close_json_markup:
1786         if (CLOSE_MARKUP(a->options)) {
1787                 json_markup_network(tab, CLOSE_JSON_MARKUP);
1788         }
1789 }
1790
1791 /*
1792  ***************************************************************************
1793  * Display CPU frequency statistics in JSON.
1794  *
1795  * IN:
1796  * @a           Activity structure with statistics.
1797  * @curr        Index in array for current sample statistics.
1798  * @tab         Indentation in output.
1799  * @itv         Interval of time in 1/100th of a second.
1800  ***************************************************************************
1801  */
1802 __print_funct_t json_print_pwr_cpufreq_stats(struct activity *a, int curr, int tab,
1803                                              unsigned long long itv)
1804 {
1805         int i;
1806         struct stats_pwr_cpufreq *spc;
1807         int sep = FALSE;
1808         char cpuno[16];
1809
1810         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1811                 goto close_json_markup;
1812
1813         json_markup_power_management(tab, OPEN_JSON_MARKUP);
1814         tab++;
1815
1816         xprintf(tab++, "\"cpu-frequency\": [");
1817
1818         for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
1819
1820                 spc = (struct stats_pwr_cpufreq *) ((char *) a->buf[curr] + i * a->msize);
1821
1822                 /* Should current CPU (including CPU "all") be displayed? */
1823                 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
1824                         /* No */
1825                         continue;
1826
1827                 if (!i) {
1828                         /* This is CPU "all" */
1829                         strcpy(cpuno, "all");
1830                 }
1831                 else {
1832                         sprintf(cpuno, "%d", i - 1);
1833                 }
1834
1835                 if (sep) {
1836                         printf(",\n");
1837                 }
1838                 sep = TRUE;
1839
1840                 xprintf0(tab, "{\"number\": \"%s\", "
1841                          "\"frequency\": %.2f}",
1842                          cpuno,
1843                          ((double) spc->cpufreq) / 100);
1844         }
1845
1846         printf("\n");
1847         xprintf0(--tab, "]");
1848         tab--;
1849
1850 close_json_markup:
1851         if (CLOSE_MARKUP(a->options)) {
1852                 json_markup_power_management(tab, CLOSE_JSON_MARKUP);
1853         }
1854 }
1855
1856 /*
1857  ***************************************************************************
1858  * Display fan statistics in JSON.
1859  *
1860  * IN:
1861  * @a           Activity structure with statistics.
1862  * @curr        Index in array for current sample statistics.
1863  * @tab         Indentation in output.
1864  * @itv         Interval of time in 1/100th of a second.
1865  ***************************************************************************
1866  */
1867 __print_funct_t json_print_pwr_fan_stats(struct activity *a, int curr, int tab,
1868                                          unsigned long long itv)
1869 {
1870         int i;
1871         struct stats_pwr_fan *spc;
1872         int sep = FALSE;
1873
1874         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1875                 goto close_json_markup;
1876
1877         json_markup_power_management(tab, OPEN_JSON_MARKUP);
1878         tab++;
1879
1880         xprintf(tab++, "\"fan-speed\": [");
1881
1882         for (i = 0; i < a->nr[curr]; i++) {
1883                 spc = (struct stats_pwr_fan *) ((char *) a->buf[curr] + i * a->msize);
1884
1885                 if (sep) {
1886                         printf(",\n");
1887                 }
1888                 sep = TRUE;
1889
1890                 xprintf0(tab, "{\"number\": %d, "
1891                          "\"rpm\": %llu, "
1892                          "\"drpm\": %llu, "
1893                          "\"device\": \"%s\"}",
1894                          i + 1,
1895                          (unsigned long long) spc->rpm,
1896                          (unsigned long long) (spc->rpm - spc->rpm_min),
1897                          spc->device);
1898         }
1899
1900         printf("\n");
1901         xprintf0(--tab, "]");
1902         tab--;
1903
1904 close_json_markup:
1905         if (CLOSE_MARKUP(a->options)) {
1906                 json_markup_power_management(tab, CLOSE_JSON_MARKUP);
1907         }
1908 }
1909
1910 /*
1911  ***************************************************************************
1912  * Display temperature statistics in JSON.
1913  *
1914  * IN:
1915  * @a           Activity structure with statistics.
1916  * @curr        Index in array for current sample statistics.
1917  * @tab         Indentation in output.
1918  * @itv         Interval of time in 1/100th of a second.
1919  ***************************************************************************
1920  */
1921 __print_funct_t json_print_pwr_temp_stats(struct activity *a, int curr, int tab,
1922                                           unsigned long long itv)
1923 {
1924         int i;
1925         struct stats_pwr_temp *spc;
1926         int sep = FALSE;
1927
1928         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1929                 goto close_json_markup;
1930
1931         json_markup_power_management(tab, OPEN_JSON_MARKUP);
1932         tab++;
1933
1934         xprintf(tab++, "\"temperature\": [");
1935
1936         for (i = 0; i < a->nr[curr]; i++) {
1937                 spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize);
1938
1939                 if (sep) {
1940                         printf(",\n");
1941                 }
1942                 sep = TRUE;
1943
1944                 xprintf0(tab, "{\"number\": %d, "
1945                          "\"degC\": %.2f, "
1946                          "\"percent-temp\": %.2f, "
1947                          "\"device\": \"%s\"}",
1948                          i + 1,
1949                          spc->temp,
1950                          (spc->temp_max - spc->temp_min) ?
1951                          (spc->temp - spc->temp_min) / (spc->temp_max - spc->temp_min) * 100 :
1952                          0.0,
1953                          spc->device);
1954         }
1955
1956         printf("\n");
1957         xprintf0(--tab, "]");
1958         tab--;
1959
1960 close_json_markup:
1961         if (CLOSE_MARKUP(a->options)) {
1962                 json_markup_power_management(tab, CLOSE_JSON_MARKUP);
1963         }
1964 }
1965
1966 /*
1967  ***************************************************************************
1968  * Display voltage inputs statistics in JSON.
1969  *
1970  * IN:
1971  * @a           Activity structure with statistics.
1972  * @curr        Index in array for current sample statistics.
1973  * @tab         Indentation in output.
1974  * @itv         Interval of time in 1/100th of a second.
1975  ***************************************************************************
1976  */
1977 __print_funct_t json_print_pwr_in_stats(struct activity *a, int curr, int tab,
1978                                         unsigned long long itv)
1979 {
1980         int i;
1981         struct stats_pwr_in *spc;
1982         int sep = FALSE;
1983
1984         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
1985                 goto close_json_markup;
1986
1987         json_markup_power_management(tab, OPEN_JSON_MARKUP);
1988         tab++;
1989
1990         xprintf(tab++, "\"voltage-input\": [");
1991
1992         for (i = 0; i < a->nr[curr]; i++) {
1993                 spc = (struct stats_pwr_in *) ((char *) a->buf[curr] + i * a->msize);
1994
1995                 if (sep) {
1996                         printf(",\n");
1997                 }
1998                 sep = TRUE;
1999
2000                 xprintf0(tab, "{\"number\": %d, "
2001                          "\"inV\": %.2f, "
2002                          "\"percent-in\": %.2f, "
2003                          "\"device\": \"%s\"}",
2004                          i,
2005                          spc->in,
2006                          (spc->in_max - spc->in_min) ?
2007                          (spc->in - spc->in_min) / (spc->in_max - spc->in_min) * 100 :
2008                          0.0,
2009                          spc->device);
2010         }
2011
2012         printf("\n");
2013         xprintf0(--tab, "]");
2014         tab--;
2015
2016 close_json_markup:
2017         if (CLOSE_MARKUP(a->options)) {
2018                 json_markup_power_management(tab, CLOSE_JSON_MARKUP);
2019         }
2020 }
2021
2022 /*
2023  ***************************************************************************
2024  * Display huge pages statistics in JSON.
2025  *
2026  * IN:
2027  * @a           Activity structure with statistics.
2028  * @curr        Index in array for current sample statistics.
2029  * @tab         Indentation in output.
2030  * @itv         Interval of time in 1/100th of a second.
2031  ***************************************************************************
2032  */
2033 __print_funct_t json_print_huge_stats(struct activity *a, int curr, int tab,
2034                                       unsigned long long itv)
2035 {
2036         struct stats_huge
2037                 *smc = (struct stats_huge *) a->buf[curr];
2038
2039         xprintf0(tab, "\"hugepages\": {"
2040                  "\"hugfree\": %llu, "
2041                  "\"hugused\": %llu, "
2042                  "\"hugused-percent\": %.2f, "
2043                  "\"hugrsvd\": %llu, "
2044                  "\"hugsurp\": %llu}",
2045                  smc->frhkb,
2046                  smc->tlhkb - smc->frhkb,
2047                  smc->tlhkb ?
2048                  SP_VALUE(smc->frhkb, smc->tlhkb, smc->tlhkb) : 0.0,
2049                  smc->rsvdhkb,
2050                  smc->surphkb);
2051 }
2052
2053 /*
2054  ***************************************************************************
2055  * Display weighted CPU frequency statistics in JSON.
2056  *
2057  * IN:
2058  * @a           Activity structure with statistics.
2059  * @curr        Index in array for current sample statistics.
2060  * @tab         Indentation in output.
2061  * @itv         Interval of time in 1/100th of a second.
2062  ***************************************************************************
2063  */
2064 __print_funct_t json_print_pwr_wghfreq_stats(struct activity *a, int curr, int tab,
2065                                              unsigned long long itv)
2066 {
2067         int i, k;
2068         struct stats_pwr_wghfreq *spc, *spp, *spc_k, *spp_k;
2069         unsigned long long tis, tisfreq;
2070         int sep = FALSE;
2071         char cpuno[16];
2072
2073         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
2074                 goto close_json_markup;
2075
2076         json_markup_power_management(tab, OPEN_JSON_MARKUP);
2077         tab++;
2078
2079         xprintf(tab++, "\"cpu-weighted-frequency\": [");
2080
2081         for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
2082
2083                 spc = (struct stats_pwr_wghfreq *) ((char *) a->buf[curr]  + i * a->msize * a->nr2);
2084                 spp = (struct stats_pwr_wghfreq *) ((char *) a->buf[!curr] + i * a->msize * a->nr2);
2085
2086                 /* Should current CPU (including CPU "all") be displayed? */
2087                 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
2088                         /* No */
2089                         continue;
2090
2091                 tisfreq = 0;
2092                 tis = 0;
2093
2094                 for (k = 0; k < a->nr2; k++) {
2095
2096                         spc_k = (struct stats_pwr_wghfreq *) ((char *) spc + k * a->msize);
2097                         if (!spc_k->freq)
2098                                 break;
2099                         spp_k = (struct stats_pwr_wghfreq *) ((char *) spp + k * a->msize);
2100
2101                         tisfreq += (spc_k->freq / 1000) *
2102                                    (spc_k->time_in_state - spp_k->time_in_state);
2103                         tis     += (spc_k->time_in_state - spp_k->time_in_state);
2104                 }
2105
2106                 if (!i) {
2107                         /* This is CPU "all" */
2108                         strcpy(cpuno, "all");
2109                 }
2110                 else {
2111                         sprintf(cpuno, "%d", i - 1);
2112                 }
2113
2114                 if (sep) {
2115                         printf(",\n");
2116                 }
2117                 sep = TRUE;
2118
2119                 xprintf0(tab, "{\"number\": \"%s\", "
2120                          "\"weighted-frequency\": %.2f}",
2121                          cpuno,
2122                          tis ? ((double) tisfreq) / tis : 0.0);
2123         }
2124
2125         printf("\n");
2126         xprintf0(--tab, "]");
2127         tab--;
2128
2129 close_json_markup:
2130         if (CLOSE_MARKUP(a->options)) {
2131                 json_markup_power_management(tab, CLOSE_JSON_MARKUP);
2132         }
2133 }
2134
2135 /*
2136  ***************************************************************************
2137  * Display USB devices statistics in JSON.
2138  *
2139  * IN:
2140  * @a           Activity structure with statistics.
2141  * @curr        Index in array for current sample statistics.
2142  * @tab         Indentation in output.
2143  * @itv         Interval of time in 1/100th of a second.
2144  ***************************************************************************
2145  */
2146 __print_funct_t json_print_pwr_usb_stats(struct activity *a, int curr, int tab,
2147                                          unsigned long long itv)
2148 {
2149         int i;
2150         struct stats_pwr_usb *suc;
2151         int sep = FALSE;
2152
2153         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
2154                 goto close_json_markup;
2155
2156         json_markup_power_management(tab, OPEN_JSON_MARKUP);
2157         tab++;
2158
2159         xprintf(tab++, "\"usb-devices\": [");
2160
2161         for (i = 0; i < a->nr[curr]; i++) {
2162                 suc = (struct stats_pwr_usb *) ((char *) a->buf[curr] + i * a->msize);
2163
2164                 if (sep) {
2165                         printf(",\n");
2166                 }
2167                 sep = TRUE;
2168
2169                 xprintf0(tab, "{\"bus_number\": %d, "
2170                          "\"idvendor\": \"%x\", "
2171                          "\"idprod\": \"%x\", "
2172                          "\"maxpower\": %u, "
2173                          "\"manufact\": \"%s\", "
2174                          "\"product\": \"%s\"}",
2175                          suc->bus_nr,
2176                          suc->vendor_id,
2177                          suc->product_id,
2178                          suc->bmaxpower << 1,
2179                          suc->manufacturer,
2180                          suc->product);
2181         }
2182
2183         printf("\n");
2184         xprintf0(--tab, "]");
2185         tab--;
2186
2187 close_json_markup:
2188         if (CLOSE_MARKUP(a->options)) {
2189                 json_markup_power_management(tab, CLOSE_JSON_MARKUP);
2190         }
2191 }
2192
2193 /*
2194  ***************************************************************************
2195  * Display filesystems statistics in JSON.
2196  *
2197  * IN:
2198  * @a           Activity structure with statistics.
2199  * @curr        Index in array for current sample statistics.
2200  * @tab         Indentation in output.
2201  * @itv         Interval of time in 1/100th of a second.
2202  ***************************************************************************
2203  */
2204 __print_funct_t json_print_filesystem_stats(struct activity *a, int curr, int tab,
2205                                             unsigned long long itv)
2206 {
2207         int i;
2208         struct stats_filesystem *sfc;
2209         int sep = FALSE;
2210         char *dev_name;
2211
2212         xprintf(tab++, "\"filesystems\": [");
2213
2214         for (i = 0; i < a->nr[curr]; i++) {
2215                 sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
2216
2217                 /* Get name to display (persistent or standard fs name, or mount point) */
2218                 dev_name = get_fs_name_to_display(a, flags, sfc);
2219
2220                 if (a->item_list != NULL) {
2221                         /* A list of devices has been entered on the command line */
2222                         if (!search_list_item(a->item_list, dev_name))
2223                                 /* Device not found */
2224                                 continue;
2225                 }
2226
2227                 if (sep) {
2228                         printf(",\n");
2229                 }
2230                 sep = TRUE;
2231
2232                 xprintf0(tab, "{\"%s\": \"%s\", "
2233                          "\"MBfsfree\": %.0f, "
2234                          "\"MBfsused\": %.0f, "
2235                          "\"%%fsused\": %.2f, "
2236                          "\"%%ufsused\": %.2f, "
2237                          "\"Ifree\": %llu, "
2238                          "\"Iused\": %llu, "
2239                          "\"%%Iused\": %.2f}",
2240                          DISPLAY_MOUNT(a->opt_flags) ? "mountpoint" : "filesystem",
2241                          dev_name,
2242                          (double) sfc->f_bfree / 1024 / 1024,
2243                          (double) (sfc->f_blocks - sfc->f_bfree) / 1024 / 1024,
2244                          sfc->f_blocks ? SP_VALUE(sfc->f_bfree, sfc->f_blocks, sfc->f_blocks)
2245                                      : 0.0,
2246                          sfc->f_blocks ? SP_VALUE(sfc->f_bavail, sfc->f_blocks, sfc->f_blocks)
2247                                      : 0.0,
2248                          sfc->f_ffree,
2249                          sfc->f_files - sfc->f_ffree,
2250                          sfc->f_files ? SP_VALUE(sfc->f_ffree, sfc->f_files, sfc->f_files)
2251                                     : 0.0);
2252         }
2253
2254         printf("\n");
2255         xprintf0(--tab, "]");
2256 }
2257
2258 /*
2259  ***************************************************************************
2260  * Display Fibre Channel HBA statistics in JSON.
2261  *
2262  * IN:
2263  * @a           Activity structure with statistics.
2264  * @curr        Index in array for current sample statistics.
2265  * @tab         Indentation in output.
2266  * @itv         Interval of time in 1/100th of a second.
2267  ***************************************************************************
2268  */
2269 __print_funct_t json_print_fchost_stats(struct activity *a, int curr, int tab,
2270                                         unsigned long long itv)
2271 {
2272         int i, j, j0, found;
2273         struct stats_fchost *sfcc, *sfcp, sfczero;
2274         int sep = FALSE;
2275
2276         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
2277                 goto close_json_markup;
2278
2279         memset(&sfczero, 0, sizeof(struct stats_fchost));
2280
2281         json_markup_network(tab, OPEN_JSON_MARKUP);
2282         tab++;
2283
2284         xprintf(tab++, "\"fchosts\": [");
2285
2286         for (i = 0; i < a->nr[curr]; i++) {
2287
2288                 found = FALSE;
2289                 sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
2290
2291                 if (a->nr[!curr] > 0) {
2292                         /* Look for corresponding structure in previous iteration */
2293                         j = i;
2294
2295                         if (j >= a->nr[!curr]) {
2296                                 j = a->nr[!curr] - 1;
2297                         }
2298
2299                         j0 = j;
2300
2301                         do {
2302                                 sfcp = (struct stats_fchost *) ((char *) a->buf[!curr] + j * a->msize);
2303                                 if (!strcmp(sfcc->fchost_name, sfcp->fchost_name)) {
2304                                         found = TRUE;
2305                                         break;
2306                                 }
2307                                 if (++j >= a->nr[!curr]) {
2308                                         j = 0;
2309                                 }
2310                         }
2311                         while (j != j0);
2312                 }
2313
2314                 if (!found) {
2315                         /* This is a newly registered host */
2316                         sfcp = &sfczero;
2317                 }
2318
2319                 if (sep)
2320                         printf(",\n");
2321
2322                 sep = TRUE;
2323
2324                 xprintf0(tab, "{\"fchost\": \"%s\", "
2325                          "\"fch_rxf\": %.2f, "
2326                          "\"fch_txf\": %.2f, "
2327                          "\"fch_rxw\": %.2f, "
2328                          "\"fch_txw\": %.2f}",
2329                          sfcc->fchost_name,
2330                          S_VALUE(sfcp->f_rxframes, sfcc->f_rxframes, itv),
2331                          S_VALUE(sfcp->f_txframes, sfcc->f_txframes, itv),
2332                          S_VALUE(sfcp->f_rxwords,  sfcc->f_rxwords,  itv),
2333                          S_VALUE(sfcp->f_txwords,  sfcc->f_txwords,  itv));
2334         }
2335
2336         printf("\n");
2337         xprintf0(--tab, "]");
2338
2339         tab --;
2340
2341 close_json_markup:
2342         if (CLOSE_MARKUP(a->options)) {
2343                 json_markup_network(tab, CLOSE_JSON_MARKUP);
2344         }
2345 }
2346
2347 /*
2348  ***************************************************************************
2349  * Display softnet statistics in JSON.
2350  *
2351  * IN:
2352  * @a           Activity structure with statistics.
2353  * @curr        Index in array for current sample statistics.
2354  * @tab         Indentation in output.
2355  * @itv         Interval of time in 1/100th of a second.
2356  ***************************************************************************
2357  */
2358 __print_funct_t json_print_softnet_stats(struct activity *a, int curr, int tab,
2359                                          unsigned long long itv)
2360 {
2361         int i;
2362         struct stats_softnet *ssnc, *ssnp;
2363         int sep = FALSE;
2364         char cpuno[16];
2365         unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
2366
2367         if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
2368                 goto close_json_markup;
2369
2370         json_markup_network(tab, OPEN_JSON_MARKUP);
2371         tab++;
2372
2373         xprintf(tab++, "\"softnet\": [");
2374
2375         /* @nr[curr] cannot normally be greater than @nr_ini */
2376         if (a->nr[curr] > a->nr_ini) {
2377                 a->nr_ini = a->nr[curr];
2378         }
2379
2380         /* Compute statistics for CPU "all" */
2381         get_global_soft_statistics(a, !curr, curr, flags, offline_cpu_bitmap);
2382
2383         for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
2384
2385                 /*
2386                  * Should current CPU (including CPU "all") be displayed?
2387                  * Note: a->nr is in [1, NR_CPUS + 1].
2388                  * Bitmap size is provided for (NR_CPUS + 1) CPUs.
2389                  * Anyway, NR_CPUS may vary between the version of sysstat
2390                  * used by sadc to create a file, and the version of sysstat
2391                  * used by sar to read it...
2392                  */
2393                 if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) ||
2394                     offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07)))
2395                         /* No */
2396                         continue;
2397
2398                 /*
2399                  * The size of a->buf[...] CPU structure may be different from the default
2400                  * sizeof(struct stats_pwr_cpufreq) value if data have been read from a file!
2401                  * That's why we don't use a syntax like:
2402                  * ssnc = (struct stats_softnet *) a->buf[...] + i;
2403                  */
2404                 ssnc = (struct stats_softnet *) ((char *) a->buf[curr]  + i * a->msize);
2405                 ssnp = (struct stats_softnet *) ((char *) a->buf[!curr] + i * a->msize);
2406
2407                 if (sep) {
2408                         printf(",\n");
2409                 }
2410                 sep = TRUE;
2411
2412                 if (!i) {
2413                         /* This is CPU "all" */
2414                         strcpy(cpuno, "all");
2415                 }
2416                 else {
2417                         sprintf(cpuno, "%d", i - 1);
2418                 }
2419
2420                 xprintf0(tab, "{\"cpu\": \"%s\", "
2421                          "\"total\": %.2f, "
2422                          "\"dropd\": %.2f, "
2423                          "\"squeezd\": %.2f, "
2424                          "\"rx_rps\": %.2f, "
2425                          "\"flw_lim\": %.2f}",
2426                          cpuno,
2427                          S_VALUE(ssnp->processed,    ssnc->processed,    itv),
2428                          S_VALUE(ssnp->dropped,      ssnc->dropped,      itv),
2429                          S_VALUE(ssnp->time_squeeze, ssnc->time_squeeze, itv),
2430                          S_VALUE(ssnp->received_rps, ssnc->received_rps, itv),
2431                          S_VALUE(ssnp->flow_limit,   ssnc->flow_limit,   itv));
2432         }
2433
2434         printf("\n");
2435         xprintf0(--tab, "]");
2436
2437         tab --;
2438
2439 close_json_markup:
2440         if (CLOSE_MARKUP(a->options)) {
2441                 json_markup_network(tab, CLOSE_JSON_MARKUP);
2442         }
2443 }
2444
2445 /*
2446  ***************************************************************************
2447  * Display pressure-stall CPU statistics in JSON.
2448  *
2449  * IN:
2450  * @a           Activity structure with statistics.
2451  * @curr        Index in array for current sample statistics.
2452  * @tab         Indentation in output.
2453  * @itv         Interval of time in 1/100th of a second.
2454  ***************************************************************************
2455  */
2456 __print_funct_t json_print_psicpu_stats(struct activity *a, int curr, int tab,
2457                                         unsigned long long itv)
2458 {
2459         struct stats_psi_cpu
2460                 *psic = (struct stats_psi_cpu *) a->buf[curr],
2461                 *psip = (struct stats_psi_cpu *) a->buf[!curr];
2462
2463         if (!IS_SELECTED(a->options))
2464                 goto close_json_markup;
2465
2466         json_markup_psi(tab, OPEN_JSON_MARKUP);
2467         tab++;
2468
2469         xprintf0(tab, "\"psi-cpu\": {"
2470                  "\"some_avg10\": %.2f, "
2471                  "\"some_avg60\": %.2f, "
2472                  "\"some_avg300\": %.2f, "
2473                  "\"some_avg\": %.2f}",
2474                  (double) psic->some_acpu_10  / 100,
2475                  (double) psic->some_acpu_60  / 100,
2476                  (double) psic->some_acpu_300 / 100,
2477                  ((double) psic->some_cpu_total - psip->some_cpu_total) / (100 * itv));
2478         tab--;
2479
2480 close_json_markup:
2481         if (CLOSE_MARKUP(a->options)) {
2482                 json_markup_psi(tab, CLOSE_JSON_MARKUP);
2483         }
2484 }
2485
2486 /*
2487  ***************************************************************************
2488  * Display pressure-stall I/O statistics in JSON.
2489  *
2490  * IN:
2491  * @a           Activity structure with statistics.
2492  * @curr        Index in array for current sample statistics.
2493  * @tab         Indentation in output.
2494  * @itv         Interval of time in 1/100th of a second.
2495  ***************************************************************************
2496  */
2497 __print_funct_t json_print_psiio_stats(struct activity *a, int curr, int tab,
2498                                        unsigned long long itv)
2499 {
2500         struct stats_psi_io
2501                 *psic = (struct stats_psi_io *) a->buf[curr],
2502                 *psip = (struct stats_psi_io *) a->buf[!curr];
2503
2504         if (!IS_SELECTED(a->options))
2505                 goto close_json_markup;
2506
2507         json_markup_psi(tab, OPEN_JSON_MARKUP);
2508         tab++;
2509
2510         xprintf0(tab, "\"psi-io\": {"
2511                  "\"some_avg10\": %.2f, "
2512                  "\"some_avg60\": %.2f, "
2513                  "\"some_avg300\": %.2f, "
2514                  "\"some_avg\": %.2f, "
2515                  "\"full_avg10\": %.2f, "
2516                  "\"full_avg60\": %.2f, "
2517                  "\"full_avg300\": %.2f, "
2518                  "\"full_avg\": %.2f}",
2519                  (double) psic->some_aio_10  / 100,
2520                  (double) psic->some_aio_60  / 100,
2521                  (double) psic->some_aio_300 / 100,
2522                  ((double) psic->some_io_total - psip->some_io_total) / (100 * itv),
2523                  (double) psic->full_aio_10  / 100,
2524                  (double) psic->full_aio_60  / 100,
2525                  (double) psic->full_aio_300 / 100,
2526                  ((double) psic->full_io_total - psip->full_io_total) / (100 * itv));
2527         tab--;
2528
2529 close_json_markup:
2530         if (CLOSE_MARKUP(a->options)) {
2531                 json_markup_psi(tab, CLOSE_JSON_MARKUP);
2532         }
2533 }
2534
2535 /*
2536  ***************************************************************************
2537  * Display pressure-stall memory statistics in JSON.
2538  *
2539  * IN:
2540  * @a           Activity structure with statistics.
2541  * @curr        Index in array for current sample statistics.
2542  * @tab         Indentation in output.
2543  * @itv         Interval of time in 1/100th of a second.
2544  ***************************************************************************
2545  */
2546 __print_funct_t json_print_psimem_stats(struct activity *a, int curr, int tab,
2547                                         unsigned long long itv)
2548 {
2549         struct stats_psi_mem
2550                 *psic = (struct stats_psi_mem *) a->buf[curr],
2551                 *psip = (struct stats_psi_mem *) a->buf[!curr];
2552
2553         if (!IS_SELECTED(a->options))
2554                 goto close_json_markup;
2555
2556         json_markup_psi(tab, OPEN_JSON_MARKUP);
2557         tab++;
2558
2559         xprintf0(tab, "\"psi-mem\": {"
2560                  "\"some_avg10\": %.2f, "
2561                  "\"some_avg60\": %.2f, "
2562                  "\"some_avg300\": %.2f, "
2563                  "\"some_avg\": %.2f, "
2564                  "\"full_avg10\": %.2f, "
2565                  "\"full_avg60\": %.2f, "
2566                  "\"full_avg300\": %.2f, "
2567                  "\"full_avg\": %.2f}",
2568                  (double) psic->some_amem_10  / 100,
2569                  (double) psic->some_amem_60  / 100,
2570                  (double) psic->some_amem_300 / 100,
2571                  ((double) psic->some_mem_total - psip->some_mem_total) / (100 * itv),
2572                  (double) psic->full_amem_10  / 100,
2573                  (double) psic->full_amem_60  / 100,
2574                  (double) psic->full_amem_300 / 100,
2575                  ((double) psic->full_mem_total - psip->full_mem_total) / (100 * itv));
2576         tab--;
2577
2578 close_json_markup:
2579         if (CLOSE_MARKUP(a->options)) {
2580                 json_markup_psi(tab, CLOSE_JSON_MARKUP);
2581         }
2582 }