Skip to content

Instantly share code, notes, and snippets.

@j0ju
Created July 2, 2020 17:43
Show Gist options
  • Save j0ju/41ff63e92cc6f33971f00b90b31c6532 to your computer and use it in GitHub Desktop.
Save j0ju/41ff63e92cc6f33971f00b90b31c6532 to your computer and use it in GitHub Desktop.
#!/bin/sh
prefix=
preamble_printed=
PREAMBLE() {
[ "$preamble_printed" != 1 ] || return 0
cat << EOF
# HELP bird_route_metadata
# TYPE bird_route_metadata gauge
# HELP bird_route_bgp_metadata
# TYPE bird_route_bgp_metadata gauge
# HELP bird_route_bgp_metadata_as_pathlen
# TYPE bird_route_bgp_metadata_as_pathlen gauge
EOF
preamble_printed=1
}
birdc_dump_routes() {
# dump routes for
# V4
for cmd in birdc birdc4; do
"$cmd" < /dev/null > /dev/null 2> /dev/null || continue
"$cmd" sh route all
continue
done
# V6
for cmd in birdc6; do
"$cmd" < /dev/null > /dev/null 2> /dev/null || continue
"$cmd" sh route all
continue
done
}
generate_metrics() {
while read line; do
case "$line" in
[0-9a-f:.]*[]/[1-9]* )
prefix="${line%% *}"
# trim leading and trailing white spaces, and double spaces
# execve is more expensive on embedded systems
# this forks, forks are cheap, IFS is cool
line="$( echo "${line#$prefix}" | ( read line; echo "$line" ) )"
protocol=
nexthopinfo=
as_path=
as_pathlen=
as_origin=
as_peer=
device=
nexthop=
proto=
;;
esac
[ -n "$prefix" ] || \
continue
case "$line" in
"dev "* | "via "* )
parse_nexthop_info "$line"
;;
"Type: "* )
# same prefix, new route via another protocol
# dump current values
if [ -n "$protocol" ]; then
PREAMBLE
assemble_metric bird_route_metadata 1 prefix device nexthop
if [ "$protocol" = BGP ]; then
assemble_metric bird_route_bgp_metadata_as_pathlen $as_pathlen prefix as_peer as_path
assemble_metric bird_route_bgp_metadata 1 prefix as_peer as_origin
fi
fi
protocol="${line#Type: }"
protocol="${protocol%% *}"
;;
"BGP.as_path: "* )
as_path="${line#BGP.as_path: }"
as_pathlen="$(echo "$as_path" | wc -w)"
as_origin="${as_path##* }"
as_peer="${as_path%% *}"
;;
esac
done
}
shiftv() {
local _shiftv_new_ _shiftv_prev_
eval "_shiftv_prev_=\"\${$1}\""
eval "_shiftv_new_=\"\${$1#* }\""
if [ "$_shiftv_prev_" = "$_shiftv_new_" ]; then
eval "$1=''"
else
eval "$1='$_shiftv_new_'"
fi
}
parse_nexthop_info() {
local line="$line"
while [ -n "$line" ]; do
case "$line" in
"dev "* | "on "* )
shiftv line
device="${line%% *}"
;;
"via "* | "on "* )
shiftv line
nexthop="${line%% *}"
;;
esac
shiftv line
done
}
assemble_metric() {
local _metric_="$1"
shift
local _value_="$1"
shift
local _a_ _v_ _attributes_=
for _a_; do
eval "_v_=\"\${$_a_}\""
[ -n "$_v_" ] || \
continue
[ -z "$_attributes_" ] || \
_attributes_="${_attributes_},"
_attributes_="${_attributes_}${_a_}=\"${_v_}\""
done
echo "$_metric_{$_attributes_} $_value_"
}
birdc_dump_routes | generate_metrics
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment