Skip to content

Instantly share code, notes, and snippets.

@ericek111
Last active March 27, 2023 01:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericek111/0bbc3a084680925e52f4722db868d364 to your computer and use it in GitHub Desktop.
Save ericek111/0bbc3a084680925e52f4722db868d364 to your computer and use it in GitHub Desktop.
Manticore Search query log parser in PHP
<?php
class ManticoreLogLine {
public function __construct(
public *\DateTimeImmutable* $date,
public int $conn,
public float $realTime,
public float $wallTime,
public int $foundRows,
public string $sql,
public array $iostats
) {
}
public function getMatch(): ?string {
if (preg_match("/MATCH\(\'(.*?)\'\)/", $this->sql, $matches)) {
return $matches[1];
} else {
return null;
}
}
}
class ManticoreLogParser {
public function __construct() {
}
public function parseIostats(string $inside): array {
$iostats = [];
$token = strtok($inside, " ");
while ($token !== false) {
if (str_starts_with($token, "error=") || str_starts_with($token, "warning=")) {
$rest = strtok("");
$key = strtok($token, "=");
$firstWord = strtok("");
$iostats[$key] = $firstWord . ' ' . $rest;
break;
} else {
list($key, $value) = explode('=', $token, 2);
$iostats[$key] = is_numeric($value) ? (float) ($value ?? 0) : ($value ?? '');
}
$token = strtok(" ");
}
return $iostats;
}
public function parseLine(string $line): ?\ManticoreLogLine {
$regex = '/^\/\* (.*) conn (\d+) real ([\d\.]+) wall ([\d\.]+) found (\d+) \*\/ (.+?)(?: \/\*(.+)\*\/)?$/';
$line = trim($line);
if (!preg_match($regex, $line, $matches)) {
return null;
}
$iostats = $this->parseIostats($matches[7]);
$dateRaw = $matches[1];
$dateRaw = substr($dateRaw, ($pos = strpos($dateRaw, ' ')) !== false ? $pos + 1 : 0);
$date = \DateTimeImmutable::createFromFormat('M j H:i:s.v Y', $dateRaw); // local timezone
$line = new ManticoreLogLine(
date: $date,
conn: (int) $matches[2],
realTime: (float) $matches[3],
wallTime: (float) $matches[4],
foundRows: (int) $matches[5],
sql: $matches[6],
iostats: $iostats,
);
return $line;
}
public function processFile(string $path) {
$fd = fopen($path, 'r');
if (!$fd)
return;
while (($rawLine = fgets($fd)) !== false) {
$line = $this->parseLine($rawLine);
yield $line;
}
fclose($fd);
}
}
foreach ($parser->processFile($argv[1]) as $line) {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment