% isochron-report(1) | ISOCHRON

NAME
====

isochron-report - Gather statistics from logged isochron data

SYNOPSIS
========

**isochron** report \[_OPTIONS_\]

DESCRIPTION
===========

This command opens an isochron.dat file generated by `isochron send` and
filters the requested data from it.

OPTIONS
=======

`-h`, `--help`

:   prints the short help message and exits

`-F`, `--input-file` <`PATH`>

:   specify the path to the input file. Optional, defaults to
    "isochron.dat".

`-m`, `--summary`

:   optionally calculate and print a summary of the built-in metrics.

`-s`, `--start` <`NUMBER`>

:   specify the sequence number of the first packet to be taken into
    consideration for printing and for statistics calculation. Optional;
    defaults to sequence number 1 (the first packet).

`-S`, `--stop` <`NUMBER`>

:   specify the sequence number of the last packet to be taken into
    consideration for printing and for statistics calculation. Optional;
    defaults to a sequence number equal to the number of packets of the
    test (the last packet).

`-f`, `--printf-format` <`STRING`>

:   specify the format in which a packet will be printed. Optional; if
    not specified, per-packet information is not printed.

`-a`, `--printf-args` <`STRING`>

:   specify the built-in variables which will be printed per packet.

PRINTF FORMAT
=============

The `--printf-format` argument specifies a free-form string that can
also contain up to 256 printf-like codes prefixed by the `%` (percent)
character. The printf codes will be replaced by isochron for each packet
with internal variables taken from the log. The newline character is not
added automatically between packets.

The printf codes understood by isochron are:

`%d`

:   print a built-in variable as a signed integer in decimal format.

`%u`

:   print a built-in variable as an unsigned integer in decimal format.

`%x`

:   print a built-in variable as an unsigned integer in hexadecimal
    format.

`%T`

:   print a built-in variable in human-readable time format (`sec.nsec`).

PRINTF VARIABLES
================

The `--printf-args` argument is an array of single-character isochron
variable codes. The program associates, in left-to-right order, each
variable code with the printf code from the format specifier in order to
figure out how to print it.

The variable codes understood by isochron are:

`A`

:   advance time as defined by `isochron send --advance-time`. Can be
    printed using `%d`, `%u`, `%x` or `%T`.

`B`

:   base time as defined by `isochron send --base-time`, then adjusted
    by the sender application using the shift time and advanced into the
    immediate future at the time of the test. The base time minus the
    advance time denotes the programmed time of the wakeup timer for the
    sender's first packet. Can be printed using `%d`, `%u`, `%x` or `%T`.

`C`

:   cycle time as defined by `isochron send --cycle-time`. Can be
    printed using `%d`, `%u`, `%x` or `%T`.

`H`

:   shift time as defined by `isochron send --shift-time`. Can be
    printed using `%d`, `%u`, `%x` or `%T`.

`W`

:   window size as defined by `isochron send --window-size`. Can be
    printed using `%d`, `%u`, `%x` or `%T`.

`S`

:   scheduled TX time of the packet (the time at which the packet must
    hit the wire). Can be printed using `%d`, `%u`, `%x` or `%T`.

`w`

:   the actual value of the `CLOCK_TAI` system clock when the sender
    starts executing code again immediately after its wakeup timer for
    the packet has expired. Can be printed using `%d`, `%u`, `%x` or
    `%T`.

`T`

:   TX hardware timestamp of the packet, taken by the NIC of the sender.
    Can be printed using `%d`, `%u`, `%x` or `%T`.

`t`

:   TX software timestamp of the packet, taken by the NIC driver of the
    sender right before hardware transmission. Can be printed using
    `%d`, `%u`, `%x` or `%T`.

`s`

:   TX software timestamp of the packet, taken by the network stack
    prior to entering the packet scheduler (qdisc). Can be printed using
    `%d`, `%u`, `%x` or `%T`.

`q`

