From ed468152fa95b4bb00174f30072843ddfeddf43b Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Wed, 29 Aug 2018 14:39:53 -0400 Subject: [PATCH 01/16] Don't complain if cleaning pre-emptively --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f516fb9..f3c91d6 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ endef build: $(AWK_EXECUTABLES) clean: - rm $(AWK_EXECUTABLES) + rm -f $(AWK_EXECUTABLES) bin/khatus_bar: \ -- 2.20.1 From 23fbde848bf322bb5dfd8e43ebc591265e2549a0 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Wed, 29 Aug 2018 17:13:10 -0400 Subject: [PATCH 02/16] Bring back src module name in messages --- Makefile | 2 +- src/awk/exe/actuate_alert_to_notify_send.awk | 11 +++++++---- src/awk/exe/actuate_status_bar_to_xsetroot_name.awk | 1 - src/awk/lib/msg_out.awk | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index f3c91d6..c741acf 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,7 @@ AWK_EXECUTABLES := \ define BUILD_AWK_EXE echo '#! $(PATH_TO_AWK) -f' > $@ && \ + echo 'BEGIN {Module = "$(notdir $@)"}' >> $@ && \ cat $^ >> $@ && \ chmod +x $@ endef @@ -32,7 +33,6 @@ endef build \ clean - build: $(AWK_EXECUTABLES) clean: diff --git a/src/awk/exe/actuate_alert_to_notify_send.awk b/src/awk/exe/actuate_alert_to_notify_send.awk index eae5cb5..f11b2f4 100755 --- a/src/awk/exe/actuate_alert_to_notify_send.awk +++ b/src/awk/exe/actuate_alert_to_notify_send.awk @@ -7,17 +7,20 @@ BEGIN { } $1 == "OK" && \ -$2 == "alert" { - priority = $3 - subject = $4 +$3 == "alert" { + src = $2 + priority = $4 + subject = $5 - # Not just using $5 for body - because body might contain a character + # Not just using $6 for body - because body might contain a character # identical to FS len_line = length($0) len_head = length($1 FS $2 FS $3 FS $4 FS $5 FS) len_body = len_line - len_head body = substr($0, len_head + 1, len_body) + sep = body ? "\n" : "" + body = body sep "--" src urgency = priority sub("hi" , "critical", urgency) sub("med", "normal" , urgency) diff --git a/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk b/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk index 60966c3..b97538b 100755 --- a/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk +++ b/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk @@ -7,7 +7,6 @@ $3 == "status_bar" { len_head = length($1 FS $2 FS $3 FS) len_val = len_line - len_head val = substr($0, len_head + 1, len_val) - system("xsetroot -name \"" val "\"") next } diff --git a/src/awk/lib/msg_out.awk b/src/awk/lib/msg_out.awk index 9207fd0..1a0f813 100755 --- a/src/awk/lib/msg_out.awk +++ b/src/awk/lib/msg_out.awk @@ -16,5 +16,5 @@ function msg_out_error(location, msg) { } function msg_out(status, key, val, channel) { - print(status, key, val) > channel + print(status, Module, key, val) > channel } -- 2.20.1 From 3ad4dbbb5749882df5ab4c4596bb9743a5b2f736 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Wed, 29 Aug 2018 17:33:12 -0400 Subject: [PATCH 03/16] Move install script to make --- Makefile | 5 +++++ install | 15 --------------- 2 files changed, 5 insertions(+), 15 deletions(-) delete mode 100755 install diff --git a/Makefile b/Makefile index c741acf..c63c61e 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +PREFIX := $(HOME) PATH_TO_AWK := /usr/bin/awk AWK_EXECUTABLES := \ bin/khatus_bar \ @@ -31,10 +32,14 @@ endef .PHONY: \ build \ + install \ clean build: $(AWK_EXECUTABLES) +install: + $(foreach filename,$(wildcard bin/*),cp -p "$(filename)" "$(PREFIX)/$(filename)"; ) + clean: rm -f $(AWK_EXECUTABLES) diff --git a/install b/install deleted file mode 100755 index ca12cc4..0000000 --- a/install +++ /dev/null @@ -1,15 +0,0 @@ -#! /bin/sh - -PREFIX="$HOME/bin" - -if [ $1 ] -then - PREFIX=$1 -fi - -cd bin - -for filename in * -do - cp -p "`pwd`/$filename" "$PREFIX/$filename" -done -- 2.20.1 From 7875d28d993b1178a548c8224b27afa8b7eceda9 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Wed, 29 Aug 2018 17:36:08 -0400 Subject: [PATCH 04/16] Add build instructions --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 169b7d2..947e6ed 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ Experimental system-monitor and status (bar) reporter I use with Usage ----- +`make build && make install` + +`make install` copies everything from `./bin` to `$HOME/bin` + In my `~/.xinitrc` I have something like the following: ```sh -- 2.20.1 From 61849d4c62b4b5a66c217f687f23d91a82eff906 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Wed, 29 Aug 2018 17:47:53 -0400 Subject: [PATCH 05/16] Fix alert to include src module in msg --- src/awk/lib/alert.awk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/awk/lib/alert.awk b/src/awk/lib/alert.awk index c043ea8..5e14146 100755 --- a/src/awk/lib/alert.awk +++ b/src/awk/lib/alert.awk @@ -2,5 +2,5 @@ function alert(priority, subject, body) { # priority : "low" | "med" | "hi" # subject : string without spaces # body : anything - print("OK", "alert", priority, subject, body) + print("OK", Module, "alert", priority, subject, body) } -- 2.20.1 From e62110ca0e9df50acdd458df7ef19cc8c1a4b81b Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Wed, 29 Aug 2018 19:57:31 -0400 Subject: [PATCH 06/16] Break out status component values from formatting first step in giving user more fine-grained bar control --- src/awk/exe/bar.awk | 244 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 190 insertions(+), 54 deletions(-) diff --git a/src/awk/exe/bar.awk b/src/awk/exe/bar.awk index 6862ee8..d3deefe 100755 --- a/src/awk/exe/bar.awk +++ b/src/awk/exe/bar.awk @@ -23,13 +23,22 @@ $2 == "khatus_sensor_datetime" { # ----------------------------------------------------------------------------- -# Status bar +# Energy # ----------------------------------------------------------------------------- -function bar_make_status_energy( state, charge, direction_of_change) { - cache_get(state , "khatus_sensor_energy", "battery_state" , 0) +function bar_make_status_energy( d, p) { + d = bar_make_status_energy_direction() + p = bar_make_status_energy_percent() + return sprintf("E%s%d%%", d, p) +} + +function bar_make_status_energy_percent( charge) { cache_get(charge, "khatus_sensor_energy", "battery_percentage", 0) + return charge["value"] +} +function bar_make_status_energy_direction( state, direction_of_change) { + cache_get(state, "khatus_sensor_energy", "battery_state", 0) if (state["value"] == "discharging") { direction_of_change = "<" } else if (state["value"] == "charging") { @@ -37,11 +46,18 @@ function bar_make_status_energy( state, charge, direction_of_change) { } else { direction_of_change = "=" } + return direction_of_change +} - return sprintf("E%s%d%%", direction_of_change, charge["value"]) +# ----------------------------------------------------------------------------- +# Memory +# ----------------------------------------------------------------------------- + +function bar_make_status_mem() { + return sprintf("M=%s%%", bar_make_status_mem_percent()) } -function bar_make_status_mem( total, used, percent, status) { +function bar_make_status_mem_percent( total, used, percent, percent_str) { cache_get(total, "khatus_sensor_memory", "total", 5) cache_get(used , "khatus_sensor_memory", "used" , 5) # Checking total["value"] to avoid division by zero when data is missing @@ -50,13 +66,17 @@ function bar_make_status_mem( total, used, percent, status) { total["value"] \ ) { percent = util_round((used["value"] / total["value"]) * 100) - status = sprintf("%d%%", percent) + percent_str = sprintf("%d", percent) } else { - status = "__" + percent_str = "__" } - return sprintf("M=%s", status) + return percent_str } +# ----------------------------------------------------------------------------- +# Processes +# ----------------------------------------------------------------------------- + function bar_make_status_procs() { # From man ps: # D uninterruptible sleep (usually IO) @@ -71,87 +91,185 @@ function bar_make_status_procs() { # Additionally, not documented in ps man page: # I Idle # - src = "khatus_sensor_procs" - all = cache_get_fmt_def(src, "total_procs" , 15, "%d") - r = cache_get_fmt_def(src, "total_per_state" Kfs "R", 15, "%d", "0") - d = cache_get_fmt_def(src, "total_per_state" Kfs "D", 15, "%d", "0") - t = cache_get_fmt_def(src, "total_per_state" Kfs "T", 15, "%d", "0") - i = cache_get_fmt_def(src, "total_per_state" Kfs "I", 15, "%d", "0") - z = cache_get_fmt_def(src, "total_per_state" Kfs "Z", 15, "%d", "0") + all = bar_make_status_procs_count_all() + r = bar_make_status_procs_count_r() + d = bar_make_status_procs_count_d() + t = bar_make_status_procs_count_t() + i = bar_make_status_procs_count_i() + z = bar_make_status_procs_count_z() return sprintf("P=[%s %sr %sd %st %si %sz]", all, r, d, t, i, z) } +function bar_make_status_procs_count_all() { + return cache_get_fmt_def("khatus_sensor_procs", "total_procs", 15, "%d") +} + +function bar_make_status_procs_count_r( src) { + src = "khatus_sensor_procs" + return cache_get_fmt_def(src, "total_per_state" Kfs "R", 15, "%d", "0") +} + +function bar_make_status_procs_count_d( src) { + src = "khatus_sensor_procs" + return cache_get_fmt_def(src, "total_per_state" Kfs "D", 15, "%d", "0") +} + +function bar_make_status_procs_count_t( src) { + src = "khatus_sensor_procs" + return cache_get_fmt_def(src, "total_per_state" Kfs "T", 15, "%d", "0") +} + +function bar_make_status_procs_count_i( src) { + src = "khatus_sensor_procs" + return cache_get_fmt_def(src, "total_per_state" Kfs "I", 15, "%d", "0") +} + +function bar_make_status_procs_count_z( src) { + src = "khatus_sensor_procs" + return cache_get_fmt_def(src, "total_per_state" Kfs "Z", 15, "%d", "0") +} + +# ----------------------------------------------------------------------------- +# CPU +# ----------------------------------------------------------------------------- + function bar_make_status_cpu( l, t, f) { - l_src = "khatus_sensor_loadavg" - t_src = "khatus_sensor_temperature" - f_src = "khatus_sensor_fan" - l = cache_get_fmt_def(l_src, "load_avg_1min", 5, "%4.2f") - t = cache_get_fmt_def(t_src, "temp_c" , 5, "%d" ) - f = cache_get_fmt_def(f_src, "speed" , 5, "%4d" ) + l = bar_make_status_cpu_loadavg() + t = bar_make_status_cpu_temperature() + f = bar_make_status_cpu_fan_speed() return sprintf("C=[%s %s°C %srpm]", l, t, f) } -function bar_make_status_disk( u, w, r, src_u, src_io) { - src_u = "khatus_sensor_disk_space" - src_io = "khatus_sensor_disk_io" - u = cache_get_fmt_def(src_u , "disk_usage_percentage", 10, "%s") - w = cache_get_fmt_def(src_io, "sectors_written" , 5, "%0.3f") - r = cache_get_fmt_def(src_io, "sectors_read" , 5, "%0.3f") +function bar_make_status_cpu_loadavg( src) { + src = "khatus_sensor_loadavg" + return cache_get_fmt_def(src, "load_avg_1min", 5, "%4.2f") +} + +function bar_make_status_cpu_temperature() { + return cache_get_fmt_def("khatus_sensor_temperature", "temp_c", 5, "%d") +} + +function bar_make_status_cpu_fan_speed() { + return cache_get_fmt_def("khatus_sensor_fan", "speed", 5, "%4d") +} + +# ----------------------------------------------------------------------------- +# Disk +# ----------------------------------------------------------------------------- + +function bar_make_status_disk( u, w, r) { + u = bar_make_status_disk_space() + w = bar_make_status_disk_io_w() + r = bar_make_status_disk_io_r() return sprintf("D=[%s%% %s▲ %s▼]", u, w, r) } +function bar_make_status_disk_space( src) { + src = "khatus_sensor_disk_space" + return cache_get_fmt_def(src, "disk_usage_percentage", 10, "%s") +} + +function bar_make_status_disk_io_w( src) { + src = "khatus_sensor_disk_io" + return cache_get_fmt_def(src, "sectors_written", 5, "%0.3f") +} + +function bar_make_status_disk_io_r( src) { + src = "khatus_sensor_disk_io" + return cache_get_fmt_def(src, "sectors_read", 5, "%0.3f") +} + +# ----------------------------------------------------------------------------- +# Network +# ----------------------------------------------------------------------------- + function bar_make_status_net( \ number_of_net_interfaces_to_show, \ net_interfaces_to_show, \ - io, \ - wi, \ i, \ interface, \ label, \ - wifi, \ addr, \ w, \ r, \ - io_stat, \ out, \ sep \ ) { number_of_net_interfaces_to_show = \ split(Opt_Net_Interfaces_To_Show, net_interfaces_to_show, ",") - io = "khatus_sensor_net_addr_io" - wi = "khatus_sensor_net_wifi_status" out = "" sep = "" for (i = number_of_net_interfaces_to_show; i > 0; i--) { interface = net_interfaces_to_show[i] label = substr(interface, 1, 1) if (interface ~ "^w") { - wifi = cache_get_fmt_def(wi, "status" Kfs interface, 10, "%s") - label = label ":" wifi + label = label ":" bar_make_status_net_wifi(interface) } - addr = cache_get_fmt_def(io, "addr" Kfs interface, 5, "%s", "") - w = cache_get_fmt_def(io, "bytes_written" Kfs interface, 5, "%0.3f") - r = cache_get_fmt_def(io, "bytes_read" Kfs interface, 5, "%0.3f") - io_stat = addr ? sprintf("%s▲ %s▼", w, r) : "--" - out = out sep label ":" io_stat + addr = bar_make_status_net_addr(interface) + w = bar_make_status_net_io_w(interface) + r = bar_make_status_net_io_r(interface) + out = out sep label ":" sprintf("%s▲ %s▼", w, r) sep = " " } return sprintf("N[%s]", out) } -function bar_make_status_bluetooth( src, key) { +function bar_make_status_net_addr(interface, src) { + src = "khatus_sensor_net_addr_io" + return cache_get_fmt_def(src, "addr" Kfs interface, 5, "%s", "") +} + +function bar_make_status_net_io_w(interface, src) { + src = "khatus_sensor_net_addr_io" + return cache_get_fmt_def(src, "bytes_written" Kfs interface, 5, "%0.3f") +} + +function bar_make_status_net_io_r(interface, src) { + src = "khatus_sensor_net_addr_io" + return cache_get_fmt_def(src, "bytes_read" Kfs interface, 5, "%0.3f") +} + +function bar_make_status_net_wifi(interface, src) { + src = "khatus_sensor_net_wifi_status" + return cache_get_fmt_def(src, "status" Kfs interface, 10, "%s") +} + +# ----------------------------------------------------------------------------- +# Bluetooth +# ----------------------------------------------------------------------------- + +function bar_make_status_bluetooth() { + return sprintf("B=%s", bar_make_status_bluetooth_power()) +} + +function bar_make_status_bluetooth_power( src) { src = "khatus_sensor_bluetooth_power" - key = "power_status" - return sprintf("B=%s", cache_get_fmt_def(src, key, 10, "%s")) + return cache_get_fmt_def(src, "power_status", 10, "%s") } -function bar_make_status_screen_brightness( src, key) { +# ----------------------------------------------------------------------------- +# Backlight +# ----------------------------------------------------------------------------- + +function bar_make_status_screen_brightness() { + return sprintf("*%s%%", bar_make_status_backlight_percent()) +} + +function bar_make_status_backlight_percent( src) { src = "khatus_sensor_screen_brightness" - key = "percentage" - return sprintf("*%s%%", cache_get_fmt_def(src, key, 5, "%d")) + return cache_get_fmt_def(src, "percentage", 5, "%d") } -function bar_make_status_volume( sink, mu, vl, vr, show) { +# ----------------------------------------------------------------------------- +# Volume +# ----------------------------------------------------------------------------- + +function bar_make_status_volume() { + return sprintf("(%s)", bar_make_status_volume_value()) +} + +# TODO: better name than "bar_make_status_volume_value" ... :) +function bar_make_status_volume_value( sink, mu, vl, vr, show) { sink = Opt_Pulseaudio_Sink cache_get(mu, "khatus_sensor_volume", "mute" Kfs sink, 5) cache_get(vl, "khatus_sensor_volume", "vol_left" Kfs sink, 5) @@ -167,10 +285,18 @@ function bar_make_status_volume( sink, mu, vl, vr, show) { ) } } - return sprintf("(%s)", show) + return show } -function bar_make_status_mpd( state, status) { +# ----------------------------------------------------------------------------- +# MPD +# ----------------------------------------------------------------------------- + +function bar_make_status_mpd() { + return sprintf("[%s]", bar_make_status_mpd_value()) +} + +function bar_make_status_mpd_value( state, status) { cache_get(state, "khatus_sensor_mpd", "state", 5) if (!state["is_expired"] && state["value"]) { if (state["value"] == "play") { @@ -189,8 +315,7 @@ function bar_make_status_mpd( state, status) { } else { status = "--" } - - return sprintf("[%s]", status) + return status } function bar_make_status_mpd_state_known(symbol, s, song, time, percentage) { @@ -202,13 +327,24 @@ function bar_make_status_mpd_state_known(symbol, s, song, time, percentage) { return sprintf("%s %s %s %s", symbol, time, percent, song) } -function bar_make_status_weather( src, hour, t_f) { +# ----------------------------------------------------------------------------- +# Weather +# ----------------------------------------------------------------------------- + +function bar_make_status_weather() { + return sprintf("%s°F", bar_make_status_weather_temp_f()) +} + +function bar_make_status_weather_temp_f( src, hour) { src = "khatus_sensor_weather" hour = 60 * 60 - t_f = cache_get_fmt_def(src, "temperature_f", 3 * hour, "%d") - return sprintf("%s°F", t_f) + return cache_get_fmt_def(src, "temperature_f", 3 * hour, "%d") } +# ----------------------------------------------------------------------------- +# Datetime +# ----------------------------------------------------------------------------- + function bar_make_status_datetime( dt) { return cache_get_fmt_def("khatus_sensor_datetime", "datetime", 5, "%s") } -- 2.20.1 From 65034298ed16f62809953c9554c46b253564bf5f Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Thu, 30 Aug 2018 10:42:43 -0400 Subject: [PATCH 07/16] Move (most of) bar formatting to the user --- bin/khatus_gen_bar_make_status | 89 ++++++++++++++++------- sanity_check | 4 +- src/awk/exe/bar.awk | 125 +++++---------------------------- 3 files changed, 82 insertions(+), 136 deletions(-) diff --git a/bin/khatus_gen_bar_make_status b/bin/khatus_gen_bar_make_status index 00e5506..7c34148 100755 --- a/bin/khatus_gen_bar_make_status +++ b/bin/khatus_gen_bar_make_status @@ -1,39 +1,74 @@ #! /usr/bin/awk -f BEGIN { - aliases["@energy"] = "bar_make_status_energy()" - aliases["@memory"] = "bar_make_status_mem()" - aliases["@processes"] = "bar_make_status_procs()" - aliases["@cpu"] = "bar_make_status_cpu()" - aliases["@disk"] = "bar_make_status_disk()" - aliases["@net"] = "bar_make_status_net()" - aliases["@bluetooth"] = "bar_make_status_bluetooth()" - aliases["@backlight"] = "bar_make_status_screen_brightness()" - aliases["@volume"] = "bar_make_status_volume()" - aliases["@mpd"] = "bar_make_status_mpd()" - aliases["@weather"] = "bar_make_status_weather()" - aliases["@datetime"] = "bar_make_status_datetime()" - out = "function bar_make_status( position, bar, sep, i, j) {\n" - n = split(Status_Bar, s, ",") - for (i=1; i<=n; i++) { - alias = s[i] - function_call = aliases[alias] + aliases["@energy_percent"] = "bar_make_status_energy_percent()" + aliases["@energy_direction"] = "bar_make_status_energy_direction()" + + aliases["@memory_percent"] = "bar_make_status_mem_percent()" + + aliases["@processes_count_all"] = "bar_make_status_procs_count_all()" + aliases["@processes_count_r"] = "bar_make_status_procs_count_r()" + aliases["@processes_count_d"] = "bar_make_status_procs_count_d()" + aliases["@processes_count_t"] = "bar_make_status_procs_count_t()" + aliases["@processes_count_i"] = "bar_make_status_procs_count_i()" + aliases["@processes_count_z"] = "bar_make_status_procs_count_z()" + + aliases["@cpu_loadavg"] = "bar_make_status_cpu_loadavg()" + aliases["@cpu_temp"] = "bar_make_status_cpu_temperature()" + aliases["@cpu_fan_speed"] = "bar_make_status_cpu_fan_speed()" + + aliases["@disk_space"] = "bar_make_status_disk_space()" + aliases["@disk_io_w"] = "bar_make_status_disk_io_w()" + aliases["@disk_io_r"] = "bar_make_status_disk_io_r()" + + aliases["@net_addr"] = "bar_make_status_net_addr(\"%s\")" + params["@net_addr"] = 1 + aliases["@net_io_w"] = "bar_make_status_net_io_w(\"%s\")" + params["@net_io_w"] = 1 + aliases["@net_io_r"] = "bar_make_status_net_io_r(\"%s\")" + params["@net_io_r"] = 1 + aliases["@net_wifi"] = "bar_make_status_net_wifi(\"%s\")" + params["@net_wifi"] = 1 + + aliases["@bluetooth_power"] = "bar_make_status_bluetooth_power()" + + aliases["@backlight_percent"] = "bar_make_status_backlight_percent()" + + aliases["@volume_pa_sink"] = "bar_make_status_volume_pulseaudio_sink(%d)" + params["@volume_pa_sink"] = 1 + + aliases["@mpd"] = "bar_make_status_mpd()" + + aliases["@weather_temp_f"] = "bar_make_status_weather_temp_f()" + + aliases["@datetime"] = "bar_make_status_datetime()" + + out = "function bar_make_status() {\n" + n_args = split(Status_Args, args_arr, ",") + for (i=1; i<=n_args; i++) { + arg = args_arr[i] + split(arg, arg_parts, ":") + alias = arg_parts[1] + n_expected_params = params[alias] + if (n_expected_params == 0) { + function_call = aliases[alias] + } else if (n_expected_params == 1) { + function_call = sprintf(aliases[alias], arg_parts[2]) + } else { + printf(\ + "Unsupported number of params: %d in %s\n", + n_expected_params, alias) \ + > "/dev/stderr" + exit(1) + } if (function_call) { - out = out " position[++i] = " function_call ";\n" + args_str = args_str ", " function_call } else { printf("Unexpected status bar component alias: \"%s\"\n", alias) \ > "/dev/stderr" exit(1) } } - out = out "\ - bar = \"\";\ - sep = \"\";\ - for (j = 1; j <= i; j++) {\ - bar = bar sep position[j];\ - sep = \" \";\ - }\ - return bar;\ - }"; + out = out " return sprintf(\"" Status_Fmt "\"" args_str ");\n}"; print out } diff --git a/sanity_check b/sanity_check index ed7f574..09fc142 100755 --- a/sanity_check +++ b/sanity_check @@ -6,11 +6,11 @@ | stdbuf -o L tee \ >(stdbuf -o L ./bin/khatus_bar \ -v Opt_Mpd_Song_Max_Chars=10 \ - -v Opt_Net_Interfaces_To_Show=wlp3s0 \ -v Opt_Pulseaudio_Sink=0 \ -v GC_Interval=300 \ -f <(./bin/khatus_gen_bar_make_status \ - -v Status_Bar='@energy,@memory,@processes,@cpu,@disk,@net,@bluetooth,@backlight,@volume,@mpd,@weather,@datetime' \ + -v Status_Fmt=' E=%s%% M=%d%% P=[%s %sr %sd %st %si %sz] C=[%s %s°C %srpm] D=[%s%% %s▲ %s▼] W=[%s %s▲ %s▼] B=%s *=%s%% (%s) [%s] %s°F %s ' \ + -v Status_Args='@energy_percent,@memory_percent,@processes_count_all,@processes_count_r,@processes_count_d,@processes_count_t,@processes_count_i,@processes_count_z,@cpu_loadavg,@cpu_temp,@cpu_fan_speed,@disk_space,@disk_io_w,@disk_io_r,@net_wifi:wlp3s0,@net_io_w:wlp3s0,@net_io_r:wlp3s0,@bluetooth_power,@backlight_percent,@volume_pa_sink:0,@mpd,@weather_temp_f,@datetime' \ ) \ ) \ >(stdbuf -o L ./bin/khatus_monitor_energy) \ diff --git a/src/awk/exe/bar.awk b/src/awk/exe/bar.awk index d3deefe..9be1adb 100755 --- a/src/awk/exe/bar.awk +++ b/src/awk/exe/bar.awk @@ -26,15 +26,8 @@ $2 == "khatus_sensor_datetime" { # Energy # ----------------------------------------------------------------------------- -function bar_make_status_energy( d, p) { - d = bar_make_status_energy_direction() - p = bar_make_status_energy_percent() - return sprintf("E%s%d%%", d, p) -} - -function bar_make_status_energy_percent( charge) { - cache_get(charge, "khatus_sensor_energy", "battery_percentage", 0) - return charge["value"] +function bar_make_status_energy_percent() { + return cache_get_fmt_def("khatus_sensor_energy", "battery_percentage", 0, "%d") } function bar_make_status_energy_direction( state, direction_of_change) { @@ -53,10 +46,6 @@ function bar_make_status_energy_direction( state, direction_of_change) { # Memory # ----------------------------------------------------------------------------- -function bar_make_status_mem() { - return sprintf("M=%s%%", bar_make_status_mem_percent()) -} - function bar_make_status_mem_percent( total, used, percent, percent_str) { cache_get(total, "khatus_sensor_memory", "total", 5) cache_get(used , "khatus_sensor_memory", "used" , 5) @@ -76,29 +65,18 @@ function bar_make_status_mem_percent( total, used, percent, percent_str) { # ----------------------------------------------------------------------------- # Processes # ----------------------------------------------------------------------------- - -function bar_make_status_procs() { - # From man ps: - # D uninterruptible sleep (usually IO) - # R running or runnable (on run queue) - # S interruptible sleep (waiting for an event to complete) - # T stopped by job control signal - # t stopped by debugger during the tracing - # W paging (not valid since the 2.6.xx kernel) - # X dead (should never be seen) - # Z defunct ("zombie") process, terminated but not reaped by its parent - # - # Additionally, not documented in ps man page: - # I Idle - # - all = bar_make_status_procs_count_all() - r = bar_make_status_procs_count_r() - d = bar_make_status_procs_count_d() - t = bar_make_status_procs_count_t() - i = bar_make_status_procs_count_i() - z = bar_make_status_procs_count_z() - return sprintf("P=[%s %sr %sd %st %si %sz]", all, r, d, t, i, z) -} +# From man ps: +# D uninterruptible sleep (usually IO) +# R running or runnable (on run queue) +# S interruptible sleep (waiting for an event to complete) +# T stopped by job control signal +# t stopped by debugger during the tracing +# W paging (not valid since the 2.6.xx kernel) +# X dead (should never be seen) +# Z defunct ("zombie") process, terminated but not reaped by its parent +# +# Additionally, not documented in ps man page: +# I Idle function bar_make_status_procs_count_all() { return cache_get_fmt_def("khatus_sensor_procs", "total_procs", 15, "%d") @@ -133,13 +111,6 @@ function bar_make_status_procs_count_z( src) { # CPU # ----------------------------------------------------------------------------- -function bar_make_status_cpu( l, t, f) { - l = bar_make_status_cpu_loadavg() - t = bar_make_status_cpu_temperature() - f = bar_make_status_cpu_fan_speed() - return sprintf("C=[%s %s°C %srpm]", l, t, f) -} - function bar_make_status_cpu_loadavg( src) { src = "khatus_sensor_loadavg" return cache_get_fmt_def(src, "load_avg_1min", 5, "%4.2f") @@ -157,13 +128,6 @@ function bar_make_status_cpu_fan_speed() { # Disk # ----------------------------------------------------------------------------- -function bar_make_status_disk( u, w, r) { - u = bar_make_status_disk_space() - w = bar_make_status_disk_io_w() - r = bar_make_status_disk_io_r() - return sprintf("D=[%s%% %s▲ %s▼]", u, w, r) -} - function bar_make_status_disk_space( src) { src = "khatus_sensor_disk_space" return cache_get_fmt_def(src, "disk_usage_percentage", 10, "%s") @@ -183,37 +147,6 @@ function bar_make_status_disk_io_r( src) { # Network # ----------------------------------------------------------------------------- -function bar_make_status_net( \ - number_of_net_interfaces_to_show, \ - net_interfaces_to_show, \ - i, \ - interface, \ - label, \ - addr, \ - w, \ - r, \ - out, \ - sep \ -) { - number_of_net_interfaces_to_show = \ - split(Opt_Net_Interfaces_To_Show, net_interfaces_to_show, ",") - out = "" - sep = "" - for (i = number_of_net_interfaces_to_show; i > 0; i--) { - interface = net_interfaces_to_show[i] - label = substr(interface, 1, 1) - if (interface ~ "^w") { - label = label ":" bar_make_status_net_wifi(interface) - } - addr = bar_make_status_net_addr(interface) - w = bar_make_status_net_io_w(interface) - r = bar_make_status_net_io_r(interface) - out = out sep label ":" sprintf("%s▲ %s▼", w, r) - sep = " " - } - return sprintf("N[%s]", out) -} - function bar_make_status_net_addr(interface, src) { src = "khatus_sensor_net_addr_io" return cache_get_fmt_def(src, "addr" Kfs interface, 5, "%s", "") @@ -238,23 +171,15 @@ function bar_make_status_net_wifi(interface, src) { # Bluetooth # ----------------------------------------------------------------------------- -function bar_make_status_bluetooth() { - return sprintf("B=%s", bar_make_status_bluetooth_power()) -} - function bar_make_status_bluetooth_power( src) { src = "khatus_sensor_bluetooth_power" return cache_get_fmt_def(src, "power_status", 10, "%s") } # ----------------------------------------------------------------------------- -# Backlight +# Backlight (screen brightness) # ----------------------------------------------------------------------------- -function bar_make_status_screen_brightness() { - return sprintf("*%s%%", bar_make_status_backlight_percent()) -} - function bar_make_status_backlight_percent( src) { src = "khatus_sensor_screen_brightness" return cache_get_fmt_def(src, "percentage", 5, "%d") @@ -264,13 +189,7 @@ function bar_make_status_backlight_percent( src) { # Volume # ----------------------------------------------------------------------------- -function bar_make_status_volume() { - return sprintf("(%s)", bar_make_status_volume_value()) -} - -# TODO: better name than "bar_make_status_volume_value" ... :) -function bar_make_status_volume_value( sink, mu, vl, vr, show) { - sink = Opt_Pulseaudio_Sink +function bar_make_status_volume_pulseaudio_sink(sink, mu, vl, vr, show) { cache_get(mu, "khatus_sensor_volume", "mute" Kfs sink, 5) cache_get(vl, "khatus_sensor_volume", "vol_left" Kfs sink, 5) cache_get(vr, "khatus_sensor_volume", "vol_right" Kfs sink, 5) @@ -280,7 +199,7 @@ function bar_make_status_volume_value( sink, mu, vl, vr, show) { else if (mu["value"] == "no") {show = vl["value"] " " vr["value"]} else { msg_out_error(\ - "bar_make_status_volume", \ + "bar_make_status_volume_pulseaudio_sink: " sink ". ", \ "Unexpected value for 'mute' field: " mu["value"] \ ) } @@ -292,11 +211,7 @@ function bar_make_status_volume_value( sink, mu, vl, vr, show) { # MPD # ----------------------------------------------------------------------------- -function bar_make_status_mpd() { - return sprintf("[%s]", bar_make_status_mpd_value()) -} - -function bar_make_status_mpd_value( state, status) { +function bar_make_status_mpd( state, status) { cache_get(state, "khatus_sensor_mpd", "state", 5) if (!state["is_expired"] && state["value"]) { if (state["value"] == "play") { @@ -331,10 +246,6 @@ function bar_make_status_mpd_state_known(symbol, s, song, time, percentage) { # Weather # ----------------------------------------------------------------------------- -function bar_make_status_weather() { - return sprintf("%s°F", bar_make_status_weather_temp_f()) -} - function bar_make_status_weather_temp_f( src, hour) { src = "khatus_sensor_weather" hour = 60 * 60 -- 2.20.1 From 42b03b4e7166f53277260bc3ac7d7d343c9a7bd6 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Thu, 30 Aug 2018 12:52:35 -0400 Subject: [PATCH 08/16] Update README --- README.md | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 947e6ed..834d6ab 100644 --- a/README.md +++ b/README.md @@ -10,22 +10,34 @@ Experimental system-monitor and status (bar) reporter I use with Usage ----- -`make build && make install` +### Build -`make install` copies everything from `./bin` to `$HOME/bin` +`make build` + +### Install + +To copy everything from `./bin` to `$HOME/bin`: + +`make install` + +### Use In my `~/.xinitrc` I have something like the following: ```sh ( $BIN/khatus \ - --wifi_interface 'wlp3s0' \ + --wifi_interface 'wlp3s0' \ + --interval_bluetooth 5 \ + --interval_net_wifi 5 \ + --interval_disk_space 5 \ | stdbuf -o L tee \ >(stdbuf -o L "$BIN"/khatus_bar \ -v Opt_Mpd_Song_Max_Chars=10 \ - -v Opt_Net_Interfaces_To_Show=wlp3s0 \ -v Opt_Pulseaudio_Sink=0 \ - -f <(./bin/khatus_gen_make_status_bar \ - -v Status_Bar='@energy,@memory,@processes,@cpu,@disk,@net,@bluetooth,@backlight,@volume,@mpd,@weather,@datetime' \ + -v GC_Interval=1800 \ + -f <("$BIN"/khatus_gen_bar_make_status \ + -v Status_Fmt=' E=%s%% M=%d%% P=[%s %sr %sd %st %si %sz] C=[%s %s°C %srpm] D=[%s%% %s▲ %s▼] W=[%s %s▲ %s▼] B=%s *=%s%% (%s) [%s] %s°F %s ' \ + -v Status_Args='@energy_percent,@memory_percent,@processes_count_all,@processes_count_r,@processes_count_d,@processes_count_t,@processes_count_i,@processes_count_z,@cpu_loadavg,@cpu_temp,@cpu_fan_speed,@disk_space,@disk_io_w,@disk_io_r,@net_wifi:wlp3s0,@net_io_w:wlp3s0,@net_io_r:wlp3s0,@bluetooth_power,@backlight_percent,@volume_pa_sink:0,@mpd,@weather_temp_f,@datetime' \ ) \ | "$BIN"/khatus_actuate_status_bar_to_xsetroot_name \ ) \ @@ -35,8 +47,14 @@ In my `~/.xinitrc` I have something like the following: >(stdbuf -o L "$BIN"/khatus_monitor_errors \ | "$BIN"/khatus_actuate_alert_to_notify_send \ ) \ + >(stdbuf -o L "$BIN"/khatus_monitor_devices \ + | "$BIN"/khatus_actuate_alert_to_notify_send \ + ) \ + >(stdbuf -o L "$BIN"/khatus_actuate_device_add_to_automount \ + | "$BIN"/khatus_actuate_alert_to_notify_send \ + ) \ ) \ -2> >($BIN/twrap.sh >> $HOME/var/log/khatus/main.log) \ +2> >($BIN/twrap >> $KHATUS_LOGS_DIR/main.log) \ 1> /dev/null \ & ``` @@ -232,8 +250,8 @@ Redesign notes intervals at runtime (which seems like a better idea than the above in-memory DB one). -Ideas ------ +Idea grab bag +------------- - track devices: - alert when never before seen device is plugged-in -- 2.20.1 From e103315c72597a9cc9fffaaff11e04b30d1c6416 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Mon, 3 Sep 2018 15:33:38 -0400 Subject: [PATCH 09/16] Normalize alert msg --- Makefile | 11 +++-------- src/awk/exe/actuate_alert_to_notify_send.awk | 8 +++++--- src/awk/exe/actuate_device_add_to_automount.awk | 6 +++--- src/awk/exe/monitor_devices.awk | 2 +- src/awk/exe/monitor_energy.awk | 4 ++-- src/awk/exe/monitor_errors.awk | 2 +- src/awk/lib/alert.awk | 6 ------ src/awk/lib/msg_out.awk | 9 +++++++++ 8 files changed, 24 insertions(+), 24 deletions(-) delete mode 100755 src/awk/lib/alert.awk diff --git a/Makefile b/Makefile index c63c61e..5dbefc2 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,6 @@ install: clean: rm -f $(AWK_EXECUTABLES) - bin/khatus_bar: \ src/awk/exe/bar.awk \ src/awk/lib/cache.awk \ @@ -60,8 +59,7 @@ bin/khatus_actuate_alert_to_notify_send: \ bin/khatus_actuate_device_add_to_automount: \ src/awk/exe/actuate_device_add_to_automount.awk \ src/awk/lib/msg_in.awk \ - src/awk/lib/msg_out.awk \ - src/awk/lib/alert.awk + src/awk/lib/msg_out.awk $(BUILD_AWK_EXE) bin/khatus_actuate_status_bar_to_xsetroot_name: \ @@ -72,23 +70,20 @@ bin/khatus_actuate_status_bar_to_xsetroot_name: \ bin/khatus_monitor_devices: \ src/awk/exe/monitor_devices.awk \ src/awk/lib/msg_in.awk \ - src/awk/lib/msg_out.awk \ - src/awk/lib/alert.awk + src/awk/lib/msg_out.awk $(BUILD_AWK_EXE) bin/khatus_monitor_energy: \ src/awk/exe/monitor_energy.awk \ src/awk/lib/msg_in.awk \ src/awk/lib/msg_out.awk \ - src/awk/lib/alert.awk \ src/awk/lib/util.awk $(BUILD_AWK_EXE) bin/khatus_monitor_errors: \ src/awk/exe/monitor_errors.awk \ src/awk/lib/msg_in.awk \ - src/awk/lib/msg_out.awk \ - src/awk/lib/alert.awk + src/awk/lib/msg_out.awk $(BUILD_AWK_EXE) bin/khatus_parse_bluetoothctl_show: \ diff --git a/src/awk/exe/actuate_alert_to_notify_send.awk b/src/awk/exe/actuate_alert_to_notify_send.awk index f11b2f4..2cebbff 100755 --- a/src/awk/exe/actuate_alert_to_notify_send.awk +++ b/src/awk/exe/actuate_alert_to_notify_send.awk @@ -7,10 +7,12 @@ BEGIN { } $1 == "OK" && \ -$3 == "alert" { +$3 ~ /^alert/ { src = $2 - priority = $4 - subject = $5 + key = $3 + split(key, key_parts, Kfs) + priority = key_parts[2] + subject = key_parts[3] # Not just using $6 for body - because body might contain a character # identical to FS diff --git a/src/awk/exe/actuate_device_add_to_automount.awk b/src/awk/exe/actuate_device_add_to_automount.awk index 9db7e9e..d1a56aa 100755 --- a/src/awk/exe/actuate_device_add_to_automount.awk +++ b/src/awk/exe/actuate_device_add_to_automount.awk @@ -28,15 +28,15 @@ function mount_device(path, cmd, line, lines, line_count, status, i, path_mnt=line sub("^Mounted " path_dev " at ", "", path_mnt) sub("\.$", "", path_mnt) - alert("low", "successfully-mounted", path_dev " to " path_mnt) + msg_out_ok_alert("low", "successfully-mounted", path_dev " to " path_mnt) if (Execute_On_Mount) { system(Execute_On_Mount " '" path_mnt "'") } } else { - alert("hi", "unexpected-success-line", line) + msg_out_ok_alert("hi", "unexpected-success-line", line) } } } else { - alert("hi", "failed-to-mount-device", path) + msg_out_ok_alert("hi", "failed-to-mount-device", path) } } diff --git a/src/awk/exe/monitor_devices.awk b/src/awk/exe/monitor_devices.awk index a37a30c..d43f67c 100755 --- a/src/awk/exe/monitor_devices.awk +++ b/src/awk/exe/monitor_devices.awk @@ -1,5 +1,5 @@ $1 == "OK" && \ $2 == "khatus_sensor_devices" \ { - alert("low", "BlockDeviceEvent", $3 " " $4) + msg_out_ok_alert("low", "BlockDeviceEvent", $3 " " $4) } diff --git a/src/awk/exe/monitor_energy.awk b/src/awk/exe/monitor_energy.awk index 0730ec7..0d3f339 100755 --- a/src/awk/exe/monitor_energy.awk +++ b/src/awk/exe/monitor_energy.awk @@ -14,7 +14,7 @@ $3 == "line_power" { line_power_prev = line_power_curr line_power_curr = $4 if (line_power_curr == "no" && line_power_prev != "no") { - alert("low", "PowerUnplugged", "") + msg_out_ok_alert("low", "PowerUnplugged", "") } } @@ -38,7 +38,7 @@ $3 == "battery_percentage" { priority = msg[1] subject = msg[2] body = sprintf("%d%% %s", battery_percentage, msg[3]) - alert(priority, subject, body) + msg_out_ok_alert(priority, subject, body) _alerted[threshold]++ } } diff --git a/src/awk/exe/monitor_errors.awk b/src/awk/exe/monitor_errors.awk index a096db7..13130cc 100755 --- a/src/awk/exe/monitor_errors.awk +++ b/src/awk/exe/monitor_errors.awk @@ -6,5 +6,5 @@ len_head = length($1 FS $2 FS) len_body = len_line - len_head body = substr($0, len_head + 1, len_body) - alert("hi", "ERROR_IN_" src, body) + msg_out_ok_alert("hi", "ERROR_IN_" src, body) } diff --git a/src/awk/lib/alert.awk b/src/awk/lib/alert.awk deleted file mode 100755 index 5e14146..0000000 --- a/src/awk/lib/alert.awk +++ /dev/null @@ -1,6 +0,0 @@ -function alert(priority, subject, body) { - # priority : "low" | "med" | "hi" - # subject : string without spaces - # body : anything - print("OK", Module, "alert", priority, subject, body) -} diff --git a/src/awk/lib/msg_out.awk b/src/awk/lib/msg_out.awk index 1a0f813..6f5f945 100755 --- a/src/awk/lib/msg_out.awk +++ b/src/awk/lib/msg_out.awk @@ -3,6 +3,15 @@ BEGIN { Kfs = Key_fs ? Key_fs : ":" } +function msg_out_ok_alert(priority, subject, body, key, val) { + # priority : "low" | "med" | "hi" + # subject : string without spaces + # body : anything + key = "alert" Kfs priority Kfs subject + val = body + msg_out_ok(key, val) +} + function msg_out_ok(key, val) { msg_out("OK", key, val, "/dev/stdout") } -- 2.20.1 From 8482fea64a51f9a9b97895c974a88a986b42aa15 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Wed, 5 Sep 2018 16:48:23 -0400 Subject: [PATCH 10/16] Redesign message format - supports distributed khatus (adds node field) - separates messages into types (data, error, alert, log) --- Makefile | 20 +++-- README.md | 2 +- bin/khatus | 9 ++- src/awk/exe/actuate_alert_to_notify_send.awk | 23 ++---- .../exe/actuate_device_add_to_automount.awk | 15 ++-- .../actuate_status_bar_to_xsetroot_name.awk | 12 +-- src/awk/exe/bar.awk | 20 ++--- src/awk/exe/monitor_devices.awk | 11 ++- src/awk/exe/monitor_energy.awk | 35 +++++---- src/awk/exe/monitor_errors.awk | 14 ++-- src/awk/exe/parse_metar_d_output.awk | 6 +- src/awk/lib/cache.awk | 75 +++++++++---------- src/awk/lib/msg_in.awk | 38 +++++++++- src/awk/lib/msg_out.awk | 57 ++++++++++---- src/awk/lib/{util.awk => num.awk} | 16 ++-- src/awk/lib/str.awk | 23 ++++++ 16 files changed, 227 insertions(+), 149 deletions(-) rename src/awk/lib/{util.awk => num.awk} (84%) create mode 100755 src/awk/lib/str.awk diff --git a/Makefile b/Makefile index 5dbefc2..1f39234 100644 --- a/Makefile +++ b/Makefile @@ -24,9 +24,10 @@ AWK_EXECUTABLES := \ bin/khatus_parse_upower define BUILD_AWK_EXE - echo '#! $(PATH_TO_AWK) -f' > $@ && \ - echo 'BEGIN {Module = "$(notdir $@)"}' >> $@ && \ - cat $^ >> $@ && \ + echo '#! $(PATH_TO_AWK) -f' > $@ && \ + echo 'BEGIN {Node = Node ? Node : "$(shell hostname)"}' >> $@ && \ + echo 'BEGIN {Module = "$(notdir $@)"}' >> $@ && \ + cat $^ >> $@ && \ chmod +x $@ endef @@ -46,42 +47,49 @@ clean: bin/khatus_bar: \ src/awk/exe/bar.awk \ src/awk/lib/cache.awk \ + src/awk/lib/str.awk \ src/awk/lib/msg_in.awk \ src/awk/lib/msg_out.awk \ - src/awk/lib/util.awk + src/awk/lib/num.awk $(BUILD_AWK_EXE) bin/khatus_actuate_alert_to_notify_send: \ src/awk/exe/actuate_alert_to_notify_send.awk \ + src/awk/lib/str.awk \ src/awk/lib/msg_in.awk $(BUILD_AWK_EXE) bin/khatus_actuate_device_add_to_automount: \ src/awk/exe/actuate_device_add_to_automount.awk \ + src/awk/lib/str.awk \ src/awk/lib/msg_in.awk \ src/awk/lib/msg_out.awk $(BUILD_AWK_EXE) bin/khatus_actuate_status_bar_to_xsetroot_name: \ src/awk/exe/actuate_status_bar_to_xsetroot_name.awk \ + src/awk/lib/str.awk \ src/awk/lib/msg_in.awk $(BUILD_AWK_EXE) bin/khatus_monitor_devices: \ src/awk/exe/monitor_devices.awk \ + src/awk/lib/str.awk \ src/awk/lib/msg_in.awk \ src/awk/lib/msg_out.awk $(BUILD_AWK_EXE) bin/khatus_monitor_energy: \ src/awk/exe/monitor_energy.awk \ + src/awk/lib/str.awk \ src/awk/lib/msg_in.awk \ src/awk/lib/msg_out.awk \ - src/awk/lib/util.awk + src/awk/lib/num.awk $(BUILD_AWK_EXE) bin/khatus_monitor_errors: \ src/awk/exe/monitor_errors.awk \ + src/awk/lib/str.awk \ src/awk/lib/msg_in.awk \ src/awk/lib/msg_out.awk $(BUILD_AWK_EXE) @@ -124,7 +132,7 @@ bin/khatus_parse_loadavg_file: \ bin/khatus_parse_metar_d_output: \ src/awk/exe/parse_metar_d_output.awk \ src/awk/lib/msg_out.awk \ - src/awk/lib/util.awk + src/awk/lib/str.awk $(BUILD_AWK_EXE) bin/khatus_parse_mpd_status_currentsong: \ diff --git a/README.md b/README.md index 834d6ab..c02c1f8 100644 --- a/README.md +++ b/README.md @@ -258,7 +258,7 @@ Idea grab bag - report history and trends on when and how-often each device/category is plugged-in, how-long it stays plaugged-in, etc. - daemonize `khatus`, so we don't have to re-launch `X11` to re-launch `khatus` -- interoperate with other khatus instances +- interoperate with other khatus nodes - prefix machine ID to each data source (What should that ID be? Hostname? Pub key?) - fetch remote data and process locally diff --git a/bin/khatus b/bin/khatus index 747fd32..ec8270f 100755 --- a/bin/khatus +++ b/bin/khatus @@ -36,18 +36,18 @@ run_producer() { 2> >( while read line do - echo "ERROR${MSG_FS}${executable_name}${MSG_FS}$line" > "$pipe" + echo "${NODE}${MSG_FS}${executable_name}${MSG_FS}error${MSG_FS}$line" > "$pipe" done \ ) \ | while read line do - echo "OK${MSG_FS}${executable_name}${MSG_FS}$line" > "$pipe" + echo "${NODE}${MSG_FS}${executable_name}${MSG_FS}data${MSG_FS}$line" > "$pipe" done cmd_exit_code=${PIPESTATUS[0]} if [ "$cmd_exit_code" -ne 0 ] then echo - "ERROR${MSG_FS}${executable_name}${MSG_FS}NON_ZERO_EXIT_CODE${MSG_FS}$cmd_exit_code" \ + "${NODE}${MSG_FS}${executable_name}${MSG_FS}error${MSG_FS}NON_ZERO_EXIT_CODE${MSG_FS}$cmd_exit_code" \ > "$pipe" fi } @@ -87,6 +87,7 @@ fork_poller() { main() { declare -A opts=( + ["--node"]=$(hostname) ["--dir_bin"]="$HOME/bin" ["--dir_perf_logs"]='' ["--file_pipe"]=$(mktemp) @@ -160,6 +161,8 @@ main() { echo '----------------------------------------------' ) >&2 + NODE="${opts['--node']}" + screen_brightness_device_path='/sys/class/backlight' screen_brightness_device_path+="/${opts['--screen_brightness_device_name']}" diff --git a/src/awk/exe/actuate_alert_to_notify_send.awk b/src/awk/exe/actuate_alert_to_notify_send.awk index 2cebbff..a49a723 100755 --- a/src/awk/exe/actuate_alert_to_notify_send.awk +++ b/src/awk/exe/actuate_alert_to_notify_send.awk @@ -6,31 +6,22 @@ BEGIN { Display = Display ? Display : ":0" } -$1 == "OK" && \ -$3 ~ /^alert/ { - src = $2 - key = $3 - split(key, key_parts, Kfs) - priority = key_parts[2] - subject = key_parts[3] - # Not just using $6 for body - because body might contain a character - # identical to FS - len_line = length($0) - len_head = length($1 FS $2 FS $3 FS $4 FS $5 FS) - len_body = len_line - len_head - body = substr($0, len_head + 1, len_body) +$3 == "alert" { + delete msg + msg_in_parse(msg, $0) + body = msg["body"] sep = body ? "\n" : "" - body = body sep "--" src - urgency = priority + body = body sep "--" msg["node"] ":" msg["module"] + urgency = msg["priority"] sub("hi" , "critical", urgency) sub("med", "normal" , urgency) cmd = \ sprintf(\ "DISPLAY=%s notify-send -u %s %s \" %s\"", - Display, urgency, subject, body \ + Display, urgency, msg["subject"], body \ ) system(cmd) next diff --git a/src/awk/exe/actuate_device_add_to_automount.awk b/src/awk/exe/actuate_device_add_to_automount.awk index d1a56aa..9510720 100755 --- a/src/awk/exe/actuate_device_add_to_automount.awk +++ b/src/awk/exe/actuate_device_add_to_automount.awk @@ -3,11 +3,12 @@ BEGIN { Execute_On_Mount = Execute_On_Mount ? Execute_On_Mount : "" } -$1 == "OK" && \ +$1 == Node && \ $2 == "khatus_sensor_devices" && \ -$3 == "add" && \ -$4 ~ /[0-9]$/ { - mount_device($4) +$3 == "data" && \ +$4 == "add" && \ +$5 ~ /[0-9]$/ { + mount_device($5) } function mount_device(path, cmd, line, lines, line_count, status, i, @@ -28,15 +29,15 @@ function mount_device(path, cmd, line, lines, line_count, status, i, path_mnt=line sub("^Mounted " path_dev " at ", "", path_mnt) sub("\.$", "", path_mnt) - msg_out_ok_alert("low", "successfully-mounted", path_dev " to " path_mnt) + msg_out_alert_low("successfully-mounted", path_dev " to " path_mnt) if (Execute_On_Mount) { system(Execute_On_Mount " '" path_mnt "'") } } else { - msg_out_ok_alert("hi", "unexpected-success-line", line) + msg_out_alert_hi("unexpected-success-line", line) } } } else { - msg_out_ok_alert("hi", "failed-to-mount-device", path) + msg_out_alert_hi("failed-to-mount-device", path) } } diff --git a/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk b/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk index b97538b..6f87344 100755 --- a/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk +++ b/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk @@ -1,12 +1,8 @@ -$1 == "OK" && \ +$1 == Node && \ $2 == "khatus_bar" && \ $3 == "status_bar" { - # Not just using $4 for val - because val might contain a character - # identical to FS - len_line = length($0) - len_head = length($1 FS $2 FS $3 FS) - len_val = len_line - len_head - val = substr($0, len_head + 1, len_val) - system("xsetroot -name \"" val "\"") + delete msg + msg_in_parse(msg, $0) + system("xsetroot -name \"" msg["status_bar"] "\"") next } diff --git a/src/awk/exe/bar.awk b/src/awk/exe/bar.awk index 9be1adb..43126ff 100755 --- a/src/awk/exe/bar.awk +++ b/src/awk/exe/bar.awk @@ -10,18 +10,20 @@ # ----------------------------------------------------------------------------- # Input # ----------------------------------------------------------------------------- -$1 == "OK" { - cache_update() +$3 == "data" { + delete msg + msg_in_parse(msg, $0) + cache_update(msg["node"], msg["module"], msg["key"], msg["val"]) } -$1 == "OK" && \ -$2 == "khatus_sensor_datetime" { +$1 == Node && \ +$2 == "khatus_sensor_datetime" && \ +$3 == "data" { # Code for bar_make_status is expected to be passed as an # additional source file, using -f flag. - msg_out_ok("status_bar", bar_make_status()) + msg_out_status_bar(bar_make_status()) } - # ----------------------------------------------------------------------------- # Energy # ----------------------------------------------------------------------------- @@ -54,7 +56,7 @@ function bar_make_status_mem_percent( total, used, percent, percent_str) { !used["is_expired"] && \ total["value"] \ ) { - percent = util_round((used["value"] / total["value"]) * 100) + percent = num_round((used["value"] / total["value"]) * 100) percent_str = sprintf("%d", percent) } else { percent_str = "__" @@ -198,7 +200,7 @@ function bar_make_status_volume_pulseaudio_sink(sink, mu, vl, vr, show) { if (mu["value"] == "yes") {show = "X"} else if (mu["value"] == "no") {show = vl["value"] " " vr["value"]} else { - msg_out_error(\ + msg_out_log_error(\ "bar_make_status_volume_pulseaudio_sink: " sink ". ", \ "Unexpected value for 'mute' field: " mu["value"] \ ) @@ -221,7 +223,7 @@ function bar_make_status_mpd( state, status) { } else if (state["value"] == "stop") { status = bar_make_status_mpd_state_known("⬛") } else { - msg_out_error(\ + msg_out_log_error(\ "bar_make_status_mpd", \ "Unexpected value for 'state' field: " state["value"] \ ) diff --git a/src/awk/exe/monitor_devices.awk b/src/awk/exe/monitor_devices.awk index d43f67c..efb7b79 100755 --- a/src/awk/exe/monitor_devices.awk +++ b/src/awk/exe/monitor_devices.awk @@ -1,5 +1,10 @@ -$1 == "OK" && \ -$2 == "khatus_sensor_devices" \ +$2 == "khatus_sensor_devices" && \ +$3 == "data" \ { - msg_out_ok_alert("low", "BlockDeviceEvent", $3 " " $4) + delete msg + msg_in_parse(msg, $0) + msg_out_alert_low( \ + "BlockDeviceEvent", + msg["key"] " " msg["val"] " on " msg["node"]\ + ) } diff --git a/src/awk/exe/monitor_energy.awk b/src/awk/exe/monitor_energy.awk index 0d3f339..518d687 100755 --- a/src/awk/exe/monitor_energy.awk +++ b/src/awk/exe/monitor_energy.awk @@ -8,37 +8,40 @@ BEGIN { bat_alert_spec[5] = "hi|Energy_CRITICALLY_Low|CHARGE NOW!!! GO GO GO!!!" } -$1 == "OK" && \ +$1 == Node && \ $2 == "khatus_sensor_energy" && \ -$3 == "line_power" { +$3 == "data" && \ +$4 == "line_power" { line_power_prev = line_power_curr - line_power_curr = $4 + line_power_curr = $5 if (line_power_curr == "no" && line_power_prev != "no") { - msg_out_ok_alert("low", "PowerUnplugged", "") + msg_out_alert_low("PowerUnplugged", "") } } -$1 == "OK" && \ +$1 == Node && \ $2 == "khatus_sensor_energy" && \ -$3 == "battery_state" { +$3 == "data" && \ +$4 == "battery_state" { battery_state_prev = battery_state_curr - battery_state_curr = $4 + battery_state_curr = $5 } -$1 == "OK" && \ +$1 == Node && \ $2 == "khatus_sensor_energy" && \ -$3 == "battery_percentage" { +$3 == "data" && \ +$4 == "battery_percentage" { # TODO: Re-think the spec - can't rely on order of keys - battery_percentage = util_ensure_numeric($4) + battery_percentage = num_ensure_numeric($5) if (battery_state_curr == "discharging") { for (threshold in bat_alert_spec) { - threshold = util_ensure_numeric(threshold) + threshold = num_ensure_numeric(threshold) if (battery_percentage <= threshold && !_alerted[threshold]) { - split(bat_alert_spec[threshold], msg, "|") - priority = msg[1] - subject = msg[2] - body = sprintf("%d%% %s", battery_percentage, msg[3]) - msg_out_ok_alert(priority, subject, body) + split(bat_alert_spec[threshold], alert, "|") + priority = alert[1] + subject = alert[2] + body = sprintf("%d%% %s", battery_percentage, alert[3]) + msg_out_alert(priority, subject, body) _alerted[threshold]++ } } diff --git a/src/awk/exe/monitor_errors.awk b/src/awk/exe/monitor_errors.awk index 13130cc..36fd534 100755 --- a/src/awk/exe/monitor_errors.awk +++ b/src/awk/exe/monitor_errors.awk @@ -1,10 +1,6 @@ -/^ERROR/ { - src = $2 - # Not just using $3 for body - because body might contain a character - # identical to FS - len_line = length($0) - len_head = length($1 FS $2 FS) - len_body = len_line - len_head - body = substr($0, len_head + 1, len_body) - msg_out_ok_alert("hi", "ERROR_IN_" src, body) +$3 == "error" { + delete msg + msg_in_parse(msg, $0) + subject = "ERROR_IN_" msg["node"] ":" msg["module"] + msg_out_alert_hi(subject, msg["line"]) } diff --git a/src/awk/exe/parse_metar_d_output.awk b/src/awk/exe/parse_metar_d_output.awk index fa354da..82d2e29 100755 --- a/src/awk/exe/parse_metar_d_output.awk +++ b/src/awk/exe/parse_metar_d_output.awk @@ -8,15 +8,15 @@ /[A-z][a-z]+ *: / { split($0, line, ":") - key = util_strip(line[1]) - val = util_strip(line[2]) + key = str_strip(line[1]) + val = str_strip(line[2]) values[NR] = val first[key] = NR last[key] = NR } /^ +/ { - values[NR] = util_strip($0) + values[NR] = str_strip($0) last[key] = NR } diff --git a/src/awk/lib/cache.awk b/src/awk/lib/cache.awk index fbdd122..a2dd879 100755 --- a/src/awk/lib/cache.awk +++ b/src/awk/lib/cache.awk @@ -31,86 +31,79 @@ BEGIN { _scale["khatus_sensor_net_addr_io", "bytes_read" ] = 1 / _bytes_per_mb } -function cache_update( src, key, val, len_line, len_head, len_val, time) { - src = $2 - key = $3 - # Not just using $4 for val - because an unstructured value (like name of a - # song) might contain a character identical to FS - len_line = length($0) - len_head = length($1 FS $2 FS $3 FS) - len_val = len_line - len_head - val = substr($0, len_head + 1, len_val) - val = cache_maybe_total_to_diff(src, key, val) - val = cache_maybe_scale(src, key, val) - _cache[src, key] = val +function cache_update(node, module, key, val, time) { + # TODO: Use node value + val = cache_maybe_total_to_diff(module, key, val) + val = cache_maybe_scale(module, key, val) + _cache[module, key] = val time = cache_get_time() - _cache_mtime[src, key] = time + _cache_mtime[module, key] = time if (time % GC_Interval == 0) { cache_gc() } } -function cache_get(result, src, key, ttl, time, age, is_expired) { +function cache_get(result, module, key, ttl, time, age, is_expired) { time = cache_get_time() - _cache_atime[src, key] = time - age = time - _cache_mtime[src, key] + _cache_atime[module, key] = time + age = time - _cache_mtime[module, key] result["is_expired"] = ttl && age > ttl # ttl = 0 => forever - result["value"] = _cache[src, key] + result["value"] = _cache[module, key] } function cache_res_fmt_or_def(result, format, default) { return result["is_expired"] ? default : sprintf(format, result["value"]) } -function cache_get_fmt_def(src, key, ttl, format, default, result) { +function cache_get_fmt_def(module, key, ttl, format, default, result) { default = default ? default : "--" - cache_get(result, src, key, ttl) + cache_get(result, module, key, ttl) return cache_res_fmt_or_def(result, format, default) } -function cache_get_time( src, key, time) { - src = "khatus_sensor_datetime" +function cache_get_time( module, key, time) { + module = "khatus_sensor_datetime" key = "epoch" - time = _cache[src, key] - _cache_atime[src, key] = time + time = _cache[module, key] + _cache_atime[module, key] = time return time } -function cache_gc( src_and_key, parts, src, key, unused_for) { - for (src_and_key in _cache) { - split(src_and_key, parts, SUBSEP) - src = parts[1] +function cache_gc( module_and_key, parts, module, key, unused_for) { + for (module_and_key in _cache) { + split(module_and_key, parts, SUBSEP) + module = parts[1] key = parts[2] - val = _cache[src, key] - unused_for = cache_get_time() - _cache_atime[src, key] + val = _cache[module, key] + unused_for = cache_get_time() - _cache_atime[module, key] if (unused_for > GC_Interval) { - msg_out_info(\ + msg_out_log_info(\ "cache_gc", sprintf(\ - "Deleting unused data SRC=%s KEY=%s VAL=%s", - src, key, val\ + "Deleting unused data MODULE=%s KEY=%s VAL=%s", + module, key, val\ ) \ ) - delete _cache[src, key] + delete _cache[module, key] } } } -function cache_maybe_total_to_diff(src, key, val, key_parts) { +function cache_maybe_total_to_diff(module, key, val, key_parts) { split(key, key_parts, Kfs) - if (_total_to_diff[src, key_parts[1]]) { - _prev[src, key] = _curr[src, key] - _curr[src, key] = val - return (_curr[src, key] - _prev[src, key]) + if (_total_to_diff[module, key_parts[1]]) { + _prev[module, key] = _curr[module, key] + _curr[module, key] = val + return (_curr[module, key] - _prev[module, key]) } else { return val } } -function cache_maybe_scale(src, key, val, key_parts) { +function cache_maybe_scale(module, key, val, key_parts) { split(key, key_parts, Kfs) - if ((src SUBSEP key_parts[1]) in _scale) { - return val * _scale[src, key_parts[1]] + if ((module SUBSEP key_parts[1]) in _scale) { + return val * _scale[module, key_parts[1]] } else { return val } diff --git a/src/awk/lib/msg_in.awk b/src/awk/lib/msg_in.awk index d1f62d6..cda89e8 100755 --- a/src/awk/lib/msg_in.awk +++ b/src/awk/lib/msg_in.awk @@ -1,4 +1,38 @@ BEGIN { - FS = Msg_fs ? Msg_fs : "|" - Kfs = Key_fs ? Key_fs : ":" + FS1 = "|" # Fiels separator, level 1 (record to fields) + FS2 = ":" # Fiels separator, level 2 (field to subfields) + + FS = FS1 + Kfs = FS2 +} + +function msg_in_parse(msg, line, fields, type) { + split(line, fields, FS1) + msg["node"] = fields[1] + msg["module"] = fields[2] + type = fields[3] + msg["type"] = type + + if (type == "data") { + msg["key"] = fields[4] + msg["val"] = str_tail(str_join(fields, 1, 4, FS1) FS1, line) + } else if (type == "error") { + msg["line"] = str_tail(str_join(fields, 1, 3, FS1) FS1, line) + } else if (type == "alert") { + msg["priority"] = fields[4] + msg["subject"] = fields[5] + msg["body"] = str_tail(str_join(fields, 1, 5, FS1) FS1, line) + } else if (type == "log") { + msg["location"] = fields[4] + msg["level"] = fields[5] + msg["msg"] = str_tail(str_join(fields, 1, 5, FS1) FS1, line) + } else if (type == "status_bar") { + msg["status_bar"] = str_tail(str_join(fields, 1, 3, FS1) FS1, line) + } else { + msg_out_log_error(\ + "msg_in_parse", + "Unexpected msg type: " type " in given input line: " line \ + ) + exit 1 + } } diff --git a/src/awk/lib/msg_out.awk b/src/awk/lib/msg_out.awk index 6f5f945..24393c6 100755 --- a/src/awk/lib/msg_out.awk +++ b/src/awk/lib/msg_out.awk @@ -1,29 +1,58 @@ BEGIN { - OFS = Msg_fs ? Msg_fs : "|" - Kfs = Key_fs ? Key_fs : ":" + FS1 = "|" # Fiels separator, level 1 (record to fields) + FS2 = ":" # Fiels separator, level 2 (field to subfields + + OFS = FS1 + Kfs = FS2 +} + +# ----------------------------------------------------------------------------- +# alert +# ----------------------------------------------------------------------------- +function msg_out_alert_low(subject, body) { + msg_out_alert("low", subject, body) +} + +function msg_out_alert_med(subject, body) { + msg_out_alert("med", subject, body) } -function msg_out_ok_alert(priority, subject, body, key, val) { +function msg_out_alert_hi(subject, body) { + msg_out_alert("hi", subject, body) +} + +function msg_out_alert(priority, subject, body) { # priority : "low" | "med" | "hi" # subject : string without spaces # body : anything - key = "alert" Kfs priority Kfs subject - val = body - msg_out_ok(key, val) + print(Node, Module, "alert", priority, subject, body) +} + +# ----------------------------------------------------------------------------- +# log +# ----------------------------------------------------------------------------- +function msg_out_log_info(location, msg) { + msg_out_log("info", location, msg) } -function msg_out_ok(key, val) { - msg_out("OK", key, val, "/dev/stdout") +function msg_out_log_error(location, msg) { + msg_out_log("error", location, msg) } -function msg_out_info(location, msg) { - msg_out("INFO", location, msg, "/dev/stderr") +function msg_out_log(level, location, msg) { + print(Node, Module, "log", location, level, msg) > "/dev/stderr" } -function msg_out_error(location, msg) { - msg_out("ERROR", location, msg, "/dev/stderr") +# ----------------------------------------------------------------------------- +# status_bar +# ----------------------------------------------------------------------------- +function msg_out_status_bar(bar) { + print(Node, Module, "status_bar", bar) } -function msg_out(status, key, val, channel) { - print(status, Module, key, val) > channel +# ----------------------------------------------------------------------------- +# data +# ----------------------------------------------------------------------------- +function msg_out_data(key, val) { + print(Node, Module, "data", key, val) } diff --git a/src/awk/lib/util.awk b/src/awk/lib/num.awk similarity index 84% rename from src/awk/lib/util.awk rename to src/awk/lib/num.awk index b7a92e6..4c22f9d 100755 --- a/src/awk/lib/util.awk +++ b/src/awk/lib/num.awk @@ -1,20 +1,14 @@ -function util_strip(s) { - sub("^ *", "", s) - sub(" *$", "", s) - return s -} - -function util_round(n) { +function num_round(n) { return int(n + 0.5) } -function util_ensure_numeric(n) { +function num_ensure_numeric(n) { return n + 0 } -#------------------------------------ -# Why do we need util_ensure_numeric? -#------------------------------------ +#----------------------------------- +# Why do we need num_ensure_numeric? +#----------------------------------- # awk appears to be guessing the type of an inputted scalar based on usage, so # if we read-in a number, but did not use it in any numeric operations, but did # use as a string (even in just a format string!) - it will be treated as a diff --git a/src/awk/lib/str.awk b/src/awk/lib/str.awk new file mode 100755 index 0000000..422ff66 --- /dev/null +++ b/src/awk/lib/str.awk @@ -0,0 +1,23 @@ +function str_join(array, from, to, sep_given, str, sep, i) { + str = "" + sep = "" + for (i=from; i<=to; i++) { + str = str sep array[i] + sep = sep_given + } + return str +} + +function str_tail(head, full, tail, len_tail, len_head, len_full) { + len_full = length(full) + len_head = length(head) + len_tail = len_full - len_head + tail = substr(full, len_head + 1, len_tail) + return tail +} + +function str_strip(s) { + sub("^ *", "", s) + sub(" *$", "", s) + return s +} -- 2.20.1 From c6a7396ebc93cec32a1465d878ac9d36465dcb19 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Mon, 3 Sep 2018 15:47:12 -0400 Subject: [PATCH 11/16] Implement a basic cache dumper --- .gitignore | 6 +- Makefile | 16 +++++- sanity_check | 1 + src/ocaml/exe/khatus_cache_dumper.ml | 76 ++++++++++++++++++++++++++ src/ocaml/exe/khatus_cache_dumper.mli | 0 src/ocaml/lib/khatus.ml | 4 ++ src/ocaml/lib/khatus_cache.ml | 52 ++++++++++++++++++ src/ocaml/lib/khatus_cache.mli | 16 ++++++ src/ocaml/lib/khatus_msg.ml | 70 ++++++++++++++++++++++++ src/ocaml/lib/khatus_msg.mli | 20 +++++++ src/ocaml/lib/khatus_msg_parser.mli | 8 +++ src/ocaml/lib/khatus_msg_parser.mll | 79 +++++++++++++++++++++++++++ src/ocaml/lib/khatus_time.ml | 24 ++++++++ src/ocaml/lib/khatus_time.mli | 17 ++++++ 14 files changed, 386 insertions(+), 3 deletions(-) create mode 100644 src/ocaml/exe/khatus_cache_dumper.ml create mode 100644 src/ocaml/exe/khatus_cache_dumper.mli create mode 100644 src/ocaml/lib/khatus.ml create mode 100644 src/ocaml/lib/khatus_cache.ml create mode 100644 src/ocaml/lib/khatus_cache.mli create mode 100644 src/ocaml/lib/khatus_msg.ml create mode 100644 src/ocaml/lib/khatus_msg.mli create mode 100644 src/ocaml/lib/khatus_msg_parser.mli create mode 100644 src/ocaml/lib/khatus_msg_parser.mll create mode 100644 src/ocaml/lib/khatus_time.ml create mode 100644 src/ocaml/lib/khatus_time.mli diff --git a/.gitignore b/.gitignore index f01981c..7d4b4de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ -data/ -bin/khatus_bar +_build/ bin/khatus_actuate_alert_to_notify_send bin/khatus_actuate_device_add_to_automount bin/khatus_actuate_status_bar_to_xsetroot_name +bin/khatus_bar +bin/khatus_dashboard bin/khatus_monitor_devices bin/khatus_monitor_energy bin/khatus_monitor_errors @@ -20,3 +21,4 @@ bin/khatus_parse_ps bin/khatus_parse_sys_block_stat bin/khatus_parse_udevadm_monitor_block bin/khatus_parse_upower +data/ diff --git a/Makefile b/Makefile index 1f39234..54353de 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,8 @@ AWK_EXECUTABLES := \ bin/khatus_parse_sys_block_stat \ bin/khatus_parse_udevadm_monitor_block \ bin/khatus_parse_upower +OCAML_EXECUTABLES := \ + bin/khatus_dashboard define BUILD_AWK_EXE echo '#! $(PATH_TO_AWK) -f' > $@ && \ @@ -36,14 +38,18 @@ endef install \ clean -build: $(AWK_EXECUTABLES) +build: $(AWK_EXECUTABLES) $(OCAML_EXECUTABLES) install: $(foreach filename,$(wildcard bin/*),cp -p "$(filename)" "$(PREFIX)/$(filename)"; ) clean: rm -f $(AWK_EXECUTABLES) + rm -f $(OCAML_EXECUTABLES) +#----------------------------------------------------------------------------- +# AWK +#----------------------------------------------------------------------------- bin/khatus_bar: \ src/awk/exe/bar.awk \ src/awk/lib/cache.awk \ @@ -164,3 +170,11 @@ bin/khatus_parse_upower: \ src/awk/exe/parse_upower.awk \ src/awk/lib/msg_out.awk $(BUILD_AWK_EXE) + +#----------------------------------------------------------------------------- +# OCaml +#----------------------------------------------------------------------------- +bin/khatus_cache_dumper: src/ocaml/exe/khatus_cache_dumper.ml + ocamlbuild -cflags '-w A' -pkg unix -I src/ocaml/exe -I src/ocaml/lib khatus_cache_dumper.byte + mv _build/src/ocaml/exe/khatus_cache_dumper.byte bin/khatus_cache_dumper + rm -f khatus_cache_dumper.byte diff --git a/sanity_check b/sanity_check index 09fc142..8fb8a8a 100755 --- a/sanity_check +++ b/sanity_check @@ -13,6 +13,7 @@ -v Status_Args='@energy_percent,@memory_percent,@processes_count_all,@processes_count_r,@processes_count_d,@processes_count_t,@processes_count_i,@processes_count_z,@cpu_loadavg,@cpu_temp,@cpu_fan_speed,@disk_space,@disk_io_w,@disk_io_r,@net_wifi:wlp3s0,@net_io_w:wlp3s0,@net_io_r:wlp3s0,@bluetooth_power,@backlight_percent,@volume_pa_sink:0,@mpd,@weather_temp_f,@datetime' \ ) \ ) \ + >(stdbuf -o L ./bin/khatus_cache_dumper $(hostname) 5 "$PWD/data") \ >(stdbuf -o L ./bin/khatus_monitor_energy) \ >(stdbuf -o L ./bin/khatus_monitor_errors) \ >(stdbuf -o L ./bin/khatus_monitor_devices) \ diff --git a/src/ocaml/exe/khatus_cache_dumper.ml b/src/ocaml/exe/khatus_cache_dumper.ml new file mode 100644 index 0000000..e51243e --- /dev/null +++ b/src/ocaml/exe/khatus_cache_dumper.ml @@ -0,0 +1,76 @@ +open Printf +open Khatus + +let modul = __MODULE__ + +let (/) = Filename.concat + +let mkdir_p dir = + match Sys.command("mkdir -p " ^ dir) with + | 0 -> () + | n -> + failwith + (sprintf "Failed to create directory: %S. mkdir status: %d\n" dir n) + +let gzip path = + match Sys.command("gzip " ^ path) with + | 0 -> () + | n -> + failwith + (sprintf "Failed to gzip path: %S. gzip status: %d\n" path n) + +let main ~node ~cache ~dump_interval:interval ~dump_directory = + mkdir_p dump_directory; + let dump_filename = dump_directory / "khatus-cache-dump.psv.gz" in + let rec loop ~time ~time_dumped = + (match read_line () with + | exception End_of_file -> + () + | line -> + (match Msg_parser.parse_msg (Lexing.from_string line) with + | Ok msg -> + let time = Msg.next_time msg ~node ~time in + Cache.update_if_data cache ~msg ~time; + if (Time.Span.is_gt_or_eq (Time.diff time_dumped time) interval) + then + ( + let (tmp_filename, oc) = + Filename.open_temp_file "khatus-cache" "dump" + in + Cache.dump cache ~node ~modul ~oc; + close_out oc; + gzip tmp_filename; + Sys.rename (tmp_filename ^ ".gz") dump_filename; + loop ~time ~time_dumped:time + ) + else + loop ~time ~time_dumped + | Error e -> + let e = + match e with + | `Bad_format_of_msg_head -> "Bad_format_of_msg_head" + | `Bad_format_of_msg_content -> "Bad_format_of_msg_content" + in + eprintf + "%s\n%!" + Msg.(to_string + { node + ; modul + ; content = Log + { location = "main:loop" + ; level = `error + ; msg = sprintf "Parse error %s in %s" e line + } + }); + loop ~time ~time_dumped + ) + ) + in + loop ~time:Time.init ~time_dumped:Time.init + +let () = + main + ~node:(Sys.argv.(1)) + ~dump_interval:(Time.Span.of_string Sys.argv.(2)) + ~dump_directory:(Sys.argv.(3)) + ~cache:(Cache.create ()) diff --git a/src/ocaml/exe/khatus_cache_dumper.mli b/src/ocaml/exe/khatus_cache_dumper.mli new file mode 100644 index 0000000..e69de29 diff --git a/src/ocaml/lib/khatus.ml b/src/ocaml/lib/khatus.ml new file mode 100644 index 0000000..bd01385 --- /dev/null +++ b/src/ocaml/lib/khatus.ml @@ -0,0 +1,4 @@ +module Cache = Khatus_cache +module Msg = Khatus_msg +module Msg_parser = Khatus_msg_parser +module Time = Khatus_time diff --git a/src/ocaml/lib/khatus_cache.ml b/src/ocaml/lib/khatus_cache.ml new file mode 100644 index 0000000..698d20b --- /dev/null +++ b/src/ocaml/lib/khatus_cache.ml @@ -0,0 +1,52 @@ +module Hashtbl = MoreLabels.Hashtbl + +module Msg = Khatus_msg +module Time = Khatus_time + +type t = + { values : ((string * string * string list), string) Hashtbl.t + ; mtimes : ((string * string * string list), Time.t) Hashtbl.t + } + +let create () = + { values = Hashtbl.create 256 + ; mtimes = Hashtbl.create 256 + } + +let update {values; mtimes} ~node ~modul ~key ~value:data ~time = + let key = (node, modul, key) in + Hashtbl.replace values ~key ~data; + Hashtbl.replace mtimes ~key ~data:time + +let update_if_data t ~msg ~time = + match msg with + | Msg.({content = Data {key; value}; node; modul}) -> + update t ~node ~modul ~key ~value ~time + | {Msg.content = Msg.Alert _; _} + | {Msg.content = Msg.Cache _; _} + | {Msg.content = Msg.Error _; _} + | {Msg.content = Msg.Log _; _} + | {Msg.content = Msg.Status_bar _; _} + -> + () + +let dump {values; mtimes} ~node ~modul ~oc = + Hashtbl.iter values ~f:(fun ~key ~data:value -> + let mtime = + match Hashtbl.find_opt mtimes key with + | Some mtime -> mtime + | None -> assert false (* Implies update was incorrect *) + in + let (node', modul', key) = key in + let msg = + Msg.(to_string + { node + ; modul + ; content = Cache {mtime; node = node'; modul = modul'; key; value} + } + ) + in + output_string + oc + (msg ^ "\n") + ) diff --git a/src/ocaml/lib/khatus_cache.mli b/src/ocaml/lib/khatus_cache.mli new file mode 100644 index 0000000..f6c951e --- /dev/null +++ b/src/ocaml/lib/khatus_cache.mli @@ -0,0 +1,16 @@ +type t + +val create : unit -> t + +val update + : t + -> node : string + -> modul : string + -> key : (string list) + -> value : string + -> time : Khatus_time.t + -> unit + +val update_if_data : t -> msg:Khatus_msg.t -> time:Khatus_time.t -> unit + +val dump : t -> node:string -> modul:string -> oc:out_channel -> unit diff --git a/src/ocaml/lib/khatus_msg.ml b/src/ocaml/lib/khatus_msg.ml new file mode 100644 index 0000000..cd9fd86 --- /dev/null +++ b/src/ocaml/lib/khatus_msg.ml @@ -0,0 +1,70 @@ +module Time = Khatus_time + +type content = + | Alert of {priority : [`low | `med | `hi]; subject : string; body : string} + | Data of {key : string list; value : string} + | Cache of + { mtime : Time.t + ; node : string + ; modul : string + ; key : string list + ; value : string + } + | Error of string + | Log of {location : string; level : [`info | `error]; msg : string} + | Status_bar of string + +type t = + {node : string; modul : string; content : content} + +let sep_1 = "|" +let sep_2 = ":" + +let to_string {node; modul; content} = + match content with + | Alert {priority; subject; body} -> + let priority = + match priority with + | `hi -> "hi" + | `med -> "med" + | `low -> "low" + in + String.concat sep_1 [node; modul; "alert"; priority; subject; body] + | Data {key; value} -> + let key = String.concat sep_2 key in + String.concat sep_1 [node; modul; "data"; key; value] + | Cache {mtime; node=node'; modul=modul'; key; value} -> + let key = String.concat sep_2 key in + let mtime = Time.to_string mtime in + String.concat + sep_1 + [node; modul; "cache"; mtime; node'; modul'; key; value] + | Error text -> + String.concat sep_1 [node; modul; "error"; text] + | Log {location; level; msg} -> + let level = + match level with + | `info -> "info" + | `error -> "error" + in + String.concat sep_1 [node; modul; "log"; location; level; msg] + | Status_bar text -> + String.concat sep_1 [node; modul; "status_bar"; text] + +let next_time t ~node ~time:time0 = + match t with + | { modul = "khatus_sensor_datetime" + ; content = Data {key = ["epoch"]; value = time1} + ; node = node' + } when node' = node -> + (* TODO: Going forawrd, perhaps throwing exceptions is the wrong way. *) + (* TODO: Should we check this one at msg parse time? *) + Time.of_string time1 + | {content = Data _; _} + | {content = Alert _; _} + | {content = Cache _; _} + | {content = Error _; _} + | {content = Log _; _} + | {content = Status_bar _; _} + -> + time0 diff --git a/src/ocaml/lib/khatus_msg.mli b/src/ocaml/lib/khatus_msg.mli new file mode 100644 index 0000000..7f89c2b --- /dev/null +++ b/src/ocaml/lib/khatus_msg.mli @@ -0,0 +1,20 @@ +type content = + | Alert of {priority : [`low | `med | `hi]; subject : string; body : string} + | Data of {key : string list; value : string} + | Cache of + { mtime : Khatus_time.t + ; node : string + ; modul : string + ; key : string list + ; value : string + } + | Error of string + | Log of {location : string; level : [`info | `error]; msg : string} + | Status_bar of string + +type t = + {node : string; modul : string; content : content} + +val to_string : t -> string + +val next_time : t -> node:string -> time:Khatus_time.t -> Khatus_time.t diff --git a/src/ocaml/lib/khatus_msg_parser.mli b/src/ocaml/lib/khatus_msg_parser.mli new file mode 100644 index 0000000..f177b28 --- /dev/null +++ b/src/ocaml/lib/khatus_msg_parser.mli @@ -0,0 +1,8 @@ +val parse_msg + : Lexing.lexbuf + -> + ( Khatus_msg.t + , [ `Bad_format_of_msg_head + | `Bad_format_of_msg_content + ] + ) result diff --git a/src/ocaml/lib/khatus_msg_parser.mll b/src/ocaml/lib/khatus_msg_parser.mll new file mode 100644 index 0000000..2015f77 --- /dev/null +++ b/src/ocaml/lib/khatus_msg_parser.mll @@ -0,0 +1,79 @@ +{ + module Msg = Khatus_msg + module Time = Khatus_time + let sep_2 = ':' +} + +let alphnumdash = ['a'-'z' 'A'-'Z' '0'-'9' '_' '-']+ +let snake = ['a'-'z' '_']+ + +let sep_1 = '|' +let node = alphnumdash +let modul = snake +let key = ['a'-'z' 'A'-'Z' '0'-'9' '_' '-' ':']+ +let level = ("info" | "error") +let priority = ("low" | "med" | "hi") +let subject = alphnumdash + +rule parse_msg = parse + | (node as node) sep_1 (modul as modul) sep_1 { + match parse_content lexbuf with + | Ok content -> Ok Msg.({node; modul; content : content}) + | (Error _) as e -> e + } + | _ { + parse_msg lexbuf + } + | eof { + Error (`Bad_format_of_msg_head) + } + +and parse_content = parse + | "status_bar" sep_1 { + Ok (Msg.Status_bar (tl lexbuf)) + } + | "cache" + sep_1 (['0'-'9']+ as mtime) + sep_1 (node as node) + sep_1 (modul as modul) + sep_1 (key as key) + sep_1 + { + let key = String.split_on_char sep_2 key in + let mtime = Time.of_string mtime in + Ok (Msg.Cache {mtime; node; modul; key; value = tl lexbuf}) + } + | "data" sep_1 (key as key) sep_1 { + Ok (Msg.Data {key = String.split_on_char sep_2 key; value = tl lexbuf}) + } + | "error" sep_1 { + Ok (Msg.Error (tl lexbuf)) + } + | "alert" sep_1 (priority as priority) (subject as subject) sep_1 { + let priority = + match priority with + | "low" -> `low + | "med" -> `med + | "hi" -> `hi + | _ -> assert false + in + Ok (Msg.Alert {priority; subject; body = tl lexbuf}) + } + | "log" sep_1 (snake as location) (level as level) sep_1 { + let level = + match level with + | "info" -> `info + | "error" -> `error + | _ -> assert false + in + Ok (Msg.Log {location; level; msg = tl lexbuf}) + } + | _ { + parse_content lexbuf + } + | eof { + Error (`Bad_format_of_msg_content) + } + +and tl = parse + | (_* as tail) eof {tail} diff --git a/src/ocaml/lib/khatus_time.ml b/src/ocaml/lib/khatus_time.ml new file mode 100644 index 0000000..cf6538a --- /dev/null +++ b/src/ocaml/lib/khatus_time.ml @@ -0,0 +1,24 @@ +module Span = struct + type t = float + + let of_string s = + float_of_string s + + let is_gt_or_eq t1 t2 = + t1 >= t2 +end + +type t = float + +let init = 0.0 + +let diff t0 t1 = + t1 -. t0 + +let to_string t = + Printf.sprintf "%f" t + |> String.split_on_char '.' + |> List.hd + +let of_string s = + float_of_string s diff --git a/src/ocaml/lib/khatus_time.mli b/src/ocaml/lib/khatus_time.mli new file mode 100644 index 0000000..9f930af --- /dev/null +++ b/src/ocaml/lib/khatus_time.mli @@ -0,0 +1,17 @@ +module Span : sig + type t + + val of_string : string -> t + + val is_gt_or_eq : t -> t -> bool +end + +type t + +val init : t + +val diff : t -> t -> Span.t + +val to_string : t -> string + +val of_string : string -> t -- 2.20.1 From 91ee40f32a8ab133c8fd2119c052bc02bf32bae2 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Thu, 6 Sep 2018 20:45:22 -0400 Subject: [PATCH 12/16] Move remaining code out of bin and reserve it for built files from now on --- .gitignore | 23 +-------- Makefile | 50 +++++++++++++++++-- bin/khatus => src/bash/exe/khatus.sh | 0 .../bash/exe/khatus_gen_bar_make_status.sh | 0 .../bash/exe/khatus_sensor_bluetooth_power.sh | 0 .../bash/exe/khatus_sensor_datetime.sh | 0 .../bash/exe/khatus_sensor_devices.sh | 0 .../bash/exe/khatus_sensor_disk_io.sh | 0 .../bash/exe/khatus_sensor_disk_space.sh | 0 .../bash/exe/khatus_sensor_energy.sh | 0 .../bash/exe/khatus_sensor_fan.sh | 0 .../bash/exe/khatus_sensor_loadavg.sh | 0 .../bash/exe/khatus_sensor_memory.sh | 0 .../bash/exe/khatus_sensor_mpd.sh | 0 .../bash/exe/khatus_sensor_net_addr_io.sh | 0 .../bash/exe/khatus_sensor_net_wifi_status.sh | 0 .../bash/exe/khatus_sensor_procs.sh | 0 .../exe/khatus_sensor_screen_brightness.sh | 0 .../bash/exe/khatus_sensor_temperature.sh | 0 .../bash/exe/khatus_sensor_volume.sh | 0 .../bash/exe/khatus_sensor_weather.sh | 0 21 files changed, 47 insertions(+), 26 deletions(-) rename bin/khatus => src/bash/exe/khatus.sh (100%) mode change 100755 => 100644 rename bin/khatus_gen_bar_make_status => src/bash/exe/khatus_gen_bar_make_status.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_bluetooth_power => src/bash/exe/khatus_sensor_bluetooth_power.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_datetime => src/bash/exe/khatus_sensor_datetime.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_devices => src/bash/exe/khatus_sensor_devices.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_disk_io => src/bash/exe/khatus_sensor_disk_io.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_disk_space => src/bash/exe/khatus_sensor_disk_space.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_energy => src/bash/exe/khatus_sensor_energy.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_fan => src/bash/exe/khatus_sensor_fan.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_loadavg => src/bash/exe/khatus_sensor_loadavg.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_memory => src/bash/exe/khatus_sensor_memory.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_mpd => src/bash/exe/khatus_sensor_mpd.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_net_addr_io => src/bash/exe/khatus_sensor_net_addr_io.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_net_wifi_status => src/bash/exe/khatus_sensor_net_wifi_status.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_procs => src/bash/exe/khatus_sensor_procs.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_screen_brightness => src/bash/exe/khatus_sensor_screen_brightness.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_temperature => src/bash/exe/khatus_sensor_temperature.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_volume => src/bash/exe/khatus_sensor_volume.sh (100%) mode change 100755 => 100644 rename bin/khatus_sensor_weather => src/bash/exe/khatus_sensor_weather.sh (100%) mode change 100755 => 100644 diff --git a/.gitignore b/.gitignore index 7d4b4de..271527f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,3 @@ _build/ -bin/khatus_actuate_alert_to_notify_send -bin/khatus_actuate_device_add_to_automount -bin/khatus_actuate_status_bar_to_xsetroot_name -bin/khatus_bar -bin/khatus_dashboard -bin/khatus_monitor_devices -bin/khatus_monitor_energy -bin/khatus_monitor_errors -bin/khatus_parse_bluetoothctl_show -bin/khatus_parse_df_pcent -bin/khatus_parse_fan_file -bin/khatus_parse_free -bin/khatus_parse_ip_addr -bin/khatus_parse_iwconfig -bin/khatus_parse_loadavg_file -bin/khatus_parse_metar_d_output -bin/khatus_parse_mpd_status_currentsong -bin/khatus_parse_pactl_list_sinks -bin/khatus_parse_ps -bin/khatus_parse_sys_block_stat -bin/khatus_parse_udevadm_monitor_block -bin/khatus_parse_upower +bin/ data/ diff --git a/Makefile b/Makefile index 54353de..b9ecf04 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +MAKEFLAGS := --no-builtin-rules + PREFIX := $(HOME) PATH_TO_AWK := /usr/bin/awk AWK_EXECUTABLES := \ @@ -22,8 +24,30 @@ AWK_EXECUTABLES := \ bin/khatus_parse_sys_block_stat \ bin/khatus_parse_udevadm_monitor_block \ bin/khatus_parse_upower +BASH_EXECUTABLE_NAMES := \ + khatus \ + khatus_gen_bar_make_status \ + khatus_sensor_bluetooth_power \ + khatus_sensor_datetime \ + khatus_sensor_devices \ + khatus_sensor_disk_io \ + khatus_sensor_disk_space \ + khatus_sensor_energy \ + khatus_sensor_fan \ + khatus_sensor_loadavg \ + khatus_sensor_memory \ + khatus_sensor_mpd \ + khatus_sensor_net_addr_io \ + khatus_sensor_net_wifi_status \ + khatus_sensor_procs \ + khatus_sensor_screen_brightness \ + khatus_sensor_temperature \ + khatus_sensor_volume \ + khatus_sensor_weather +BASH_EXECUTABLES := $(foreach exe,$(BASH_EXECUTABLE_NAMES),bin/$(exe)) OCAML_EXECUTABLES := \ - bin/khatus_dashboard + bin/khatus_cache_dumper +EXECUTABLES := $(AWK_EXECUTABLES) $(BASH_EXECUTABLES) $(OCAML_EXECUTABLES) define BUILD_AWK_EXE echo '#! $(PATH_TO_AWK) -f' > $@ && \ @@ -33,19 +57,37 @@ define BUILD_AWK_EXE chmod +x $@ endef +define BUILD_BASH_EXE + cat $^ > $@ && \ + chmod +x $@ +endef + +define GEN_BASH_EXE_RULE +bin/$(1) : src/bash/exe/$(1).sh + $$(BUILD_BASH_EXE) +endef + .PHONY: \ build \ install \ clean -build: $(AWK_EXECUTABLES) $(OCAML_EXECUTABLES) +build: | bin +build: $(EXECUTABLES) install: $(foreach filename,$(wildcard bin/*),cp -p "$(filename)" "$(PREFIX)/$(filename)"; ) clean: - rm -f $(AWK_EXECUTABLES) - rm -f $(OCAML_EXECUTABLES) + rm -rf bin + +bin: + mkdir -p bin + +#----------------------------------------------------------------------------- +# Bash +#----------------------------------------------------------------------------- +$(foreach exe,$(BASH_EXECUTABLE_NAMES),$(eval $(call GEN_BASH_EXE_RULE,$(exe)))) #----------------------------------------------------------------------------- # AWK diff --git a/bin/khatus b/src/bash/exe/khatus.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus rename to src/bash/exe/khatus.sh diff --git a/bin/khatus_gen_bar_make_status b/src/bash/exe/khatus_gen_bar_make_status.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_gen_bar_make_status rename to src/bash/exe/khatus_gen_bar_make_status.sh diff --git a/bin/khatus_sensor_bluetooth_power b/src/bash/exe/khatus_sensor_bluetooth_power.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_bluetooth_power rename to src/bash/exe/khatus_sensor_bluetooth_power.sh diff --git a/bin/khatus_sensor_datetime b/src/bash/exe/khatus_sensor_datetime.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_datetime rename to src/bash/exe/khatus_sensor_datetime.sh diff --git a/bin/khatus_sensor_devices b/src/bash/exe/khatus_sensor_devices.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_devices rename to src/bash/exe/khatus_sensor_devices.sh diff --git a/bin/khatus_sensor_disk_io b/src/bash/exe/khatus_sensor_disk_io.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_disk_io rename to src/bash/exe/khatus_sensor_disk_io.sh diff --git a/bin/khatus_sensor_disk_space b/src/bash/exe/khatus_sensor_disk_space.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_disk_space rename to src/bash/exe/khatus_sensor_disk_space.sh diff --git a/bin/khatus_sensor_energy b/src/bash/exe/khatus_sensor_energy.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_energy rename to src/bash/exe/khatus_sensor_energy.sh diff --git a/bin/khatus_sensor_fan b/src/bash/exe/khatus_sensor_fan.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_fan rename to src/bash/exe/khatus_sensor_fan.sh diff --git a/bin/khatus_sensor_loadavg b/src/bash/exe/khatus_sensor_loadavg.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_loadavg rename to src/bash/exe/khatus_sensor_loadavg.sh diff --git a/bin/khatus_sensor_memory b/src/bash/exe/khatus_sensor_memory.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_memory rename to src/bash/exe/khatus_sensor_memory.sh diff --git a/bin/khatus_sensor_mpd b/src/bash/exe/khatus_sensor_mpd.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_mpd rename to src/bash/exe/khatus_sensor_mpd.sh diff --git a/bin/khatus_sensor_net_addr_io b/src/bash/exe/khatus_sensor_net_addr_io.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_net_addr_io rename to src/bash/exe/khatus_sensor_net_addr_io.sh diff --git a/bin/khatus_sensor_net_wifi_status b/src/bash/exe/khatus_sensor_net_wifi_status.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_net_wifi_status rename to src/bash/exe/khatus_sensor_net_wifi_status.sh diff --git a/bin/khatus_sensor_procs b/src/bash/exe/khatus_sensor_procs.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_procs rename to src/bash/exe/khatus_sensor_procs.sh diff --git a/bin/khatus_sensor_screen_brightness b/src/bash/exe/khatus_sensor_screen_brightness.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_screen_brightness rename to src/bash/exe/khatus_sensor_screen_brightness.sh diff --git a/bin/khatus_sensor_temperature b/src/bash/exe/khatus_sensor_temperature.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_temperature rename to src/bash/exe/khatus_sensor_temperature.sh diff --git a/bin/khatus_sensor_volume b/src/bash/exe/khatus_sensor_volume.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_volume rename to src/bash/exe/khatus_sensor_volume.sh diff --git a/bin/khatus_sensor_weather b/src/bash/exe/khatus_sensor_weather.sh old mode 100755 new mode 100644 similarity index 100% rename from bin/khatus_sensor_weather rename to src/bash/exe/khatus_sensor_weather.sh -- 2.20.1 From 1cdd2ba229f2086b9270617872de9c312adc1d11 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Sat, 8 Sep 2018 21:53:23 -0400 Subject: [PATCH 13/16] Remove executable permission from AWK source files --- src/awk/exe/actuate_alert_to_notify_send.awk | 0 src/awk/exe/actuate_device_add_to_automount.awk | 0 src/awk/exe/actuate_status_bar_to_xsetroot_name.awk | 0 src/awk/exe/bar.awk | 0 src/awk/exe/monitor_devices.awk | 0 src/awk/exe/monitor_energy.awk | 0 src/awk/exe/monitor_errors.awk | 0 src/awk/exe/parse_bluetoothctl_show.awk | 0 src/awk/exe/parse_df_pcent.awk | 0 src/awk/exe/parse_fan_file.awk | 0 src/awk/exe/parse_free.awk | 0 src/awk/exe/parse_ip_addr.awk | 0 src/awk/exe/parse_iwconfig.awk | 0 src/awk/exe/parse_loadavg_file.awk | 0 src/awk/exe/parse_metar_d_output.awk | 0 src/awk/exe/parse_mpd_status_currentsong.awk | 0 src/awk/exe/parse_pactl_list_sinks.awk | 0 src/awk/exe/parse_ps.awk | 0 src/awk/exe/parse_sys_block_stat.awk | 0 src/awk/exe/parse_udevadm_monitor_block.awk | 0 src/awk/exe/parse_upower.awk | 0 src/awk/lib/cache.awk | 0 src/awk/lib/msg_in.awk | 0 src/awk/lib/msg_out.awk | 0 src/awk/lib/num.awk | 0 src/awk/lib/str.awk | 0 26 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/awk/exe/actuate_alert_to_notify_send.awk mode change 100755 => 100644 src/awk/exe/actuate_device_add_to_automount.awk mode change 100755 => 100644 src/awk/exe/actuate_status_bar_to_xsetroot_name.awk mode change 100755 => 100644 src/awk/exe/bar.awk mode change 100755 => 100644 src/awk/exe/monitor_devices.awk mode change 100755 => 100644 src/awk/exe/monitor_energy.awk mode change 100755 => 100644 src/awk/exe/monitor_errors.awk mode change 100755 => 100644 src/awk/exe/parse_bluetoothctl_show.awk mode change 100755 => 100644 src/awk/exe/parse_df_pcent.awk mode change 100755 => 100644 src/awk/exe/parse_fan_file.awk mode change 100755 => 100644 src/awk/exe/parse_free.awk mode change 100755 => 100644 src/awk/exe/parse_ip_addr.awk mode change 100755 => 100644 src/awk/exe/parse_iwconfig.awk mode change 100755 => 100644 src/awk/exe/parse_loadavg_file.awk mode change 100755 => 100644 src/awk/exe/parse_metar_d_output.awk mode change 100755 => 100644 src/awk/exe/parse_mpd_status_currentsong.awk mode change 100755 => 100644 src/awk/exe/parse_pactl_list_sinks.awk mode change 100755 => 100644 src/awk/exe/parse_ps.awk mode change 100755 => 100644 src/awk/exe/parse_sys_block_stat.awk mode change 100755 => 100644 src/awk/exe/parse_udevadm_monitor_block.awk mode change 100755 => 100644 src/awk/exe/parse_upower.awk mode change 100755 => 100644 src/awk/lib/cache.awk mode change 100755 => 100644 src/awk/lib/msg_in.awk mode change 100755 => 100644 src/awk/lib/msg_out.awk mode change 100755 => 100644 src/awk/lib/num.awk mode change 100755 => 100644 src/awk/lib/str.awk diff --git a/src/awk/exe/actuate_alert_to_notify_send.awk b/src/awk/exe/actuate_alert_to_notify_send.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/actuate_device_add_to_automount.awk b/src/awk/exe/actuate_device_add_to_automount.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk b/src/awk/exe/actuate_status_bar_to_xsetroot_name.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/bar.awk b/src/awk/exe/bar.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/monitor_devices.awk b/src/awk/exe/monitor_devices.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/monitor_energy.awk b/src/awk/exe/monitor_energy.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/monitor_errors.awk b/src/awk/exe/monitor_errors.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_bluetoothctl_show.awk b/src/awk/exe/parse_bluetoothctl_show.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_df_pcent.awk b/src/awk/exe/parse_df_pcent.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_fan_file.awk b/src/awk/exe/parse_fan_file.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_free.awk b/src/awk/exe/parse_free.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_ip_addr.awk b/src/awk/exe/parse_ip_addr.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_iwconfig.awk b/src/awk/exe/parse_iwconfig.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_loadavg_file.awk b/src/awk/exe/parse_loadavg_file.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_metar_d_output.awk b/src/awk/exe/parse_metar_d_output.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_mpd_status_currentsong.awk b/src/awk/exe/parse_mpd_status_currentsong.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_pactl_list_sinks.awk b/src/awk/exe/parse_pactl_list_sinks.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_ps.awk b/src/awk/exe/parse_ps.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_sys_block_stat.awk b/src/awk/exe/parse_sys_block_stat.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_udevadm_monitor_block.awk b/src/awk/exe/parse_udevadm_monitor_block.awk old mode 100755 new mode 100644 diff --git a/src/awk/exe/parse_upower.awk b/src/awk/exe/parse_upower.awk old mode 100755 new mode 100644 diff --git a/src/awk/lib/cache.awk b/src/awk/lib/cache.awk old mode 100755 new mode 100644 diff --git a/src/awk/lib/msg_in.awk b/src/awk/lib/msg_in.awk old mode 100755 new mode 100644 diff --git a/src/awk/lib/msg_out.awk b/src/awk/lib/msg_out.awk old mode 100755 new mode 100644 diff --git a/src/awk/lib/num.awk b/src/awk/lib/num.awk old mode 100755 new mode 100644 diff --git a/src/awk/lib/str.awk b/src/awk/lib/str.awk old mode 100755 new mode 100644 -- 2.20.1 From b5da4c6a25e5fc9def63071acadc6edbfe751e85 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Sat, 8 Sep 2018 21:54:59 -0400 Subject: [PATCH 14/16] Clean after ocamlbuild --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index b9ecf04..e001dd0 100644 --- a/Makefile +++ b/Makefile @@ -80,6 +80,7 @@ install: clean: rm -rf bin + ocamlbuild -clean bin: mkdir -p bin -- 2.20.1 From 6f35286a0c7e5c5b6569f742495efc267772f7a1 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Mon, 10 Sep 2018 17:38:08 -0400 Subject: [PATCH 15/16] Refactor cache dumper --- src/ocaml/exe/khatus_cache_dumper.ml | 90 ++++++---------------------- src/ocaml/lib/khatus.ml | 2 + src/ocaml/lib/khatus_cache.ml | 43 +++++++++---- src/ocaml/lib/khatus_cache.mli | 10 +++- src/ocaml/lib/khatus_msg.ml | 17 +++--- src/ocaml/lib/khatus_msg.mli | 5 +- src/ocaml/lib/khatus_msg_parser.mli | 14 ++--- src/ocaml/lib/khatus_msg_parser.mll | 6 ++ src/ocaml/lib/khatus_msg_stream.ml | 61 +++++++++++++++++++ src/ocaml/lib/khatus_msg_stream.mli | 9 +++ src/ocaml/lib/khatus_state.ml | 31 ++++++++++ src/ocaml/lib/khatus_state.mli | 10 ++++ src/ocaml/lib/khatus_time.ml | 1 + src/ocaml/lib/khatus_time.mli | 1 + 14 files changed, 194 insertions(+), 106 deletions(-) create mode 100644 src/ocaml/lib/khatus_msg_stream.ml create mode 100644 src/ocaml/lib/khatus_msg_stream.mli create mode 100644 src/ocaml/lib/khatus_state.ml create mode 100644 src/ocaml/lib/khatus_state.mli diff --git a/src/ocaml/exe/khatus_cache_dumper.ml b/src/ocaml/exe/khatus_cache_dumper.ml index e51243e..1ae1e84 100644 --- a/src/ocaml/exe/khatus_cache_dumper.ml +++ b/src/ocaml/exe/khatus_cache_dumper.ml @@ -1,76 +1,24 @@ -open Printf open Khatus -let modul = __MODULE__ - -let (/) = Filename.concat - -let mkdir_p dir = - match Sys.command("mkdir -p " ^ dir) with - | 0 -> () - | n -> - failwith - (sprintf "Failed to create directory: %S. mkdir status: %d\n" dir n) - -let gzip path = - match Sys.command("gzip " ^ path) with - | 0 -> () - | n -> - failwith - (sprintf "Failed to gzip path: %S. gzip status: %d\n" path n) - -let main ~node ~cache ~dump_interval:interval ~dump_directory = - mkdir_p dump_directory; - let dump_filename = dump_directory / "khatus-cache-dump.psv.gz" in - let rec loop ~time ~time_dumped = - (match read_line () with - | exception End_of_file -> - () - | line -> - (match Msg_parser.parse_msg (Lexing.from_string line) with - | Ok msg -> - let time = Msg.next_time msg ~node ~time in - Cache.update_if_data cache ~msg ~time; - if (Time.Span.is_gt_or_eq (Time.diff time_dumped time) interval) - then - ( - let (tmp_filename, oc) = - Filename.open_temp_file "khatus-cache" "dump" - in - Cache.dump cache ~node ~modul ~oc; - close_out oc; - gzip tmp_filename; - Sys.rename (tmp_filename ^ ".gz") dump_filename; - loop ~time ~time_dumped:time - ) - else - loop ~time ~time_dumped - | Error e -> - let e = - match e with - | `Bad_format_of_msg_head -> "Bad_format_of_msg_head" - | `Bad_format_of_msg_content -> "Bad_format_of_msg_content" - in - eprintf - "%s\n%!" - Msg.(to_string - { node - ; modul - ; content = Log - { location = "main:loop" - ; level = `error - ; msg = sprintf "Parse error %s in %s" e line - } - }); - loop ~time ~time_dumped - ) - ) - in - loop ~time:Time.init ~time_dumped:Time.init +let main ~stream ~interval ~dir = + let dumped = Time.init in + ignore (Msg_stream.fold stream ~init:dumped ~f:( + fun dumped ~state:(State.({node; modul; time = now; cache;})) ~msg:_ -> + let elapsed = Time.diff dumped now in + if (Time.Span.is_gt_or_eq elapsed interval) + then begin + Cache.dump_to_dir cache ~time:now ~node ~modul ~dir; + now + end else + dumped + )) let () = + let modul = __MODULE__ in + let node = Sys.argv.(1) in + let dump_interval = Sys.argv.(2) |> Time.Span.of_string in + let dump_directory = Sys.argv.(3) in main - ~node:(Sys.argv.(1)) - ~dump_interval:(Time.Span.of_string Sys.argv.(2)) - ~dump_directory:(Sys.argv.(3)) - ~cache:(Cache.create ()) + ~stream: (Msg_stream.init ~node ~modul) + ~interval: dump_interval + ~dir: dump_directory diff --git a/src/ocaml/lib/khatus.ml b/src/ocaml/lib/khatus.ml index bd01385..efc41ae 100644 --- a/src/ocaml/lib/khatus.ml +++ b/src/ocaml/lib/khatus.ml @@ -1,4 +1,6 @@ module Cache = Khatus_cache module Msg = Khatus_msg module Msg_parser = Khatus_msg_parser +module Msg_stream = Khatus_msg_stream +module State = Khatus_state module Time = Khatus_time diff --git a/src/ocaml/lib/khatus_cache.ml b/src/ocaml/lib/khatus_cache.ml index 698d20b..6a70e23 100644 --- a/src/ocaml/lib/khatus_cache.ml +++ b/src/ocaml/lib/khatus_cache.ml @@ -1,3 +1,5 @@ +open Printf + module Hashtbl = MoreLabels.Hashtbl module Msg = Khatus_msg @@ -18,19 +20,7 @@ let update {values; mtimes} ~node ~modul ~key ~value:data ~time = Hashtbl.replace values ~key ~data; Hashtbl.replace mtimes ~key ~data:time -let update_if_data t ~msg ~time = - match msg with - | Msg.({content = Data {key; value}; node; modul}) -> - update t ~node ~modul ~key ~value ~time - | {Msg.content = Msg.Alert _; _} - | {Msg.content = Msg.Cache _; _} - | {Msg.content = Msg.Error _; _} - | {Msg.content = Msg.Log _; _} - | {Msg.content = Msg.Status_bar _; _} - -> - () - -let dump {values; mtimes} ~node ~modul ~oc = +let dump_to_channel {values; mtimes} ~node ~modul ~oc = Hashtbl.iter values ~f:(fun ~key ~data:value -> let mtime = match Hashtbl.find_opt mtimes key with @@ -50,3 +40,30 @@ let dump {values; mtimes} ~node ~modul ~oc = oc (msg ^ "\n") ) + +let (/) = Filename.concat + +let mkdir_p dir = + match Sys.command("mkdir -p " ^ dir) with + | 0 -> () + | n -> + failwith + (sprintf "Failed to create directory: %S. mkdir status: %d\n" dir n) + +let gzip path = + match Sys.command("gzip " ^ path) with + | 0 -> () + | n -> + failwith + (sprintf "Failed to gzip path: %S. gzip status: %d\n" path n) + +let dump_to_dir t ~time ~node ~modul ~dir = + (* TODO: Just log the errors and keep it moving, instead of failing. *) + mkdir_p dir; + let dump_filename = dir / "khatus-cache-dump.psv.gz" in + let tmp_filename = "khatus-cache-dump-" ^ (Time.to_string time) in + let oc = open_out tmp_filename in + dump_to_channel t ~node ~modul ~oc; + close_out oc; + gzip tmp_filename; + Sys.rename (tmp_filename ^ ".gz") dump_filename diff --git a/src/ocaml/lib/khatus_cache.mli b/src/ocaml/lib/khatus_cache.mli index f6c951e..7a426f3 100644 --- a/src/ocaml/lib/khatus_cache.mli +++ b/src/ocaml/lib/khatus_cache.mli @@ -11,6 +11,10 @@ val update -> time : Khatus_time.t -> unit -val update_if_data : t -> msg:Khatus_msg.t -> time:Khatus_time.t -> unit - -val dump : t -> node:string -> modul:string -> oc:out_channel -> unit +val dump_to_dir + : t + -> time:Khatus_time.t + -> node:string + -> modul:string + -> dir:string + -> unit diff --git a/src/ocaml/lib/khatus_msg.ml b/src/ocaml/lib/khatus_msg.ml index cd9fd86..1d39d69 100644 --- a/src/ocaml/lib/khatus_msg.ml +++ b/src/ocaml/lib/khatus_msg.ml @@ -17,6 +17,9 @@ type content = type t = {node : string; modul : string; content : content} +type 'a data_handler = + node:string -> modul:string -> key:string list -> value:string -> 'a + let sep_1 = "|" let sep_2 = ":" @@ -51,20 +54,14 @@ let to_string {node; modul; content} = | Status_bar text -> String.concat sep_1 [node; modul; "status_bar"; text] -let next_time t ~node ~time:time0 = +let handle_data t ~f ~otherwise = match t with - | { modul = "khatus_sensor_datetime" - ; content = Data {key = ["epoch"]; value = time1} - ; node = node' - } when node' = node -> - (* TODO: Going forawrd, perhaps throwing exceptions is the wrong way. *) - (* TODO: Should we check this one at msg parse time? *) - Time.of_string time1 - | {content = Data _; _} + | {content = Data {key; value}; node; modul} -> + f ~node ~modul ~key ~value | {content = Alert _; _} | {content = Cache _; _} | {content = Error _; _} | {content = Log _; _} | {content = Status_bar _; _} -> - time0 + otherwise diff --git a/src/ocaml/lib/khatus_msg.mli b/src/ocaml/lib/khatus_msg.mli index 7f89c2b..358d0ed 100644 --- a/src/ocaml/lib/khatus_msg.mli +++ b/src/ocaml/lib/khatus_msg.mli @@ -15,6 +15,9 @@ type content = type t = {node : string; modul : string; content : content} +type 'a data_handler = + (node:string -> modul:string -> key:string list -> value:string -> 'a) + val to_string : t -> string -val next_time : t -> node:string -> time:Khatus_time.t -> Khatus_time.t +val handle_data : t -> f:'a data_handler -> otherwise:'a -> 'a diff --git a/src/ocaml/lib/khatus_msg_parser.mli b/src/ocaml/lib/khatus_msg_parser.mli index f177b28..a4296f6 100644 --- a/src/ocaml/lib/khatus_msg_parser.mli +++ b/src/ocaml/lib/khatus_msg_parser.mli @@ -1,8 +1,6 @@ -val parse_msg - : Lexing.lexbuf - -> - ( Khatus_msg.t - , [ `Bad_format_of_msg_head - | `Bad_format_of_msg_content - ] - ) result +type error = + [ `Bad_format_of_msg_head + | `Bad_format_of_msg_content + ] + +val parse_msg : Lexing.lexbuf -> (Khatus_msg.t, error) result diff --git a/src/ocaml/lib/khatus_msg_parser.mll b/src/ocaml/lib/khatus_msg_parser.mll index 2015f77..b7f6418 100644 --- a/src/ocaml/lib/khatus_msg_parser.mll +++ b/src/ocaml/lib/khatus_msg_parser.mll @@ -1,6 +1,12 @@ { module Msg = Khatus_msg module Time = Khatus_time + + type error = + [ `Bad_format_of_msg_head + | `Bad_format_of_msg_content + ] + let sep_2 = ':' } diff --git a/src/ocaml/lib/khatus_msg_stream.ml b/src/ocaml/lib/khatus_msg_stream.ml new file mode 100644 index 0000000..3013d53 --- /dev/null +++ b/src/ocaml/lib/khatus_msg_stream.ml @@ -0,0 +1,61 @@ +open Printf + +module Msg = Khatus_msg +module Msg_parser = Khatus_msg_parser +module State = Khatus_state + +type t = + { state : State.t + ; stream : Msg.t Stream.t + } + +let init ~node ~modul = + let line_stream = + Stream.from (fun _ -> + match read_line () with + | exception End_of_file -> + None + | line -> + Some line + ) + in + let rec parse_next msg_count = + (match Stream.next line_stream with + | exception Stream.Failure -> + None + | line -> + (match (Msg_parser.parse_msg (Lexing.from_string line)) with + | Ok msg -> + Some msg + | Error e -> + let e = + match e with + | `Bad_format_of_msg_head -> "Bad_format_of_msg_head" + | `Bad_format_of_msg_content -> "Bad_format_of_msg_content" + in + eprintf + "%s\n%!" + Msg.(to_string + { node + ; modul + ; content = Log + { location = "khatus_msg_stream:fold" + ; level = `error + ; msg = sprintf "Parse error %s in %s" e line + } + }); + parse_next msg_count + ) + ) + in + { state = State.init ~node ~modul + ; stream = Stream.from parse_next + } + +let rec fold ({state; stream} as t) ~f ~init = + match Stream.next stream with + | exception Stream.Failure -> + init + | msg -> + let state = State.update state ~msg in + fold {t with state} ~f ~init:(f init ~state ~msg) diff --git a/src/ocaml/lib/khatus_msg_stream.mli b/src/ocaml/lib/khatus_msg_stream.mli new file mode 100644 index 0000000..20b1677 --- /dev/null +++ b/src/ocaml/lib/khatus_msg_stream.mli @@ -0,0 +1,9 @@ +type t + +val init : node:string -> modul:string -> t + +val fold + : t + -> f:('a -> state:Khatus_state.t -> msg:Khatus_msg.t -> 'a) + -> init:'a + -> 'a diff --git a/src/ocaml/lib/khatus_state.ml b/src/ocaml/lib/khatus_state.ml new file mode 100644 index 0000000..9a77bc6 --- /dev/null +++ b/src/ocaml/lib/khatus_state.ml @@ -0,0 +1,31 @@ +module Cache = Khatus_cache +module Msg = Khatus_msg +module Time = Khatus_time + +type t = + { node : string + ; modul : string + ; time : Time.t + ; cache : Cache.t + } + +let init ~node ~modul = + { node + ; modul + ; time = Time.init + ; cache = Cache.create () + } + +(* TODO: Should probably wrap state update in result. *) +let update ({node; modul = _; time; cache} as t) ~msg = + Msg.handle_data msg ~otherwise:t ~f:(fun ~node:src_node ~modul ~key ~value -> + let time = + match (modul, key) with + | ("khatus_sensor_datetime", ["epoch"]) when src_node = node -> + Time.of_string value (* Raises if value is not a number *) + | (_, _) -> + time + in + Cache.update cache ~node:src_node ~modul ~key ~value ~time; + {t with time} + ) diff --git a/src/ocaml/lib/khatus_state.mli b/src/ocaml/lib/khatus_state.mli new file mode 100644 index 0000000..c097758 --- /dev/null +++ b/src/ocaml/lib/khatus_state.mli @@ -0,0 +1,10 @@ +type t = + { node : string + ; modul : string + ; time : Khatus_time.t + ; cache : Khatus_cache.t + } + +val init : node:string -> modul:string -> t + +val update : t -> msg:Khatus_msg.t -> t diff --git a/src/ocaml/lib/khatus_time.ml b/src/ocaml/lib/khatus_time.ml index cf6538a..9410417 100644 --- a/src/ocaml/lib/khatus_time.ml +++ b/src/ocaml/lib/khatus_time.ml @@ -21,4 +21,5 @@ let to_string t = |> List.hd let of_string s = + (* TODO: Shall we validate time string format at msg parse time? *) float_of_string s diff --git a/src/ocaml/lib/khatus_time.mli b/src/ocaml/lib/khatus_time.mli index 9f930af..b6b5441 100644 --- a/src/ocaml/lib/khatus_time.mli +++ b/src/ocaml/lib/khatus_time.mli @@ -15,3 +15,4 @@ val diff : t -> t -> Span.t val to_string : t -> string val of_string : string -> t +(** Raises if string is not a number. *) -- 2.20.1 From 0f81c6a873640359583d44a791e706de2d44ea1e Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Mon, 10 Sep 2018 17:42:18 -0400 Subject: [PATCH 16/16] Remove superfluous string concatenation --- src/ocaml/lib/khatus_cache.ml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ocaml/lib/khatus_cache.ml b/src/ocaml/lib/khatus_cache.ml index 6a70e23..64b407d 100644 --- a/src/ocaml/lib/khatus_cache.ml +++ b/src/ocaml/lib/khatus_cache.ml @@ -36,9 +36,8 @@ let dump_to_channel {values; mtimes} ~node ~modul ~oc = } ) in - output_string - oc - (msg ^ "\n") + output_string oc msg; + output_string oc "\n" ) let (/) = Filename.concat -- 2.20.1