Enhance Unifi discovery and monitoring

Adding support for station monitoring
tags/zabbix-agent-addons-0.2.46-1
Daniel Berteaud 6 years ago
parent dc66533d42
commit 2c77d2a7c8
  1. 101
      zabbix_scripts/check_unifi
  2. 9
      zabbix_scripts/disco_unifi

@ -13,7 +13,7 @@ my $site = 'default';
my $url = 'https://localhost:8443'; my $url = 'https://localhost:8443';
my $unifi; my $unifi;
my $dev; my $dev;
my $client; my $station;
my $net; my $net;
my $wlan; my $wlan;
my $pretty = 0; my $pretty = 0;
@ -28,18 +28,20 @@ GetOptions (
'url=s' => \$url, 'url=s' => \$url,
'unifi' => \$unifi, 'unifi' => \$unifi,
'dev=s' => \$dev, 'dev=s' => \$dev,
'client=s' => \$client, 'station=s' => \$station,
'net=s' => \$net, 'net=s' => \$net,
'wlan=s' => \$wlan, 'wlan=s' => \$wlan,
'pretty' => \$pretty 'pretty' => \$pretty
); );
# Log into the API my @radio_proto = qw/a b g na ng ac/;
my $resp; my $resp;
my $ua = LWP::UserAgent->new( my $ua = LWP::UserAgent->new(
ssl_opts => { verify_hostname => 0 }, ssl_opts => { verify_hostname => 0 },
cookie_jar => {} cookie_jar => {}
); );
# Log into the API
$resp = $ua->post( $resp = $ua->post(
$url . '/api/login', $url . '/api/login',
Content => to_json({ username => $user, password => $pass }), Content => to_json({ username => $user, password => $pass }),
@ -89,6 +91,7 @@ if ($unifi){
foreach (qw/version build update_available/); foreach (qw/version build update_available/);
} elsif ($dev) { } elsif ($dev) {
# Dev is identified by MAC
$resp = $ua->get($url . '/api/s/' . $site . '/stat/device/' . $dev); $resp = $ua->get($url . '/api/s/' . $site . '/stat/device/' . $dev);
die $resp->message . "\n" if $resp->is_error; die $resp->message . "\n" if $resp->is_error;
my $obj = from_json($resp->decoded_content)->{data}->[0]; my $obj = from_json($resp->decoded_content)->{data}->[0];
@ -108,11 +111,73 @@ if ($unifi){
$json->{last_seen} = time - $obj->{last_seen}; $json->{last_seen} = time - $obj->{last_seen};
# Add some more info in sys_stats # Add some more info in sys_stats
$json->{sys_stats}->{$_} = $obj->{'system-stats'}->{$_} foreach (qw/cpu mem uptime/); $json->{sys_stats}->{$_} = $obj->{'system-stats'}->{$_} foreach (qw/cpu mem uptime/);
# Count the number of SSID served
$json->{num_wlan} = scalar @{$obj->{radio_table}} if (defined $obj->{radio_table}); # If this is an ap
} elsif ($client) { if ($obj->{type} eq 'uap'){
# Count the number of SSID served
$json->{num_wlan} = scalar @{$obj->{radio_table}};
$resp = $ua->get($url . '/api/s/' . $site . '/stat/sta');
die $resp->message . "\n" if $resp->is_error;
foreach my $proto (@radio_proto){
$json->{$_ . $proto} = 0 foreach (qw/num_sta_ avg_rx_rate_ avg_tx_rate_/);
}
foreach my $entry (@{from_json($resp->decoded_content)->{data}}){
next if (not $entry->{ap_mac} or $entry->{ap_mac} ne $dev or $entry->{is_wired} == JSON::PP::true);
foreach (@radio_proto){
if ($entry->{radio_proto} eq $_){
$json->{'num_sta_' . $_}++;
$json->{'avg_rx_rate_' . $_} += $entry->{rx_rate};
$json->{'avg_tx_rate_' . $_} += $entry->{tx_rate};
}
}
$json->{$_} += $entry->{$_} foreach (qw/rx_bytes tx_bytes rx_packets tx_packets/);
$json->{'avg_' . $_} += $entry->{$_} foreach (qw/satisfaction tx_power signal noise/);
}
# Now lets compute average values
$json->{'avg_' . $_} = ($json->{num_sta} == 0) ? 0 : $json->{'avg_' . $_} / $json->{num_sta}
foreach (qw/satisfaction tx_power signal noise/);
$json->{$_} = ($json->{num_sta_ac} == 0) ? 0 : $json->{$_} / $json->{num_sta_ac}
foreach (qw/avg_rx_rate_ac avg_tx_rate_ac/);
$json->{$_} = ($json->{num_sta_ng} == 0) ? 0 : $json->{$_} / $json->{num_sta_ng}
foreach (qw/avg_rx_rate_ng avg_tx_rate_ng/);
}
} elsif ($station) {
# Client is identified by MAC
$resp = $ua->get($url . '/api/s/' . $site . '/stat/sta/' . $station);
die $resp->message . "\n" if $resp->is_error;
my $obj = from_json($resp->decoded_content)->{data}->[0];
my @client_base = qw/rx_packets tx_packets rx_bytes tx_bytes hostname last_seen ip authorized oui is_guest/;
foreach (@client_base){
$json->{$_} = $obj->{$_} || 0;
}
# Convert last_seen to relative
$json->{last_seen} = time - $json->{last_seen};
# For wireless stations, we gather some more info
if ($obj->{is_wired} == JSON::PP::false){
my @client_wireless = qw/rx_rate tx_rate essid ap_mac tx_power radio_proto signal noise/;
foreach (@client_wireless){
$json->{$_} = $obj->{$_} || 0;
}
# We have the MAC of the AP, lets try to find the name of this AP
$resp = $ua->get($url . '/api/s/' . $site . '/stat/device/' . $json->{ap_mac});
die $resp->message . "\n" if $resp->is_error;
$json->{ap} = from_json($resp->decoded_content)->{data}->[0]->{name};
}
# Force some data to be numbers and not strings
$json->{$_} = 0 + $json->{$_} foreach(qw/signal noise/);
} elsif ($wlan) { } elsif ($wlan) {
# Wlan is identified by ID
$resp = $ua->get($url . '/api/s/' . $site . '/rest/wlanconf/' . $wlan); $resp = $ua->get($url . '/api/s/' . $site . '/rest/wlanconf/' . $wlan);
die $resp->message . "\n" if $resp->is_error; die $resp->message . "\n" if $resp->is_error;
my $obj = from_json($resp->decoded_content)->{data}->[0]; my $obj = from_json($resp->decoded_content)->{data}->[0];
@ -124,23 +189,27 @@ if ($unifi){
# Now, we need to count stations for each SSID # Now, we need to count stations for each SSID
$resp = $ua->get($url . '/api/s/' . $site . '/stat/sta'); $resp = $ua->get($url . '/api/s/' . $site . '/stat/sta');
die $resp->message . "\n" if $resp->is_error; die $resp->message . "\n" if $resp->is_error;
$json->{$_} = 0 foreach (qw/avg_rx_rate_ac avg_tx_rate_ac avg_rx_rate_ng
avg_tx_rate_ng num_sta num_sta_ac num_sta_ng/); # Set default values to 0
$json->{num_sta} = 0;
foreach my $proto (@radio_proto){
$json->{$_ . $proto} = 0 foreach (qw/num_sta_ avg_rx_rate_ avg_tx_rate_/);
}
foreach my $entry (@{from_json($resp->decoded_content)->{data}}){ foreach my $entry (@{from_json($resp->decoded_content)->{data}}){
next if (not $entry->{essid} or $entry->{essid} ne $json->{name} or $entry->{is_wired} == JSON::PP::true); next if (not $entry->{essid} or $entry->{essid} ne $json->{name} or $entry->{is_wired} == JSON::PP::true);
$json->{num_sta}++; $json->{num_sta}++;
if ($entry->{radio_proto} eq 'ac'){ foreach (@radio_proto){
$json->{num_sta_ac}++; if ($entry->{radio_proto} eq $_){
$json->{avg_rx_rate_ac} += $entry->{rx_rate}; $json->{'num_sta_' . $_}++;
$json->{avg_tx_rate_ac} += $entry->{tx_rate}; $json->{'avg_rx_rate_' . $_} += $entry->{rx_rate};
} elsif ($entry->{radio_proto} eq 'ng'){ $json->{'avg_tx_rate_' . $_} += $entry->{tx_rate};
$json->{num_sta_ng}++; }
$json->{avg_rx_rate_ng} += $entry->{rx_rate};
$json->{avg_tx_rate_ng} += $entry->{tx_rate};
} }
$json->{$_} += $entry->{$_} foreach (qw/rx_bytes tx_bytes rx_packets tx_packets/); $json->{$_} += $entry->{$_} foreach (qw/rx_bytes tx_bytes rx_packets tx_packets/);
$json->{'avg_' . $_} += $entry->{$_} foreach (qw/satisfaction tx_power signal noise/); $json->{'avg_' . $_} += $entry->{$_} foreach (qw/satisfaction tx_power signal noise/);
} }
# Now lets compute average values # Now lets compute average values
$json->{'avg_' . $_} = ($json->{num_sta} == 0) ? 0 : $json->{'avg_' . $_} / $json->{num_sta} $json->{'avg_' . $_} = ($json->{num_sta} == 0) ? 0 : $json->{'avg_' . $_} / $json->{num_sta}
foreach (qw/satisfaction tx_power signal noise/); foreach (qw/satisfaction tx_power signal noise/);

@ -71,19 +71,18 @@ if ($what eq 'devices'){
'{#UNIFI_DEV_TYPE}' => $entry->{type} '{#UNIFI_DEV_TYPE}' => $entry->{type}
}; };
} }
} elsif ($what eq 'clients'){ } elsif ($what eq 'stations'){
$resp = $ua->get($url . '/api/s/' . $site . '/stat/alluser'); $resp = $ua->get($url . '/api/s/' . $site . '/stat/sta');
die $resp->message . "\n" if $resp->is_error; die $resp->message . "\n" if $resp->is_error;
foreach my $entry (@{from_json($resp->decoded_content)->{data}}){ foreach my $entry (@{from_json($resp->decoded_content)->{data}}){
# Ignore other sites # Ignore other sites
next if ($entry->{site_id} ne $site_id); next if ($entry->{site_id} ne $site_id);
# Ignore clients not seen since more than 30 days
next if (time - $entry->{last_seen} > 2592000);
next if ($type eq 'wireless' and $entry->{is_wired} eq 'true'); next if ($type eq 'wireless' and $entry->{is_wired} eq 'true');
next if ($type eq 'wired' and $entry->{is_wired} eq 'false'); next if ($type eq 'wired' and $entry->{is_wired} eq 'false');
push @{$json->{data}}, { push @{$json->{data}}, {
'{#UNIFI_STA_ID}' => $entry->{_id}, '{#UNIFI_STA_ID}' => $entry->{_id},
'{#UNIFI_STA_NAME}' => (defined $entry->{hostname}) ? $entry->{hostname} : $entry->{mac} '{#UNIFI_STA_NAME}' => (defined $entry->{hostname}) ? $entry->{hostname} : $entry->{mac},
'{#UNIFI_STA_MAC}' => $entry->{mac}
}; };
} }
} elsif ($what eq 'networks'){ } elsif ($what eq 'networks'){

Loading…
Cancel
Save