Created
April 19, 2020 12:24
-
-
Save Nalorokk/b42339200be01c95119b0a8f8d7c50b1 to your computer and use it in GitHub Desktop.
Keenetic metrics to InfluxDB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/php | |
<?php | |
ini_set('default_socket_timeout', 15); | |
ini_set('display_errors', 1); | |
error_reporting(E_ALL); | |
define('LOGIN', 'admin'); | |
define('PASSWORD', 'password'); | |
define('INFLUXDB', 'homedb'); | |
define('KEENHOST', '192.168.1.1:81'); | |
define('INFLUXHOST', 'localhost:8086'); | |
$template1 = '{"rrd":[{"attribute":"rxbytes","detail":0},{"attribute":"txbytes","detail":0}],"mac":""}'; | |
$prev_record = query(INFLUXDB, "SELECT * FROM traffic ORDER BY time DESC LIMIT 1"); | |
$prev_time = $prev_record[0][0]; | |
if(keen_auth(LOGIN, PASSWORD)) { | |
$metrics = keen_request('rci/', '[{"show":{"ip":{"hotspot":{"details":"none"}}}}]'); | |
$data = $metrics[2]; | |
$macTable = array(); | |
foreach ($data[0]['show']['ip']['hotspot']['host'] as $host) { | |
$name = $host['name']; | |
if(empty($name)) { | |
$name = $host['hostname']; | |
} | |
$name = preg_replace("/[^A-Za-z0-9А-Яа-я ]/u", '', $name); | |
$name = preg_replace("/[ ]/u", '\ ', $name); | |
$macTable[$host['mac']] = $name; | |
} | |
$bigRequest = json_decode('{"show":{"ip":{"hotspot":[]}}}', 1); | |
$macs = array_keys($macTable); | |
foreach ($macTable as $mac => $_) { | |
$request = json_decode($template1, 1); | |
$request['mac'] = $mac; | |
$bigRequest['show']['ip']['hotspot'][] = $request; | |
} | |
$now = microtime(true); | |
$allMetrics = keen_request('rci/', json_encode($bigRequest)); | |
$parsed = array(); | |
$maxTime = 0; | |
foreach ($allMetrics[2]['show']['ip']['hotspot'] as $id => $hotspot) { | |
$mac = $macs[$id]; | |
if (empty($hotspot['rrd'][0]['data'])) { | |
echo "$mac failed\n"; | |
continue; | |
} | |
foreach ($hotspot['rrd'][0]['data'] as $val) { | |
if($val['t'] > $maxTime) { | |
$maxTime = $val['t']; | |
} | |
@$parsed[$mac][$val['t']]['rxbytes'] = $val['v']; | |
} | |
foreach ($hotspot['rrd'][1]['data'] as $val) { | |
@$parsed[$mac][$val['t']]['txbytes'] = $val['v']; | |
} | |
} | |
$todb = array(); | |
foreach ($parsed as $mac => $macData) { | |
foreach ($macData as $shift => $v) { | |
$realtime = $now - $maxTime + $shift; | |
if($realtime <= $prev_time + 2) { | |
continue; | |
} | |
$todb[] = to_inline('traffic', ['mac' => $mac, 'name' => $macTable[$mac]], ['rxbytes' => $v['rxbytes'].'i', 'txbytes' => $v['txbytes'].'i'], round($realtime * 1000)); | |
} | |
} | |
echo "Inserting ".count($todb)." entries\n"; | |
to_db(INFLUXDB, implode("\n", $todb)); | |
} | |
function keen_auth($login, $password) { | |
$r = keen_request('auth'); | |
if($r[0]['http_code'] == 401) { | |
$headers = parse_http($r[1]); | |
$md5 = md5($login.':'.$headers['X-NDM-Realm'].':'.$password); | |
$sha = hash('sha256', $headers['X-NDM-Challenge'].$md5); | |
$r2 = keen_request('auth', json_encode(['login' => $login, 'password' => $sha])); | |
if($r2[0]['http_code'] == 200) { | |
return true; | |
} | |
} elseif ($r[0]['http_code'] == 200) { | |
return true; | |
} | |
return false; | |
} | |
function parse_http($http) { | |
$result = array(); | |
$lines = explode("\n", $http); | |
foreach ($lines as $line) { | |
$line = trim($line); | |
if(strpos($line, ': ') !== false) { | |
$line = explode(': ', $line); | |
$result[$line[0]] = $line[1]; | |
} | |
} | |
return $result; | |
} | |
function keen_request($query, $post = null) { | |
$url = 'http://'.KEENHOST.'/'.$query; | |
$ch = curl_init($url); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_HEADER, 1); | |
curl_setopt($ch, CURLOPT_COOKIEJAR, __DIR__.'/keen_cookie.txt'); | |
curl_setopt($ch, CURLOPT_COOKIEFILE, __DIR__.'/keen_cookie.txt'); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, array( | |
'Content-Type: application/json' | |
)); | |
if($post) { | |
//echo "\nPost data: ".var_export($post, true)."\n\n"; | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); | |
} | |
$data = curl_exec($ch); | |
$info = curl_getinfo($ch); | |
curl_close($ch); | |
$json = null; | |
$notheader = mb_strcut($data, $info['header_size']); | |
if($query == 'rci/') { | |
$json = json_decode($notheader, 1); | |
} | |
return [$info, $data, $json]; | |
} | |
function to_inline($table, $tags, $values, $time) { | |
$inline_values = array(); | |
$inline_tags = array(); | |
foreach($values as $key => $value) { | |
$inline_values[] = "$key=$value"; | |
} | |
foreach($tags as $key => $tag) { | |
$inline_tags[] = "$key=$tag"; | |
} | |
$inline_values = implode(',', $inline_values); | |
$inline_tags = implode(',', $inline_tags); | |
if(empty($inline_tags)) { | |
return "$table $inline_values $time"; | |
} | |
return "$table,$inline_tags $inline_values $time"; | |
} | |
function to_db($db, $points) { | |
$ch = curl_init(); | |
//var_dump($points); | |
curl_setopt($ch, CURLOPT_URL, "http://".INFLUXHOST."/write?db=$db&precision=ms"); | |
curl_setopt($ch, CURLOPT_HEADER, false); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 60); //timeout in seconds | |
curl_setopt($ch, CURLOPT_POST, 1 ); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $points); | |
$result = curl_exec($ch); | |
curl_close($ch); | |
var_dump($result); | |
return $result; | |
} | |
function query($db, $q) { | |
$ch = curl_init(); | |
$q = urlencode($q); | |
curl_setopt($ch, CURLOPT_URL, "http://".INFLUXHOST."/query?db=$db&q=$q&epoch=s"); | |
curl_setopt($ch, CURLOPT_HEADER, false); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 60); //timeout in seconds | |
$result = curl_exec($ch); | |
curl_close($ch); | |
$r = json_decode($result, 1); | |
return $r['results'][0]['series'][0]['values']; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment