PHP: Auslesen der Logs des Apachen (mehrere)
Autor: Ralf v.d.Mark
eingetragen: Mittwoch, 12. August 2020 um 12:49 Uhr (33/2020 Kalenderwoche)
geändert: Montag, 22. Januar 2024 um 16:43 Uhr (4/2024 Kalenderwoche)
Keywords: Error logdatei apache access debugging reporting Fehlermeldungen
Kategorien: PHP,
Text:
Den Inhalt aus dem Feld Quellcode in eine neue Datei "/php_show_errorlog.php" im public-Ordner speichern führt zum Lesen der Logs (Error/Access) eines jeden ANGEBOTs.
/var/log/httpd/ANGEBOTSNAME.dev.as.ble.de-ssl-error.log
/var/log/httpd/ANGEBOTSNAME.dev.as.ble.de-ssl-access.log
[Thu Mar 26 12:19:57.350770 2020]...
siehe auch "PHP-Error-Meldungen ausgeben"
alte Version "Apache-Error-Log ausgeben"
Und ganz nebenbei zeigt sie auch noch die PHP-Info (phpinfo()) und die Server-Parameter ($_SERVER) an.
Quellcode:
<?php
/**
* Diese Datei liest die Error-Logs aus, zeigt PHP-Info und Server-Variablen an.
*
* Der Aufruf sollte standardmäßig
* https://ANGEBOTSNAME.dev.se.ble.de/php_show_errorlog.php
*
* PHP version 8
*
* @name php_show_errorlog.php
* mit Pfad: php_show_errorlog.php
* @author Ralf von der Mark (vdM), Ref. 223 (Entwicklung), BLE <Ralf.vonderMark@BLE.de>
* @copyright 2024, BLE
* @version siehe Konstante VERSION_UND_DATUM, GIT: Yes
*/
define('VERSION_UND_DATUM', '*1.0.4* vom 22.01.2024');
define('VERZNS_LOG_FILES', '/var/log/httpd/');
define('VHOST', $_SERVER['HTTP_HOST']);
define('STANDRD_DATEI_1', VHOST . '-ssl-error.log');
define('STANDRD_DATEI_2', VHOST . '-error.log');
define('NAME_DIESER_DATEI', basename($_SERVER['PHP_SELF']));
define('LOG_TAGE_ZURUECK', 30);
//-- Änderung von Macky Deutsche Uhrzeit setzten
date_default_timezone_set('Europe/Berlin');
setlocale (LC_TIME, "de_DE");
function DownloadGrosseDatei($dateiUndPfad)
{
//Header manipulieren
header('Content-Type: application/octet-stream; charset=UTF-8');
//Jetzt noch Dateiname und Typ festlegen:
header('Content-Disposition: attachment; filename="' . basename($dateiUndPfad) . '"');
//Datei als Stream ausgeben
downloadStueckweise($dateiUndPfad);
exit();//Stopp!!
}//ENDE: function DownloadGrosseDatei(...)
define('STUECK_GROESSE', 1024 * 1024);//Größe (in bytes) eines Stücks
//Große Datei als Stream byte für byte auslesen
//https://stackoverflow.com/questions/6914912/streaming-a-large-file-using-php
function downloadStueckweise($filename, $retbytes = true)
{
$buffer = '';
$cnt = 0;
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$buffer = fread($handle, STUECK_GROESSE);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
if (isset($_GET['submitDownload']) && !empty($_GET['logFile'])) {
$pfadUndDatei = VERZNS_LOG_FILES . strip_tags($_GET['logFile']);
if (file_exists($pfadUndDatei)) {
//Datei vorhanden!
DownloadGrosseDatei($pfadUndDatei);
} else {
//Wenn die Datei nicht vorhanden ist, dann...
exit('<h1>Sie haben einen Fehler verursacht!</h1>');
}//ENDE: else ==> if (file_exists())
}//ENDE: if (!empty($_GET['download']))
/**
* Funktion um eine Byte-Größe in KB, GB etc. umzurechnen
*
* @param $groesseRoh
* @param $stellenHinterKomma
*
* @return string
*/
function lesbare_dateigroesse($groesseRoh,
$stellenHinterKomma = 2,
$htmlTagName = 'span',
$htmlTagZusatz = '')
{
/* VORSICHT: (int) funktioniert auf 32Bit-Systeme nur bis 2.147.483.647 Byte */
$groesseRoh = (float)$groesseRoh;
if ($groesseRoh >= 1073741824) {
$rueckg = round(($groesseRoh / 1073741824), $stellenHinterKomma) . ' GB';
} elseif ($groesseRoh >= 1048576) {
$rueckg = round(($groesseRoh / 1048576), $stellenHinterKomma) . ' MB';
} elseif ($groesseRoh >= 1024) {
$rueckg = round(($groesseRoh / 1024), $stellenHinterKomma) . ' KB';
} else {
$rueckg = $groesseRoh . " Byte";
}
return '<' . $htmlTagName . ' title="' . $groesseRoh . ' Bytes"' . $htmlTagZusatz
. '>' . str_replace('.', ',', $rueckg) . '</' . $htmlTagName . '>';
}/* function lesbare_dateigroesse(...) */
/**
* Produziert ein Array mit möglichen Dateinamen und Testet, ob diese vorhanden sind.
* Rückgabe: Listet die gefundenen Dateien sortiert im Array auf!
* Da das Verzeichnisauflisten für den User verboten ist, muss man es auf diese Weise probieren.
*
* PHP version 8
*
* @return array
*/
function gibtDateienImArray()
{
if (!is_dir(VERZNS_LOG_FILES)) {
echo '<h1 style="font-size: 3em; color: red; background-color: yellow;">
Achtung: Das Verzeichnis "' . VERZNS_LOG_FILES
. '" existiert nicht oder ist nicht lesebar!</h1>';
}//ENDE: if (is_readable(VERZNS_LOG_FILES))
$vorlageDateienArray = [
VHOST . '-ssl-access.log',
VHOST . '-ssl-access.log.1',
VHOST . '-ssl-error.log',
VHOST . '-ssl-error.log.1',
'ssl-error.log',
'ssl-error.log.1',
'ssl-access.log',
'ssl-access.log.1',
'error_log',
'error_log.1',
'access_log',
'access_log.1'
];
for ($zaehlr = 2; $zaehlr <= LOG_TAGE_ZURUECK; $zaehlr++) {
$vorlageDateienArray[] = 'ssl-access.log.' . $zaehlr . '.gz';
$vorlageDateienArray[] = 'ssl-error.log.' . $zaehlr . '.gz';
$vorlageDateienArray[] = VHOST . '-ssl-access.log.' . $zaehlr . '.gz';
$vorlageDateienArray[] = VHOST . '-ssl-error.log.' . $zaehlr . '.gz';
$vorlageDateienArray[] = 'access_log.' . $zaehlr . '.gz';
$vorlageDateienArray[] = 'error_log.' . $zaehlr . '.gz';
$vorlageDateienArray[] = VHOST . '-access_log.' . $zaehlr . '.gz';
$vorlageDateienArray[] = VHOST . '-error_log.' . $zaehlr . '.gz';
}//ENDE: for ($zaehlr = 1; $zaehlr <= 10; $zaehlr++)
natsort($vorlageDateienArray);
/* Dynamischer-Kommentar: Ersten Schraegen (/) der beiden wegloeschen bzw. hinschreiben!
echo '<br style="display: inline;">
[$vorlageDateienArray-Array-Count: '.count($vorlageDateienArray).']
<br style="display: inline;">
<pre style="display: inline;">Ausgabe des $vorlageDateienArray-'
.print_r($vorlageDateienArray, true)
. '</pre>
<br style="display: inline;">ENDE der $vorlageDateienArray-Array-Ausgabe';
exit('<br style="display: inline;">exit()');//*/
$inhalt = [];
foreach ($vorlageDateienArray as $eineDatei) {
if (is_file(VERZNS_LOG_FILES . $eineDatei) && is_readable(VERZNS_LOG_FILES . $eineDatei)) {
$filesize = filesize(VERZNS_LOG_FILES . $eineDatei);
$filemtime = filemtime(VERZNS_LOG_FILES . $eineDatei);
if (!defined('START_DATEI')
&& ($eineDatei == STANDRD_DATEI_1 || $eineDatei == STANDRD_DATEI_2)) {
define('START_DATEI', $eineDatei);
$standard = 1;
} else {
$standard = 0;
}//ENDE: else ==> if ($eineDatei == STANDRD_DATEI_1 || $eineDatei == STANDRD_DATEI_2)
$inhalt[$eineDatei] = ['name' => $eineDatei,
'size' => $filesize,
'groesse' => lesbare_dateigroesse($filesize, 2),
'time' => $filemtime,
'zeitpunkt' => date('d.m.Y H:i', $filemtime),
'standard' => $standard
];
}//ENDE: if (is_file() && is_readable())
}
return $inhalt;
}//ENDE: function gibtDateienImArray(...)
//Loop des Verzeichnisses in Array packen für Selectbox und If-Prüfung
$verzeichnsArray = gibtDateienImArray();
/* Dynamischer-Kommentar: Ersten Schraegen (/) der beiden wegloeschen bzw. hinschreiben!
echo '<br style="display: inline;">
[$verzeichnsArray-Array-Count: ' . count($verzeichnsArray) . ']
<br style="display: inline;">
<pre style="display: inline;">Ausgabe des $verzeichnsArray-'
. print_r($verzeichnsArray, true)
. '</pre>
<br style="display: inline;">ENDE der $verzeichnsArray-Array-Ausgabe';
exit('<br style="display: inline;">exit()');//*/
//Mögliche Lodateien anzeigen
if (isset($_GET['logFile']) && array_key_exists($_GET['logFile'], $verzeichnsArray)) {
//zum Beispiel: 'biosiegel-int.dev.as.ble.de-ssl-access.log.10.gz':
define('DATEI_2_DISPLAY', strip_tags($_GET['logFile']));
} elseif (defined('START_DATEI')) {
//Standardwert!
define('DATEI_2_DISPLAY', START_DATEI);
} else {
define('DATEI_2_DISPLAY', 'nix');
}//ENDE: else ==> if (!empty($_POST['logFile']))
$pfadUndDatei4Disply = VERZNS_LOG_FILES . DATEI_2_DISPLAY;
$selectBoxOptions = null;
foreach ($verzeichnsArray as $keyFileName => $werteArray) {
if (!defined('LOGDATEI_GEFUNDN')
&& empty($_GET['logFile']) && $werteArray['standard'] == 1) {
$selected = ' selected="selected"';
$markiert = 'Standard => ';
} elseif (!defined('LOGDATEI_GEFUNDN')
&& !empty($_GET['logFile']) && $_GET['logFile'] == $keyFileName) {
$selected = ' selected="selected"';
$markiert = '===> ';
} else {
$selected = null;
$markiert = null;
}//ENDE: else ==> if (empty($_GET['']))
if ($werteArray['standard'] == 1) {
$markiert = 'Standard => ';
}//ENDE: if ($werteArray['standard'] == 1)
$selectBoxOptions .= '
<option value="' . $keyFileName . '"' . $selected . '>' . $markiert
. $werteArray['name'] . ' (' . $werteArray['zeitpunkt'] . ', ' . $werteArray['groesse']
. ')</option>';
if (!defined('LOGDATEI_GEFUNDN') && !empty($selected)) {
define('LOGDATEI_GEFUNDN', $keyFileName);
}//ENDE: if (!defined('LOGDATEI_GEFUNDN') && !empty($selected))
}//ENDE: foreach ($verzeichnsArray as $keyFileName => $werteArray)
if (!empty($_GET['php']) && $_GET['php'] === 'info') {
//Um die PHP-Info anzuzeigen:
phpinfo(INFO_ALL);
exit();
}//ENDE: if (!empty($_GET['php']) && $_GET['php'] == 'info')
?><!DOCTYPE html>
<html lang="de">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>[Error-Log] <?= VHOST . ', ' . date('Y')
. ' (Version ' . VERSION_UND_DATUM . ')'; ?></title>
<style type="text/css">
div.austausch {
height: 44px;
width: 100%;
text-align: left;
position: relative;
padding-left: 22px !important;
margin-bottom: 6px;
background-color: #007342;
}
div.austausch span {
display: block;
overflow: hidden;
transition: all 500ms ease-in-out;
height: 44px;
}
div.austausch .default {
color: black;
background-color: aliceblue;
/* ADDED */
position: absolute;
left: 22px;
z-index: 10;
top: 0;
width: 100%;
height: 100%;
padding-left: 10px;
}
div.austausch .hover {
height: 44px;
color: white;
background-color: #007342;
}
div.austausch:hover .default {
height: 0px;
}
div.austausch a {
color: white;
background-color: #007342;
}
</style>
</head>
<body><a name="oben" id="oben"></a>
<div class="austausch" title="RELOAD - Datei neu laden...">
<h1>
<span class="default">Logdateien zu "<?= VHOST; ?>":</span>
<span class="hover"><a href="<?= NAME_DIESER_DATEI; ?>"
>Neustart: Aktuelle Log <?= VHOST; ?> laden...</a></span>
</h1>
</div><!-- ENDE: <div class="austausch"> -->
<form action="<?= NAME_DIESER_DATEI; ?>" method="get" accept-charset="utf-8">
<select name="logFile" id="logFile" onchange="this.form.submit();">
<?= $selectBoxOptions; ?>
</select>
<button type="submit" name="submitAnzeign" style="cursor: pointer;">Anzeigen</button>
<button type="submit" name="submitDownload" style="cursor: alias;">Download</button>
</form>
<?php
if (!empty($_GET['php']) && $_GET['php'] === 'server') {
//Um die PHP-Server-Variablen/Parameter anzuzeigen:
echo '<br style="display: inline;">
[$_SERVER-Array-Count: ' . count($_SERVER) . ']
<br style="display: inline;">
<pre style="display: inline;">Ausgabe des $_SERVER-'
. print_r($_SERVER, true)
. '</pre>
<br style="display: inline;">ENDE der $_SERVER-Array-Ausgabe';
exit();
}//ENDE: if (!empty($_GET['php']) && $_GET['php'] == 'server')
if (file_exists($pfadUndDatei4Disply)) {
echo '
<h1 style="display: inline; padding-right: 2em;"
>Error-Log: ' . htmlentities($pfadUndDatei4Disply) . '</h1>
<a href="#unten" style="border: 2px outset crimson;
background-color: aliceblue;
margin-left: 3em;
padding: 0.3em 1em;
text-decoration: none;
cursor: ns-resize;"
>⮇ nach unten ⮇</a>
<hr style="display: inline-block; visibility: inherit; width: 100%;">
<pre>';
$fileSizeLog = filesize($pfadUndDatei4Disply);
if ($fileSizeLog > 5000000) {
//Wenn die Datei kleiner als x (500000 = 0,5 MB) ist, verarbeiten...
echo '<h2>Achtung: Die Datei ist mit ' . lesbare_dateigroesse($fileSizeLog, 2) .
' zu groß!</h2>';
} elseif (!defined('LOGDATEI_GEFUNDN')) {
//da es nur weitergehen kann, wenn das vorhanden ist, wird hier noch mal geprüft.
echo 'Die Konstante "LOGDATEI_GEFUNDN" ist nicht vorhanden!!';
} elseif (substr(LOGDATEI_GEFUNDN, -3) === '.gz') {
//Wenn die Datei kleiner als x (500000 = 0,5 MB) ist, verarbeiten...
echo '<h2>Hinweis: Die Datei (' . lesbare_dateigroesse($fileSizeLog, 2) .
') ist als gzip gepackt und wurde geöffnet!</h2>';
$gzOpen = gzopen(VERZNS_LOG_FILES . LOGDATEI_GEFUNDN, 'r');
echo gzread($gzOpen, 5000000);
gzclose($gzOpen);//Schließt eine geöffnete gz-Datei
} else {
$file_handle = fopen(VERZNS_LOG_FILES . LOGDATEI_GEFUNDN, 'rb');
while (!feof($file_handle)) {
echo fgets($file_handle);
}
fclose($file_handle);
}//ENDE: else ==> if (!empty())
echo '</pre>';
$fund = 1;
}//if (file_exists($pfadUndDatei4Disply))
if (empty($fund)) {
//Wenn $fund leer ist, wurde keine Datei gefunden!!
echo '<h1 style="color: red; text-decoration: underline;"
>Keine Error-Logs gefunden! </h1>
<h2>Keine Datei gefunden! Auch nicht:
<br> - <span style="color: blue;">' . VERZNS_LOG_FILES . STANDRD_DATEI_1 . '</span>
<br> - <span style="color: blue;">' . VERZNS_LOG_FILES . STANDRD_DATEI_2 . '</span>
</h2>';
}//ENDE: if (empty($fund))
//-- Änderung von Macky Datum auf Deutsch
//-- Vorher mit PHP Funktion: date -> date('D.\, d.m.Y \u\m H:i:s') . ' Uhr
echo '<hr style="display: inline-block; visibility: inherit; width: 100%;">
<p>Seitenaufruf: ' . date('D, d.m.Y \u\m H:i') . ' Uhr
<a href="#oben" id="unten" style="border: 2px outset crimson;
background-color: aliceblue;
margin-left: 2em;
padding: 0.3em 1em;
text-decoration: none;
cursor: ns-resize;"
>⮅ nach oben ⮅</a>
<a href="?logFile='
. (defined('LOGDATEI_GEFUNDN') ? urlencode(LOGDATEI_GEFUNDN) : 'nix')
. '&a=' . time() . '#unten" style="border: 2px outset crimson;
background-color: aliceblue;
margin-left: 3em;
padding: 0.3em 1em;
text-decoration: none;
cursor: progress;"
>⭯ Reload ⭮</a>
<a href="' . NAME_DIESER_DATEI . '?php=info" style="border: 2px outset crimson;
background-color: blanchedalmond;
margin-left: 7em;
padding: 0.3em 0.2em;
text-decoration: none;
cursor: help;"
>😇 PHP-Info anzeigen 😵</a>
<a href="' . NAME_DIESER_DATEI . '?php=server" style="border: 2px outset crimson;
background-color: blanchedalmond;
margin-left: 3em;
padding: 0.3em 0.2em;
text-decoration: none;
cursor: progress;"
>😇 $_SERVER-Params anzeigen 😵</a></p>
<hr style="display: inline-block; visibility: inherit; width: 100%;">
<p><strong>Version ' . VERSION_UND_DATUM . ' dieser Datei (' . $_SERVER["SCRIPT_FILENAME"] . ').</strong></p>';
/* Tauscht böse Wörter aus: */
function ripli($wert)
{
return str_ireplace(chr(87) . chr(69) . chr(66)
. chr(70) . chr(73)
. chr(76) . chr(69) . chr(77)
. chr(65) . chr(78)
. chr(65) . chr(71) . chr(69)
. chr(82), 'DATEI',
str_ireplace(chr(87) . chr(70)
. chr(77), 'DATEI',
str_ireplace(chr(86) . chr(68)
. chr(77), 'i',
$wert)));
}//ENDE: function ripli(...)
?></body>
</html>