Script Functions
Overview
Script functions execute a named bash
or Python script located in the /opt/atsd/atsd/conf/script
directory and return the script stdout
and stderr
output.
Common Use Cases
- Check the TCP availability of a remote host.
- Check that the remote host is reachable via ICMP
ping
. - Check that an HTTP/S request to a URL returns HTTP
200 OK
status code. - Execute a diagnostics command on a remote host.
- Retrieve configuration information from the remote device or host.
- Analyze data using Python and prepare a report in HTML or plain text format.
Syntax
scriptOut(string file [, array arguments])
- [Required]
file
: Name of the executable script file located in the/opt/atsd/atsd/conf/script
directory. - [optional]
arguments
: Array of arguments passed to the script. Can be an empty list.
Arguments
The arguments can include literal values or window placeholders.
scriptOut('disk_size.sh', [entity, tags.file_system])
Literal string arguments must be enclosed in single quotes.
scriptOut('check_site.py', ['example.org', 3])
If no arguments are required, invoke the script without arguments or by passing an empty array []
.
scriptOut('check_service.sh')
The script must execute within a timeout.
Variables
As an alternative to passing arguments, the script can access window fields and user-defined variables as environment variables.
#!/usr/bin/env bash
# access window fields by name
ent=${entity}
...
Timeout
A script must execute within the timeout specified on the Scripts tab. If this timeout is set to Default
, the timeout value is inherited from the system.commands.timeout.seconds
server property. The default timeout is 15 seconds.
If the script times out, its process is stopped with SIGTERM
and the following text is appended to the output:
Script terminated on timeout: {current timeout value}
Permissions
Scripts must be located in the /opt/atsd/atsd/conf/script
directory and have the permission bit +x
enabled.
chmod u=rwx,g=rx,o=r /opt/atsd/atsd/conf/script/*
Scripts are executed under the axibase
user context.
To execute a Python script without the python interpreter, make the script executable and instruct the kernel which interpreter to use by adding a shebang line #!/usr/bin/env python
at the beginning of the script.
$ cat check_site.py
#!/usr/bin/env python
from atsd_client import connect, connect_url
from prettytable import PrettyTable
...
Execute the Python script by specifying its file name, similar to bash
scripts.
scriptOut('check_site.py', ['example.org', 3])
Review Daily Referer Requests script as an example.
Formatting
Format the output of the scriptOut
function when using markdown (chat messages) or with <pre>
tag when using HTML (email).
Markdown Format
HTML Format
Examples
ping
Script to ping
a host n
times.
Script
#!/usr/bin/env bash
host=${1}
count=${2}
ping -c ${count} ${host}
Function
Host ping report:
${scriptOut('ping.sh', ['example.org', '3'])}
Command
ping -c 3 example.org
Output
PING example.org (192.0.2.1) 56(84) bytes of data.
64 bytes from example.org (192.0.2.1): icmp_seq=1 ttl=52 time=45.5 ms
64 bytes from example.org (192.0.2.1): icmp_seq=2 ttl=52 time=40.0 ms
64 bytes from example.org (192.0.2.1): icmp_seq=3 ttl=52 time=43.9 ms
--- example.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 40.078/43.189/45.588/2.305 ms
Outgoing Webhooks
Telegram:
Discord:
Slack:
traceroute
Script returns traceroute
output to host.
Script
#!/usr/bin/env bash
kill_after=${1}
host=${2}
dir=$(dirname $(readlink -f $0))
timeout ${kill_after}s traceroute ${host} 2>${dir}/error
if [ $? != 0 ] && [ $(wc -c < ${dir}/error) == 0 ]; then
echo -e "\nExceeded ${kill_after} seconds"
else
cat ${dir}/error
fi
rm ${dir}/error
Function
Trace report:
${scriptOut('traceroute.sh', ['3', 'example.org'])}
Command
timeout 3 traceroute example.org
Output
traceroute to example.org (192.0.2.1), 30 hops max, 60 byte packets
1 NURSWGVML102(192.0.2.1) 0.149 ms 0.059 ms 0.032 ms
...
6 example.org (192.0.2.1) 0.348 ms 0.363 ms 0.308 ms
Outgoing Webhooks
Telegram:
Discord:
Slack:
top
Script returns output of top
in batch mode from a remote server. SSH key is stored in a pre-defined location.
Script
#!/usr/bin/env bash
host=${1}
user=${2}
count=${3}
delay=${4}
rows_n=${5}
ssh -i /home/axibase/.ssh/def.key ${host} top -u ${user} -b -n ${count} -d ${delay} | head -n ${rows_n}
Function
${scriptOut('top.sh', ['nurswgvml006','www-data', '1', '1', '15'])}
Command
ssh -i /home/axibase/.ssh/def.key nurswgvml006 top -u www-data -b -n 1 -d 1 | head -n 15
Output
top - 13:01:25 up 96 days, 23:05, 1 user, load average: 0.02, 0.04, 0.05
Tasks: 139 total, 1 running, 138 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.3 us, 0.6 sy, 0.0 ni, 97.8 id, 0.2 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem: 2049052 total, 1951460 used, 97592 free, 25364 buffers
KiB Swap: 0 total, 0 used, 0 free. 1363820 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8831 www-data 20 0 346044 67436 50140 S 0.0 3.3 0:05.49 php5-fpm
10145 www-data 20 0 341676 58756 45816 S 0.0 2.9 1:16.71 php5-fpm
21890 www-data 20 0 338204 54772 43288 S 0.0 2.7 0:14.65 php5-fpm
25001 www-data 20 0 94860 8576 2724 S 0.0 0.4 55:42.36 nginx
25002 www-data 20 0 93864 7488 2552 S 0.0 0.4 56:01.59 nginx
25003 www-data 20 0 93816 6408 1536 S 0.0 0.3 53:06.12 nginx
25005 www-data 20 0 96512 8184 696 S 0.0 0.4 54:38.85 nginx
28047 www-data 20 0 339860 57372 44236 S 0.0 2.8 0:02.34 php5-fpm
Outgoing Webhooks
Telegram:
Discord:
Slack:
ps
Script returns ps
output for the specified grep
pattern from a remote server.
Script
#!/usr/bin/env bash
host=${1}
pattern=${2}
ssh -i /home/axibase/.ssh/def.key ${host} ps aux | grep ${pattern}
Function
Output is:
${scriptOut('ps.sh', ['example.org','bash'])}
Command
ssh -i /home/axibase/.ssh/def.key example.org ps aux | grep bash
Output
axibase 1 0.0 0.0 19712 3304 ? Ss 11:07 0:00 /bin/bash /entrypoint.sh
axibase 2807 0.0 0.0 19828 3464 ? S 11:09 0:00 bash /opt/atsd/hbase/bin/hbase-daemon.sh --config /opt/atsd/hbase/bin/../conf foreground_start master
Outgoing Webhooks
Telegram:
Discord:
Slack:
URL availability
Script tests URL availability.
Script
#!/usr/bin/env bash
url=${1}
dir=$(dirname $(readlink -f $0))
status=$(curl -sS -L --insecure -X GET -m 10 -D ${dir}/headers -w "\nResponse Time: %{time_total}\n" "${url}" > ${dir}/response 2>&1)
if [[ $? == 0 ]] ; then
code=$(head -n 1 ${dir}/headers | grep -oiE "[0-9]{3}[a-z ]*")
echo "Status code: ${code}"
echo "$(tail -n 1 ${dir}/response)" # Response Time
length=$(head -n -1 ${dir}/response | wc -c)
echo "Content Length: ${length} bytes"
grep "Location:" ${dir}/headers
else
head -n 1 ${dir}/response
fi
rm ${dir}/response ${dir}/headers
Function
${scriptOut('url_avail.sh', ['https://example.org'])}
Command
curl -sS -L --insecure -X GET -m 10 -D /opt/atsd/atsd/conf/script/headers \
-w "\nResponse Time: %{time_total}\n" "https://example.org" > /opt/atsd/atsd/conf/script/response 2>&1
Output
Status code: 200 OK
Response Time: 0.618
Content Length: 35214 bytes
Outgoing Webhooks
Telegram:
Discord:
Slack:
TCP availability
Script tests TCP availability.
Script
#!/usr/bin/env bash
kill_after=${1}
host=${2}
port=${3}
timeout ${kill_after} bash -c "</dev/tcp/${host}/${port}"
if [[ $? -eq 0 ]]; then
echo "TCP port ${port} is available"
else
echo "TCP port ${port} is unavailable"
fi
Function
Output is: ${scriptOut('tcp.sh', ['2','example.org', '443'])}
Command
timeout 2 bash -c "</dev/tcp/example.org/443"
Output
TCP port 443 is available
Outgoing Webhooks
Telegram:
Discord:
Slack:
osquery
Script executes an osquery request against a remote server.
Script
#!/usr/bin/env bash
host=${1}
query=${2}
ssh -i /home/axibase/.ssh/def.key ${host} "osqueryi \"${query}\""
Function
${scriptOut('osquery.sh',
['example.org',
"SELECT DISTINCT processes.name, listening_ports.port, processes.pid FROM listening_ports " +
"JOIN processes USING (pid) WHERE listening_ports.address = '0.0.0.0';"])}
Command
ssh -i /home/axibase/.ssh/def.key example.org \
'osqueryi "SELECT DISTINCT processes.name, listening_ports.port, processes.pid FROM listening_ports \
JOIN processes USING (pid) WHERE listening_ports.address = '\''0.0.0.0'\'';"'
Output
+------+-------+------+
| name | port | pid |
+------+-------+------+
| java | 50010 | 9112 |
| java | 50075 | 9112 |
| java | 50020 | 9112 |
| java | 50090 | 9365 |
| java | 50070 | 8921 |
+------+-------+------+
Outgoing Webhooks
Telegram:
Discord:
Slack:
Daily Referer Requests
Python script generates a daily http_referer
report in HTML format based on messages collected by the nginx_access_log_tail
script.
Function
${scriptOut('daily_referer_requests.py')}
Command
./daily_referer_requests.py
Output
<table>
<tr>
<th>Date</th>
<th>URI</th>
<th>Referer</th>
<th>IP</th>
<th>Org</th>
</tr>
<tr>
<td>2018-06-14 03:58</td>
<td>/</td>
<td>https://example.org/</td>
<td>192.0.2.1</td>
<td>Example Org</td>
</tr>
<tr>
<td>2018-06-14 20:43</td>
<td>/chartlab/2ef08f32</td>
<td>https://example.org/</td>
<td>192.0.2.1</td>
<td>Example Org</td>
</tr>
</table>