:   sequence number of the packet, starting from 1. Can be printed using
    `%u` or `%x`.

`a`

:   the arrival time of the packet, i.e. the actual value of the
    `CLOCK_TAI` system clock when the receiver starts executing code
    again immediately after fully receiving the packet. Can be printed
    using `%d`, `%u`, `%x` or `%T`.

`R`

:   RX hardware timestamp of the packet, taken by the NIC of the
    receiver. Can be printed using `%d`, `%u`, `%x` or `%T`.

`r`

:   RX software timestamp of the packet, taken by the NIC driver right
    after reception from hardware. Can be printed using `%d`, `%u`, `%x`
    or `%T`.

BUILT-IN METRICS
================

When running with the `--summary` option, isochron defines some latency
related metrics and calculates the following statistics on them: maximum
value, minimum value, packet sequence number associated with the min and
max, mean value, standard deviation.

The built-in metrics are:

Path delay

: R - T (HW TX timestamp to HW RX timestamp)

Sender latency

: t - w (actual sender wakeup time to SW TX timestamp)

MAC latency

: T - S (scheduled TX time to HW TX timestamp)

Application latency budget ("time to spare per cycle")

: S - T (time until HW TX timestamp would exceed scheduled TX time)

Wakeup latency

: w - (S - A) (programmed wakeup time, i.e. scheduled TX time minus
  advance time, to actual wakeup time)

Driver latency (actually driver + qdisc latency)

: t - s (pre-qdisc timestamp to driver-level software TX timestamp)

Arrival latency

: a - R (HW RX timestamp to application)

Notice how the "MAC latency" and the "Application latency budget" is the
same metric, but calculated in reverse. The data is interpreted by the
application depending on whether the hardware was expected to send the
packet right away, or queue it until the scheduled TX time like in the
case of the tc-taprio and tc-etf qdiscs.

EXAMPLES
========

To obtain the summary of the built-in metrics:

```
isochron report \
	--input-file isochron.dat \
	--summary
```

To see the detailed network timestamps for a single packet:

```
isochron report \
	--input-file isochron.dat \
	--printf-format "seqid %u scheduled for %T, TX qdisc %T sw %T hw %T, RX hw %T sw %T\n" \
	--printf-args "qSstTRr" \
	--start 173972 --stop 173972
```

To export data in comma-separated value format, for calculating
user-defined metrics externally:

```
isochron report \
	--input-file isochron.dat \
	--printf-format "%d,%d\n" \
	--printf-args "TR" \
	> isochron.csv
```

User-defined arithmetic on the built-in isochron variables can also be
delegated to a scripting language interpreter such as Python, by
configuring the isochron printf format specifier to generate output in
Python syntax:

```
isochron report \
	--printf-format "pdelay=%d - %d\nprint(\"path_delay[%u] =\", pdelay)\n" \
	--printf-args "RTq" \
	| python3 -
```

For more complex arithmetic, the per-packet internal variables can be
stored inside arrays:

```
printf "wakeup_latency = {}\n" > isochron_data.py
isochron report \
	--printf-format "wakeup_latency[%u] = %d - (%d - %d)\n" \
	--printf-args "qwSA" \
	>> isochron_data.py
cat << 'EOF' > isochron_postprocess.py
#!/usr/bin/env python3

from isochron_data import wakeup_latency
import numpy as np

w = np.array(list(wakeup_latency.values()))
print("Wakeup latency: min {}, max {}, mean {}, median {}, stdev {}".format(np.min(w), np.max(w), np.mean(w), np.median(w), np.std(w)))
EOF
python3 ./isochron_postprocess.py
```

AUTHOR
======

isochron was written by Vladimir Oltean <vladimir.oltean@nxp.com>

SEE ALSO
========

isochron(8)
isochron-send(8)
isochron-rcv(8)

COMMENTS
========

This man page was written using [pandoc](http://pandoc.org/) by the same author.
