# topplot - procps-ng top

<a href="https://codethink.co.uk" target="_blank"><img src="resources/codethink_logo.svg" alt="Codethink" height=50 align="right"></a>
<img src="topplot/logo.png" alt="" height="50" style="align: right">

[[_TOC_]]


## Preamble

**procps-ng** provides the common-or-garden version of **top** you'll find in most Linux distros. This is the edition of **top** that
**topplot** was written to work with. 

Other variants of **top** from other projects (e.g. [Toybox](http://www.landley.net/toybox/) or [Busybox](https://busybox.net)) may format their output differently, so may or may not be compatible with **topplot**. 

(Toybox **top** is incompatible with **topplot**, and I'd guess Busybox **top** is as well. Merge Requests welcome, but do co-ordinate at Issue 
https://gitlab.com/eBardie/topplot/-/issues/3 and/or Issue https://gitlab.com/eBardie/topplot/-/issues/4.)

The [procps-ng](https://gitlab.com/procps-ng/procps) project describes itself as:

_"Command line and full screen utilities for browsing procfs, a "pseudo" file system dynamically generated by the kernel to provide information about the status of entries in its process table."_

which tells you where **top** gets its information from.


## Modes

**top** runs in two modes:

* **Interactive mode** : Dynamic, updating, "realtime" display of  screen's worth of system information. Most configuration set here can be made persistent.

* **Batch mode** : Used to "print" system information. Not limited by screen dimensions.

Broadly we'll use Interactive mode to configure **top** to display the information we want, in the format that **topplot** expects. Then we'll use Batch mode to output the data cycles we require, at the desired sampling frequency. 

I said "broadly" because whilst it is possible to control Task/Thread display in Interactive mode, this state isn't saved to the config file.
Fortunately for our pusposes there's a commandline option that we can use instead.

Before we get to *how* to configure, we need to decide upon *what* to configure.


## What to configure

* To see what Processes of Interest (POI) are doing on each individual CPU core, **top** needs to display the **P** column (a.k.a **Last Used CPU**). See [below](#display-the-last-used-cpu-field).

* To see CPU data for each individual core, **top**'s header needs to output the CPU data for each core, not the summary across all cores. See [below](#display-cpu-information-by-core-or-in-summary).

* **top** can display process information for each thread within a task, or in summary form for the whole task. See [below](#display-process-information-by-task-or-thread).

* Make **topplot**'s life easier by ensuring that the **Command** field is displayed as the rightmost column. See [below](#move-fields).

:warning: Note that the more information **top** is processing, the more resources **top** and **topplot** will consume, the higher the load contributed to the target system, and the longer time taken to graph the results. _If you're not using it, turn it off._


## Configuring **top**'s output in Interactive mode

Interactive mode is the default, so enter it by running **top** on the commandline (**without** passing the `-b` CLA (Command Line
Argument)).


### Help!?

When in Interactive mode press `h` to display terse help information. Leave the help page by pressing `q` or `<Esc>`.

(For exhaustive information on **top**, see its extensive **man** page; type `man top` on the commandline.)


### The Field configuration page

**top** refers to its columns as 'fields'.

Access the Field configuration page by pressing `f`.

The most likely change to make here is to turn on the **Last Used CPU** field. See [below](#display-the-last-used-cpu-field).

Make sure that **Command** is the rightmost field. See [Move fields](#move-fields) below. 


#### Move fields

1. Navigate the cursor to the field you wish to move using `↑`/`↓`.

2. Select the field with `→`.

3. Relocate the field with `↑`/`↓`.

4. Confirm with `←` or `<Enter>`.


#### Display the Last Used CPU field

To display [POI](#display-the-last-used-cpu-field "Processes of Interest") data by CPU core:

Look for the **P = Last Used CPU (SMP)** field. If it starts with an asterisk (**\***), then it is already enabled.

If there's no asterisk, navigate to the field using `↑`/`↓`, and press `d` or `<Space>` to toggle it on. Toggle it off by
following the same actions.


### Display CPU information by core or in summary

To toggle between displaying the information for each individual core and displaying the summary across all cores, press `1` (the number one) in the main page.

:warning: This will consume more resources on the target system to generate, and will increase processing time when producing the graphs. _If you don't need it, turn it off._


### Display process information by Task or Thread (not persistent!)

:warning: This setting is **not** saved to the config file, so is only useful for live viewing. See [below](#display-process-information-by-task-or-thread) for how to control this on the commandline when creating log files.

To toggle between displaying process information by Task or by Thread, press uppecase `H` in the main page.


### Display process information in long or short format

Long format usually (!) displays the process' commandline, so the process name can (usually) be extracted. (Some processes overwrite this
data. What can you do? Use that instead.)

Short format data can be also be manipulated by the process, usually to give thread specific names. 

You may prefer one or the other according to circumstance.

To toggle between displaying long or short format process information, press `c` in the main page.


### Saving the configuration

Press uppercase `W` to save the configuration. On my laptop the file is written to **~/.config/procps/toprc** but YMMV.

If you're regularly reinstalling your target system you may wish to keep a remote copy of this file to avoid manual reconfiguration.


### Gotchas

#### Window gotchas

Interactive mode has four slots for preset configurations ("windows" in **top** speak). Different windows can have different header and field arrangements. Either a single window has the main page to itself, or all four are displayed at the same time.

Batch mode picks up on which ever arrangement was in use when the config file was last written. Make sure it was a single window that has the
settings you intend to use.

* To select a window from the main page press `g` then press `1`, `2`, `3`, or `4`.

* To toggle between single window and multiple window modes, press uppercase `A`.

To learn more about using **top** windows press `h` to get to the help page, then press `h` again.

#### Other gotchas

There are several keypresses on the main page which affect the information displayed in Batch mode. If these have been deliberately or
inadvertantly pressed, **topplot** may not be able to process the resulting logs:

* Scaling for the memory header lines can be changed by pressing uppecase `E`. **topplot** will handle whatever this is set to, from KiB to EiB, but if it is set too high for the actual memory available, all reports will be zeroes. **topplot** will warn if this is detected.

    Bad:
    ```
    TiB Mem :      0.0 total,      0.0 free,      0.0 used,      0.0 buff/cache
    TiB Swap:      0.0 total,      0.0 free,      0.0 used.      0.0 avail Mem
    ```

    Good:
    ```
    KiB Mem : 16069464 total,  1204208 free, 10501004 used,  4364252 buff/cache
    KiB Swap: 16171004 total, 15821308 free,   349696 used.  4235368 avail Mem
    ```

* The load average header line _must_ be active. To toggle it press `l`. The first line displayed should look similar to: 
    ```
    top - 16:37:57 up 8 days, 20 min,  8 users,  load average: 0.49, 0.29, 0.29
    ```

* The CPU header lines _must_ be active and displaying non-graphical information. To toggle press `t`.

    Bad:
    ```
    %Cpu(s):   0.9/0.6     1[||                                                                                         ]
    ```
    Good:
    ```
    %Cpu(s):  0.8 us,  0.7 sy,  0.0 ni, 97.8 id,  0.4 wa,  0.0 hi,  0.3 si,  0.0 st
    ```

* The memory header lines _must_ be active and displaying non-graphical information. To toggle press `m`.

    Bad:
    ```
    MiB Mem : 71.5/15692.8  [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||                          ]
    MiB Swap:  2.2/15792.0  [||                                                                                         ]
    ```
    Good:
    ```
    MiB Mem :  15692.8 total,   1388.1 free,  10031.4 used,   4273.3 buff/cache
    MiB Swap:  15792.0 total,  15449.2 free,    342.8 used.   4478.8 avail Mem
    ```

* Forest mode _must_ be inactive. To toggle press uppecase `V`.

    Bad:
    ```
       4038   0.6   96308  89808    432   89836   2836  468    0   0.0 11  `- tmux
       4307   0.0   12708   6076    700    6380   3128  302    0   0.0  4      `- -bash
    ```
    Good:
    ```
       4038   0.6   96308  89812    432   89836   2836  469    0   0.0 11 tmux
       4307   0.0   12708   6076    700    6380   3128  302    0   0.0  4 -bash
    ```


## Controlling **top**'s output in Batch mode

Run **top** in Batch mode by passing it the `-b` [CLA](#controlling-tops-output-in-batch-mode "CommandLine Argument").


### Sampling frequency

To set the sampling frequency (delay between cycles) pass the `-d <N>` CLA, where **_&lt;N&gt;_** is the number of seconds desired. 

**_&lt;N&gt;_** can include a decimal point to specify tenths of a second. 

Bear in mind that there are limits to how fast you can collect data on a loaded system, both in terms  of the extra load imposed by **top** and in terms of the time it takes **top** to perform a single cycle.


### Number of cycles

By default Batch mode will cycle _ad infinitum_. Limit this passing the `-n <N>` CLA, where **_&lt;N&gt;_** is the number of cycles required.


### A simple example

To write three minutes worth of **top** logs, at three second intervals, to a file called **top.log**:

```
top -b -d 3 -n 60 > top.log
```


### Display process information by Task or Thread

By default Batch mode will display process information summarising across all of a Task's Threads.

To display process information by Thread, pass the `-H` [CLA](#display-process-information-by-task-or-thread "CommandLine Argument"):

```
top -b -d 3 -n 60 -H > top.log
```

:warning: There are often _many_ more threads than tasks on a system, so displaying Threads will consume more resources on the target system, and will increase processing time when producing the graphs. _If you don't need it, leave it off._


### Running over SSH

Under some circumstances the i/o of writing the log file outweighs the overhead of sending the data over SSH and you may wish to collect the logs remotely:

```
ssh user@target_host "top -b -d 3 -n 60" > top.log
```
