mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-07-12 08:24:24 +02:00
Livestatus\Connection: switch to new fetch methods
This commit is contained in:
parent
efd395e12a
commit
fd55ffe47e
@ -32,6 +32,13 @@ class Connection
|
|||||||
const TYPE_UNIX = 1;
|
const TYPE_UNIX = 1;
|
||||||
const TYPE_TCP = 2;
|
const TYPE_TCP = 2;
|
||||||
|
|
||||||
|
protected $bytesRead = 0;
|
||||||
|
protected $responseSize;
|
||||||
|
protected $status;
|
||||||
|
protected $headers;
|
||||||
|
|
||||||
|
// List of available Livestatus tables. Kept here as we otherwise get no
|
||||||
|
// useful error message
|
||||||
protected $available_tables = array(
|
protected $available_tables = array(
|
||||||
'hosts', // hosts
|
'hosts', // hosts
|
||||||
'services', // services, joined with all data from hosts
|
'services', // services, joined with all data from hosts
|
||||||
@ -110,9 +117,10 @@ class Connection
|
|||||||
{
|
{
|
||||||
return 100;
|
return 100;
|
||||||
$count = clone($query);
|
$count = clone($query);
|
||||||
$count->count();
|
// WTF? $count->count();
|
||||||
Benchmark::measure('Sending Livestatus Count Query');
|
Benchmark::measure('Sending Livestatus Count Query');
|
||||||
$data = $this->doFetch((string) $count);
|
$this->execute($query);
|
||||||
|
$data = $this->fetchRowFromSocket();
|
||||||
Benchmark::measure('Got Livestatus count result');
|
Benchmark::measure('Got Livestatus count result');
|
||||||
return $data[0][0];
|
return $data[0][0];
|
||||||
}
|
}
|
||||||
@ -163,21 +171,26 @@ class Connection
|
|||||||
public function fetchAll(Query $query)
|
public function fetchAll(Query $query)
|
||||||
{
|
{
|
||||||
Benchmark::measure('Sending Livestatus Query');
|
Benchmark::measure('Sending Livestatus Query');
|
||||||
$data = $this->doFetch((string) $query);
|
$this->execute($query);
|
||||||
Benchmark::measure('Got Livestatus Data');
|
Benchmark::measure('Got Livestatus Data');
|
||||||
|
|
||||||
if ($query->hasColumns()) {
|
if ($query->hasColumns()) {
|
||||||
$headers = $query->getColumnAliases();
|
$headers = $query->getColumnAliases();
|
||||||
} else {
|
} else {
|
||||||
|
// TODO: left this here, find out how to handle it better
|
||||||
|
die('F*** no data');
|
||||||
$headers = array_shift($data);
|
$headers = array_shift($data);
|
||||||
}
|
}
|
||||||
$result = array();
|
$result = array();
|
||||||
foreach ($data as $row) {
|
$filter = $query->filterIsSupported() ? null : $query->getFilter();
|
||||||
$result_row = & $result[];
|
|
||||||
$result_row = (object) array();
|
while ($row = $this->fetchRowFromSocket()) {
|
||||||
foreach ($row as $key => $val) {
|
$r = new ResponseRow($row, $query);
|
||||||
$result_row->{$headers[$key]} = $val;
|
$res = $query->resultRow($row);
|
||||||
}
|
if ($filter !== null && ! $filter->matches($res)) continue;
|
||||||
|
$result[] = $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($query->hasOrder()) {
|
if ($query->hasOrder()) {
|
||||||
usort($result, array($query, 'compare'));
|
usort($result, array($query, 'compare'));
|
||||||
}
|
}
|
||||||
@ -193,59 +206,49 @@ class Connection
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doFetch($raw_query)
|
protected function hasBeenExecuted()
|
||||||
{
|
{
|
||||||
$conn = $this->getConnection();
|
return $this->status !== null;
|
||||||
$this->writeToSocket($raw_query);
|
|
||||||
$header = $this->readFromSocket(16);
|
|
||||||
$status = (int) substr($header, 0, 3);
|
|
||||||
$length = (int) trim(substr($header, 4));
|
|
||||||
$body = $this->readFromSocket($length);
|
|
||||||
if ($status !== 200) {
|
|
||||||
throw new IcingaException(
|
|
||||||
'Problem while reading %d bytes from livestatus: %s',
|
|
||||||
$length,
|
|
||||||
$body
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$result = json_decode($body);
|
|
||||||
if ($result === null) {
|
|
||||||
throw new IcingaException('Got invalid response body from livestatus');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
protected function execute($query)
|
||||||
}
|
|
||||||
|
|
||||||
protected function readFromSocket($length)
|
|
||||||
{
|
{
|
||||||
$offset = 0;
|
// Reset state
|
||||||
$buffer = '';
|
$this->status = null;
|
||||||
|
$this->responseSize = null;
|
||||||
|
$this->bytesRead = 0;
|
||||||
|
|
||||||
while ($offset < $length) {
|
$raw = $query->toString();
|
||||||
$data = socket_read($this->connection, $length - $offset);
|
|
||||||
if ($data === false) {
|
Benchmark::measure($raw);
|
||||||
throw new IcingaException(
|
|
||||||
'Failed to read from livestatus socket: %s',
|
// "debug"
|
||||||
socket_strerror(socket_last_error($this->connection))
|
// echo $raw . "\n<br>";
|
||||||
|
$this->writeToSocket($raw);
|
||||||
|
$header = $this->readLineFromSocket();
|
||||||
|
|
||||||
|
if (! preg_match('~^(\d{3})\s\s*(\d+)$~', $header, $m)) {
|
||||||
|
$this->disconnect();
|
||||||
|
throw new Exception(
|
||||||
|
sprintf('Got invalid header. First 16 Bytes: %s', $header)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$size = strlen($data);
|
$this->status = (int) $m[1];
|
||||||
$offset += $size;
|
$this->bytesRead = 0;
|
||||||
$buffer .= $data;
|
$this->responseSize = (int) $m[2];
|
||||||
|
if ($this->status !== 200) {
|
||||||
if ($size === 0) {
|
// "debug"
|
||||||
break;
|
//die(var_export($raw, 1));
|
||||||
}
|
throw new Exception(
|
||||||
}
|
sprintf(
|
||||||
if ($offset !== $length) {
|
'Error %d while querying livestatus: %s %s',
|
||||||
throw new IcingaException(
|
$this->status,
|
||||||
'Got only %d instead of %d bytes from livestatus socket',
|
$raw,
|
||||||
$offset,
|
$this->readLineFromSocket()
|
||||||
$length
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$this->discoverColumnHeaders($query);
|
||||||
return $buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function discoverColumnHeaders($query)
|
protected function discoverColumnHeaders($query)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user