13 Sep

Ad-hoc Notifications for Systemd Services

We have recently migrated some of our production servers to a new linux with systemd. I wanted to get an email everytime there was an error in the httpd service. I am sure there should be a proper process and a fancy way, but for me this worked like a charm getting a notification on my phone:

#!/usr/bin/env bash
 
# depends the following tools:
# jq
# mailx
 
sender_address="sender@mydomain.com"
to_address="addressee@mydomain.com"
unit_to_follow=httpd
 
set -e
set -u
 
while read log; do
        message=$(echo "$log" | jq -r ".MESSAGE")
        timestamp=$(echo "$log" | jq -r ".__REALTIME_TIMESTAMP")
        unit=$(echo "$log" | jq -r "._SYSTEMD_UNIT")
        timestamp_in_seconds=$(( $timestamp/1000000 ))
        human_readable_timestamp=$(date -d @${timestamp_in_seconds})
        echo "Sending mail ${human_readable_timestamp}"
        mailx -s "A warning from ${unit}" -r "${sender_address}" "${to_address}" <<HERE
${human_readable_timestamp}
${message}
HERE
 
done < <(journalctl -f -u ${unit_to_follow} --priority 1..3 -o json )

All I did was run this using nohup.

26 Mar

Bash-Based Decision Support Systems

It is a well known fact that decision making is tiring. One of the more difficult decisions our team face every day is where to go for lunch. To avoid post lunch decision fatigue, we started automating the process.

Here is the first version of the script using the venerable rl utility.

rl -c 1 << HERE | say
Papa Pane
Japanese
Soup
Canteen
Honigmond
HERE

In this case we had to generate the candidates manually. In a lot of decision situations that is acceptable. However there are also situations where the machine can help generating candidates. For our lunch problem we devised the following solution:

curl -s \
      --data-urlencode "cat=eat-drink" \
      --data-urlencode "in=52.5304,13.3864;r=640" \
      --data-urlencode "size=15" \
      --data-urlencode "pretty" \
      --data-urlencode "app_code=NYKC67ShPhQwqaydGIW4yg" \
      --data-urlencode "app_id=demo_qCG24t50dHOwrLQ" \
      --get 'http://demo.places.nlp.nokia.com/places/v1/discover/explore' \
      | jsed --raw 'function(r)
         r.results.items.map(function(i)
             i.title + " (distance " + i.distance.toString() + "m)"
         ).join("\n")' \
      | rl -c 1

This would yield something like this:

Weinbar Rutz (distance 252m)

It uses the Nokia RESTful Places API to find places within 640m around our office. Conveniently its playground environment already creates a curl statement for us. Then we pipe the result through jsed to extract the important information from the JSON response, before we task rl with taking the actual decision for us.