diff options
author | euxane | 2024-11-30 11:44:43 +0100 |
---|---|---|
committer | euxane | 2024-11-30 11:44:43 +0100 |
commit | f6d0572984f78f400166fc585dd3b3a120101647 (patch) | |
tree | cd9fb97c8b00b4ec966f205f8c1e5bb484f73298 | |
parent | 12845f449cff81c37c646ecf0c6b7269de71f190 (diff) | |
download | tickwatch-f6d0572984f78f400166fc585dd3b3a120101647.tar.gz |
cli: turn action and target into positional arguments
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | main.nim | 40 | ||||
-rw-r--r-- | readme.md | 18 |
3 files changed, 40 insertions, 19 deletions
diff --git a/changelog.md b/changelog.md index b8af052..02a405f 100644 --- a/changelog.md +++ b/changelog.md | |||
@@ -2,6 +2,7 @@ Changelog | |||
2 | ========= | 2 | ========= |
3 | 3 | ||
4 | ## Next release | 4 | ## Next release |
5 | * The monitor and target are now positional CLI arguments instead of options | ||
5 | * Fixed issue emitting pings when the system's IP address changed during exec | 6 | * Fixed issue emitting pings when the system's IP address changed during exec |
6 | * Added `--timestamp=datetime|unix|none` param to set line header format | 7 | * Added `--timestamp=datetime|unix|none` param to set line header format |
7 | 8 | ||
@@ -9,6 +9,7 @@ import std/net | |||
9 | import std/posix | 9 | import std/posix |
10 | import std/paths | 10 | import std/paths |
11 | import std/strutils | 11 | import std/strutils |
12 | import std/sequtils | ||
12 | import std/parseopt | 13 | import std/parseopt |
13 | 14 | ||
14 | import file | 15 | import file |
@@ -33,17 +34,24 @@ proc registerTerminationHandlers() = | |||
33 | for signal in [SIGTERM, SIGHUP, SIGQUIT, SIGINT]: | 34 | for signal in [SIGTERM, SIGHUP, SIGQUIT, SIGINT]: |
34 | discard sigaction(signal, action) | 35 | discard sigaction(signal, action) |
35 | 36 | ||
37 | func getArg( | ||
38 | args: seq[tuple[kind: CmdLineKind, key, val: string]], | ||
39 | index: int, | ||
40 | label: string | ||
41 | ): string = | ||
42 | try: args[index].key | ||
43 | except: raise newException(ValueError, "Missing " & label & " argument") | ||
44 | |||
36 | proc main() = | 45 | proc main() = |
37 | var | 46 | var |
38 | scale: Scale = log2 | 47 | scale: Scale = log2 |
39 | symbols = UNICODE_SYMBOLS | 48 | symbols = UNICODE_SYMBOLS |
40 | timestampHeader = formatTimestampDateTime | 49 | timestampHeader = formatTimestampDateTime |
41 | (min, max) = (0, 1000) | 50 | (min, max) = (0, 1000) |
42 | probe: (timeout: Duration) -> int | ||
43 | 51 | ||
44 | for optKind, key, val in getopt(): | 52 | for optKind, key, val in getopt(): |
45 | if optKind notin {cmdLongOption, cmdShortOption}: | 53 | if optKind notin {cmdLongOption, cmdShortOption}: |
46 | raise newException(ValueError, "Invalid argument: " & key) | 54 | continue |
47 | 55 | ||
48 | case key: | 56 | case key: |
49 | 57 | ||
@@ -81,21 +89,33 @@ proc main() = | |||
81 | if parts.len != 2: raise newException(ValueError, "Invalid range") | 89 | if parts.len != 2: raise newException(ValueError, "Invalid range") |
82 | (min, max) = (parseInt(parts[0]), parseInt(parts[1])) | 90 | (min, max) = (parseInt(parts[0]), parseInt(parts[1])) |
83 | 91 | ||
92 | else: | ||
93 | raise newException(ValueError, "Unrecognised option") | ||
94 | |||
95 | let | ||
96 | args = getopt().toSeq.filterIt(it.kind == cmdArgument) | ||
97 | monitor = args.getArg(0, "monitor") | ||
98 | target = args.getArg(1, "target") | ||
99 | |||
100 | if args.len > 2: | ||
101 | raise newException(ValueError, "Invalid number of arguments") | ||
102 | |||
103 | let probe = case monitor: | ||
84 | of "ping": | 104 | of "ping": |
85 | let targetIp = resolve(val) | 105 | let targetIp = resolve(target) |
86 | let mon = initPingMonitor(targetIp, procIdent()) | 106 | let mon = initPingMonitor(targetIp, procIdent()) |
87 | probe = (timeout: Duration) => mon.ping(timeout).inMilliseconds.int | 107 | (timeout: Duration) => mon.ping(timeout).inMilliseconds.int |
88 | 108 | ||
89 | of "value": | 109 | of "value": |
90 | let mon = initFileValueMonitor(Path val) | 110 | let mon = initFileValueMonitor(Path target) |
91 | probe = (timeout: Duration) => mon.readValue() | 111 | (timeout: Duration) => mon.readValue() |
92 | 112 | ||
93 | of "change": | 113 | of "change": |
94 | let mon = initFileChangeMonitor(Path val) | 114 | let mon = initFileChangeMonitor(Path target) |
95 | probe = (timeout: Duration) => mon.readValue() | 115 | (timeout: Duration) => mon.readValue() |
96 | 116 | ||
97 | if probe == nil: | 117 | else: |
98 | raise newException(ValueError, "Missing monitor argument") | 118 | raise newException(ValueError, "Unrecognised monitor argument") |
99 | 119 | ||
100 | loop( | 120 | loop( |
101 | probe, | 121 | probe, |
@@ -22,13 +22,13 @@ CLI usage | |||
22 | ```helptext | 22 | ```helptext |
23 | tickwatch: A monitoring and visualization tool | 23 | tickwatch: A monitoring and visualization tool |
24 | 24 | ||
25 | Usage: tickwatch [OPTIONS] | 25 | Usage: tickwatch [OPTIONS] MONITOR TARGET |
26 | 26 | ||
27 | Monitor options: | 27 | Monitors: |
28 | --ping=HOST Monitor ping latency to specified IP or hostname | 28 | ping Monitor ping latency to specified IP or hostname |
29 | Prefix hostname with 4/ or 6/ to force IP version | 29 | Prefix target hostname with 4/ or 6/ to force IP version |
30 | --value=PATH Monitor a sysfs file's value | 30 | value Monitor a sysfs file's value |
31 | --change=PATH Monitor changes in a sysfs file's value | 31 | change Monitor changes in a sysfs file's value |
32 | 32 | ||
33 | Display options: | 33 | Display options: |
34 | --range=MIN:MAX Set range of values (default: 0:1000) | 34 | --range=MIN:MAX Set range of values (default: 0:1000) |
@@ -44,13 +44,13 @@ Other options: | |||
44 | --version, -v Display the version | 44 | --version, -v Display the version |
45 | 45 | ||
46 | Examples: | 46 | Examples: |
47 | tickwatch --ping=6/euxane.net | 47 | tickwatch ping 6/euxane.net |
48 | 48 | ||
49 | tickwatch --range=0:100000 \ | 49 | tickwatch --range=0:100000 \ |
50 | --change=/sys/class/net/eth0/statistics/rx_packets | 50 | change /sys/class/net/eth0/statistics/rx_packets |
51 | 51 | ||
52 | tickwatch --scale=linear --range=0:50000 \ | 52 | tickwatch --scale=linear --range=0:50000 \ |
53 | --value=/sys/class/thermal/thermal_zone0/temp | 53 | value /sys/class/thermal/thermal_zone0/temp |
54 | ``` | 54 | ``` |
55 | 55 | ||
56 | 56 | ||