The following is however again much faster:
real 0m0.003s
user 0m0.003s
sys 0m0.001s
An improvement of over 7700%.
We work around Perl's compilation overheads:
- Convert script to TCP server which compiles once, listens on port 7890 and then forks children
- Replace existing script with simple netcat wrapper:
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -d; echo $?
{
"data": [
{ "{#BGPPEER}": "iOnline" }
]
}
0
[root@zabbix ~]# cat /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh
#!/bin/sh
echo "'$1'" "'$2'" "'$3'" "'$4'" "'$5'" "'$6'" | /usr/bin/nc -w 3 127.0.0.1 7890;
exit $?;
Changes to convert script itself to a standalone tcp server:
- Alter all print statements (eg 'print', 'print STDERR', and 'printf') to output to '$client'
-print STDERR "Another ...
+print $client "Another ...
-printf ("%-25.25s ...
+printf $client ("%-25.25s ...
- Encapsulate script's previous main section by starting with the following subroutine definition and appending '}'. These changes result in the tcp server reading up to 250 characters worth of commands, instead of them being supplied directly as script arguments:
sub handle_client {
my $client = shift;
my $msg;
$client->recv($msg, 250);
my ($router, $api_user, $api_passwd, $command, $peer, $key) = quotewords('\s+', 0, $msg);
#my ($router, $api_user, $api_passwd, $command, $peer, $key) = @ARGV;
- New main body listens for tcp connections on port 7890 on the loopback adapter and forks child for each connection:
use IO::Socket::INET;
use Text::ParseWords;
$SIG{CHLD} = 'IGNORE';
STDOUT->autoflush(1);
my $server = IO::Socket::INET->new(
LocalAddr => '127.0.0.1',
LocalPort => '7890',
Listen => SOMAXCONN,
Type => SOCK_STREAM,
Reuse => 1) or die "could not open port: $!";
while (my $client = $server->accept) {
next if my $pid = fork;
die "fork: $!" unless defined $pid;
$client->autoflush(1);
close $server;
handle_client($client);
} continue {
close $client;
}
mikrotik-api-bgp-status.zip
Contains:
- init.d launch script for tcp server
- perl tcp server which listens on port 7890 and connects to MikroTik using API to retrieve BGP peer status information. Information is cached for 55 seconds so speed up subsequent queries
- client app which is really simply a netcat wrapper
Available commands:
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd'
Missing or invalid command. Usage /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh <router> <api username> <api password> <command> [<peer>] :
-d|--discover Zabbix LLD (low level discovery). In JSON format.
-c|--croak Dumps all available data. Usable as $bgp_peer{'$peer'}->{'key'}
-t|--table Displays tabled overview
-g|--get <peer> <key> example: -g "Syrex - Primary" state
Examples:
Discovery : /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms "FakeP@ssw0rd" -d
Sample : {
"data": [
{ "{#BGPPEER}": "Syrex - Primary" },
{ "{#BGPPEER}": "Syrex - Secondary" }
]
}
Get item : /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms "FakeP@ssw0rd" "Syrex - Primary" state
Sample : established
Zabbix low level item discovery:
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -d
{
"data": [
{ "{#BGPPEER}": "iOnline" }
]
}
Tabled output:
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -t
Peer Active Prefixes Remote IP Remote AS Uptime State
iOnline yes 2 172.18.0.17 327909 4w1d12h20m3s established
Dump all values (croak):
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -c
peer: iOnline
=
.id=*0
address-families=ip
as-override=false
as4-capability=true
default-originate=if-installed
disabled=false
established=true
hold-time=3m
in-filter=ionline-in
instance=mpls
local-address=172.18.0.20
multihop=false
name=iOnline
nexthop-choice=default
out-filter=ionline-out
passive=false
prefix-count=2
refresh-capability=true
remote-address=172.18.0.17
remote-as=329709
remote-hold-time=3m
remote-id=145.23.110.26
remove-private-as=false
route-reflect=false
state=established
tcp-md5-key=secret123
ttl=default
updates-received=6
updates-sent=1
uptime=4w1d12h21m3s
use-bfd=false
used-hold-time=3m
used-keepalive-time=1m
withdrawn-received=0
withdrawn-sent=0
Retrieve specific item value (uptime in MikroTik format is converted to uptime seconds):
[root@zabbix ~]# /usr/lib/zabbix/externalscripts/mikrotik-api-bgp_status_client.sh 10.0.0.1 syrexnms 'FakeP@ssw0rd' -g iOnline uptime
2550183
Sample BGP peer uptime graph:
zabbix_bgp_uptime_sample.jpg
Sample BGP prefix activity graph:
zabbix_bgp_activity_sample.jpg
Sample BGP status graph:
zabbix_bgp_status_sample.jpg
You do not have the required permissions to view the files attached to this post.