summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean E. Russell <ser@ser1.net>2021-07-17 13:19:30 -0500
committerSean E. Russell <ser@ser1.net>2021-07-17 13:19:30 -0500
commita1dc3a0b1c29d86205c4aff7720f7e549f60e991 (patch)
tree740544cd85c5c7951f35550c52ccf7cf79a0d70e
parent7954eb4f377f5bce6c5a49ed49e56d71662bb202 (diff)
Remote extension was ignoring config file values.
-rw-r--r--devices/mem.go1
-rw-r--r--devices/remote.go10
-rw-r--r--docs/remote-extension.md64
3 files changed, 71 insertions, 4 deletions
diff --git a/devices/mem.go b/devices/mem.go
index defb01f..ceff9d6 100644
--- a/devices/mem.go
+++ b/devices/mem.go
@@ -4,6 +4,7 @@ import "log"
var memFuncs []func(map[string]MemoryInfo) map[string]error
+// TODO Colors are wrong for #mem > 2
type MemoryInfo struct {
Total uint64
Used uint64
diff --git a/devices/remote.go b/devices/remote.go
index a86f3ee..2366aab 100644
--- a/devices/remote.go
+++ b/devices/remote.go
@@ -24,6 +24,7 @@ var remoteLock sync.Mutex
// TODO Replace custom decoder with https://github.com/prometheus/common/blob/master/expfmt/decode.go
// TODO MQTT / Stomp / MsgPack
func init() {
+ // TODO add this to help text
opflag.StringVarP(&name, "remote-name", "", "", "Remote: name of remote gotop")
opflag.StringVarP(&remote_url, "remote-url", "", "", "Remote: URL of remote gotop")
opflag.DurationVarP(&sleep, "remote-refresh", "", 0, "Remote: Frequency to refresh data, in seconds")
@@ -37,10 +38,6 @@ type Remote struct {
}
func startup(vars map[string]string) error {
- // Don't set anything up if there's nothing to do
- if name == "" || remote_url == "" {
- return nil
- }
_cpuData = make(map[string]int)
_tempData = make(map[string]int)
_netData = make(map[string]float64)
@@ -49,6 +46,10 @@ func startup(vars map[string]string) error {
remoteLock = sync.Mutex{}
remotes := parseConfig(vars)
+ // Don't set anything up if there's nothing to do
+ if (name == "" || remote_url == "") && len(remotes) == 0 {
+ return nil
+ }
if remote_url != "" {
r := Remote{
url: remote_url,
@@ -230,6 +231,7 @@ func updateUsage(cpus map[string]int, _ bool) map[string]error {
func parseConfig(vars map[string]string) map[string]Remote {
rv := make(map[string]Remote)
+ log.Printf("VARS = %s", vars)
for key, value := range vars {
if strings.HasPrefix(key, "remote-") {
parts := strings.Split(key, "-")
diff --git a/docs/remote-extension.md b/docs/remote-extension.md
new file mode 100644
index 0000000..edafbf6
--- /dev/null
+++ b/docs/remote-extension.md
@@ -0,0 +1,64 @@
+# Remote monitoring extension for gotop
+
+
+Show data from gotop running on remote servers in a locally-running gotop. This allows gotop to be used as a simple terminal dashboard for remote servers.
+
+![Screenshot](/screenshots/fourby.png)
+
+
+## Configuration
+
+gotop exports metrics on a local port if it is run with the `--export <port>` argument. This is a simple, read-only interface with the expectation that it will be run behind some proxy that provides security. A gotop built with this extension can read this data and render it as if the devices being monitored were on the local machine.
+
+On the local side, gotop gets the remote information from a config file; it is not possible to pass this in on the command line. The recommended approach is to create a remote-specific config file, and then run gotop with the `-C <remote-config-filename>` option (or just add the options to the normal `gotop.config` file). Two options are available for each remote server; one of these, the connection URL, is required.
+
+The format of the configuration keys are: `remote-SERVERNAME-url` and `remote-SERVERNAME-refresh`; `SERVERNAME` can be anything -- it doesn't have to reflect any real attribute of the server, but it will be used in widget labels for data from that server. For example, CPU data from `remote-Jerry-url` will show up as `Jerry-CPU0`, `Jerry-CPU1`, and so on; memory data will be labeled `Jerry-Main` and `Jerry-Swap`. If the refresh rate option is omitted, it defaults to 1 second.
+
+
+### An example
+
+One way to set this up is to run gotop behind [Caddy](https://caddyserver.com). The `Caddyfile` would have something like this in it:
+
+```
+gotop.myserver.net {
+ basicauth / gotopusername supersecretpassword
+ proxy / http://localhost:8089
+}
+```
+
+Then, gotop would be run in a persistent terminal session such as [tmux](https://github.com/tmux/tmux) with the following command:
+
+```
+gotop -x :8089
+```
+
+A future release of gotop will include a `--headless` option to avoid the need to run gotop in a persistent `screen` or `tmux` terminal.
+
+Then, on a local laptop, create a config file named `myserver.conf` with the following lines:
+
+```
+remote-myserver-url=https://gotopusername:supersecretpassword@gotop.myserver.net/metrics
+remote-myserver-refresh=2
+```
+
+Note the `/metrics` at the end -- don't omit that, and don't strip it in Caddy. The refresh value is in seconds. Run gotop with:
+
+```
+gotop -C myserver.conf
+```
+
+and you should see your remote server sensors as if it were running on your local machine.
+
+You can add as many remote servers as you like in the config file; just follow the naming pattern.
+
+## Why
+
+This can combine multiple servers into one view, which makes it more practical to use a terminal-based monitor when you have more than a couple of servers, or when you don't want to dedicate an entire wide-screen monitor to a bunch of gotop instances. It's simple to set up, configure, and run, and reasonably resource efficient.
+
+## How
+
+Since v3.5.2, gotop's been able to export its sensor data as [Prometheus](https://prometheus.io/) metrics using the `--export` flag. Prometheus has the advantages of being simple to integrate into clients, and a nice on-demand design that depends on the *aggregator* pulling data from monitors, rather than the clients pushing data to a server. In essence, it inverts the client/server relationship for monitoring/aggregating servers and the things it's monitoring. In gotop's case, it means you can turn on `-x` and not have it impact your gotop instance at all, until you actively poll it. It puts the control on measurement frequency in a single place -- your local gotop. It means you can simply stop your local gotop instance (e.g., when you go to bed) and the demand on the servers you were monitoring drops to 0.
+
+On the client (local) side, sensors are abstracted as devices that are read by widgets, and we've simply implemented virtual devices that poll data from remote Prometheus instances. At a finer grain, there's a single process spawned for each remote server that periodically polls that server and collects the information. When the widget updates and asks the virtual device for data, the device consults the cached data and provides it as the measurement.
+
+The next iteration will optimize the metrics transfer protocol; while it'll likely remain HTTP, optimizations may include HTTP/2.0 streams to reduce the HTTP connection overhead, and a binary payload format for the metrics -- although HTTP/2.0 compression may eliminate any benefit of doing that.