apachectl - wie Server auf leichte Weise neustarten?
![](/uploads/default_avatar/thumb/missing.png)
- webserver
Hallo an alle,
nicht wenigen hier dürfte das Skript apachectl bzw. apache2ctl bekannt vorkommen.
Mit dem Aufruf "apache2ctl graceful" kann ich den Server auf "leichte" Art und Weise neustarten, sprich: Alle offenen Verbindungen werden bis zu ihrem Ende laufen gelassen und allmählich werden alle nicht-root Server-Instanzen gestoppt und durch neue Instanzen ersetzt - anders als bei "apache2ctl restart".
Das funktioniert perfekt, und wird es auch weiterhin.
Mein Problem ist nun: Für ein selbstgeschriebenes logrotate-Skript muss ich den Server neustarten, was ich am Besten über "apache2ctl graceful" machen möchte, da der Server so nach außen hin auch für die (kurze) Zeit des Neustarts verfügbar bleibt und bestehende Verbindungen nicht abgebrochen werden.
Aber: Die erfolgreiche Ausführung des Neustarts kann nicht direkt abgefragt werden (da die Instanzen des Apache erst nach und nach durch neue ersetzt werden).
Daher muss ich im logrotate-Skript nach dem Signal zum Neustarten des Servers eine Wartezeit einbauen (derzeit sind es 300 Sekunden).
Aber die Unsicherheit, dass Apache noch nicht komplett neu gestartet ist, bleibt.
Welche Möglichkeit gibt es, in einem Shell-Skript zu ermitteln, ob alle notwendigen Apache-Instanzen *wirklich* komplett neu gestartet sind? Diese Überprüfung könnte ich dann beispielsweise alle N Sekunden ausführen, um dann (bei erfolgreichem Neustart) weitere Aktionen durchzuführen.
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hellihello Marcel,
Mein Problem ist nun: Für ein selbstgeschriebenes logrotate-Skript muss ich den Server neustarten, was ich am Besten über "apache2ctl graceful" machen möchte, da der Server so nach außen hin auch für die (kurze) Zeit des Neustarts verfügbar bleibt und bestehende Verbindungen nicht abgebrochen werden.
Aber: Die erfolgreiche Ausführung des Neustarts kann nicht direkt abgefragt werden (da die Instanzen des Apache erst nach und nach durch neue ersetzt werden).
Leider habe ich darüber auch nur ein bissel gelesen. Ich hätte jetzt gedacht, dass der Apache als ein Prozess läuft und dieser Parent-Prozess eine ProzessID hätte und dieser Parentprozess erst dann gekillt wird, wenn alle laufenden (geforkten?) Prozesse beendet sind. Wäre dem so, könntest Du ja mittels einer while(1)-Schleife abfragen, ob Apache (bzw. der Prozess httpd) noch mit der alten PID läuft.
Daher muss ich im logrotate-Skript nach dem Signal zum Neustarten des Servers eine Wartezeit einbauen (derzeit sind es 300 Sekunden).
Aber die Unsicherheit, dass Apache noch nicht komplett neu gestartet ist, bleibt.
Welche Möglichkeit gibt es, in einem Shell-Skript zu ermitteln, ob alle notwendigen Apache-Instanzen *wirklich* komplett neu gestartet sind? Diese Überprüfung könnte ich dann beispielsweise alle N Sekunden ausführen, um dann (bei erfolgreichem Neustart) weitere Aktionen durchzuführen.
Dank und Gruß,
Hallo nochmals,
ich habe mir nun eine halbwegs vernünftige Lösung erstellt: Ein Shell-Skript, welches zuerst alle PIDs der "apache2"-Prozesse des Benutzers "www-data" sichert, dann einen Server-Neustart initialisiert und anschließend jede Sekunde überprüft, ob die Prozesse mit den PIDs noch existieren (denn die neuen Prozesse haben immer eine höhere PID).
Anschließend werden trotzdem noch 30 Sekunden Sicherheitspause eingelegt, da die beiden Zeilen "apache2pids=pgrep -U www-data apache2
" zusammen mit "apache2ctl -k graceful" keine atomare Operation (EN) darstellen.
In Ausnahmefällen könnte nämlich genau in der Mitte der beiden Operationen ein neuer Prozess gestartet werden, dessen PID nicht in der Variable $apache2ctl zu finden ist und der ergo auch nicht überprüft wird.
Gibt es eine Möglichkeit, diese kleine Ungereimtheit auch noch zu entfernen? Wenn ihr mir dabei helft haben wir nachher eine schöne Lösung gefunden, wie man einen Apache2-Server "nett" neustarten kann und trotzdem weiß wann er neu gestartet ist. :-)
Hier das Skript, wie ich es derzeit verwende:
#!/bin/bash
function someProcessesLeft () {
for pid in $@
do
if $(ps -p $pid > /dev/null)
then
return 0
fi
done
return 1
}
# -----------------------------------------------------------------------
echo "DO SOMETHING HERE (before Apache2 restart)"
# -----------------------------------------------------------------------
# Save processes and init restart
apache2pids=`pgrep -U www-data apache2`
apache2ctl -k graceful
while someProcessesLeft $apache2pids
do
sleep 1
echo -n "."
done
echo
echo "Waiting for 30 seconds to ensure the restart was successfully..."
sleep 30
# -----------------------------------------------------------------------
echo "DO SOMETHING HERE (after Apache2 restart)"
# -----------------------------------------------------------------------
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo,
ich habe mir nun eine halbwegs vernünftige Lösung erstellt: Ein Shell-Skript, welches zuerst alle PIDs der "apache2"-Prozesse des Benutzers "www-data" sichert, dann einen Server-Neustart initialisiert und anschließend jede Sekunde überprüft, ob die Prozesse mit den PIDs noch existieren (denn die neuen Prozesse haben immer eine höhere PID).
tut nichts zur Sache, also nur nebenbei: Diese Annahme ist falsch. Sind N Prozesse erzeugt worden, fährt das OS mit einer niedrigen Nummerierung fort.
[...]
Gibt es eine Möglichkeit, diese kleine Ungereimtheit auch noch zu entfernen?
Nein und es ist auch nicht hundertprozentig gesichert, daß während pgrep arbeitet, nicht keine Prozesse erzeugt werden.
Gruß aus Berlin!
eddi
Hallo Edgar,
ich habe mir nun eine halbwegs vernünftige Lösung erstellt: Ein Shell-Skript, welches zuerst alle PIDs der "apache2"-Prozesse des Benutzers "www-data" sichert, dann einen Server-Neustart initialisiert und anschließend jede Sekunde überprüft, ob die Prozesse mit den PIDs noch existieren (denn die neuen Prozesse haben immer eine höhere PID).
tut nichts zur Sache, also nur nebenbei: Diese Annahme ist falsch. Sind N Prozesse erzeugt worden, fährt das OS mit einer niedrigen Nummerierung fort.
Logischerweise. Aber dies ist im betrachteten Zeitraum sehr unwahrscheinlich.
[...]
Gibt es eine Möglichkeit, diese kleine Ungereimtheit auch noch zu entfernen?Nein und es ist auch nicht hundertprozentig gesichert, daß während pgrep arbeitet, nicht keine Prozesse erzeugt werden.
Ich weiß - daher ja der Timeout.
Man müsste ein Apache-Modul schreiben, dass diese Funktionalität zur Verfügung stellt - dann wäre es möglich.
Trotzdem funktioniert mein Backup-Skript für Logfiles sehr gut (da die betrachteten Fälle sehr unwahrscheinlich sind), und daher stelle ich es hier jedem, der es brauchen kann, hiermit zur Verfügung:
#!/bin/bash
# Options
target="/var/www"
safewaittime=30
function someProcessesLeft () {
for pid in $@
do
if $(ps -p $pid > /dev/null)
then
return 0
fi
done
return 1
}
if test `whoami` != "root"; then
echo "Error: Must be root to run this script."
exit 1
fi
cd $target
echo "Moving log files"
for dir in *; do
if `test -d "$dir"`; then
if `test -d "$dir"/logs`; then
if `test -f "$dir"/logs/access_log`; then
mv "$dir"/logs/access_log "$dir"/logs/access_log.temp
fi
if `test -f "$dir"/logs/error_log`; then
mv "$dir"/logs/error_log "$dir"/logs/error_log.temp
fi
fi
fi
done
echo "Giving Apache2 the order to restart"
# Save processes and init restart
apache2pids=`pgrep -U www-data apache2`
apache2ctl -k graceful
echo "Waiting for Apache2 to restart..."
while someProcessesLeft $apache2pids
do
sleep 5
echo -n "."
done
echo
echo "Waiting $safewaittime more seconds to ensure the restart is fulfilled..."
sleep $safewaittime
for dir in *; do
if `test -d "$dir"`; then
if `test -d "$dir"/logs`; then
echo "Compressing log files for \"$dir\"";
if `test -f "$dir"/logs/access_log.temp`; then
nice gzip -c "$dir"/logs/access_log.temp >> "$dir"/logs/access_log.old.gz;
rm "$dir"/logs/access_log.temp;
fi
if `test -f "$dir"/logs/error_log.temp`; then
nice gzip -c "$dir"/logs/error_log.temp >> "$dir"/logs/error_log.old.gz;
rm "$dir"/logs/error_log.temp;
fi
fi
fi
done
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Moin!
tut nichts zur Sache, also nur nebenbei: Diese Annahme ist falsch. Sind N Prozesse erzeugt worden, fährt das OS mit einer niedrigen Nummerierung fort.
Logischerweise. Aber dies ist im betrachteten Zeitraum sehr unwahrscheinlich.
Das würde ich nicht unbedingt sagen.
Es gibt zwei Fälle, in denen diese Annahme scheitert:
1. Es gibt schon in normalen Kerneln eine maximale PID, Werte darüber sind nicht erlaubt, es wird die nächste freie PID gesucht, die ab 1 wieder verfügbar ist. Die Wahrscheinlichkeit ist nach längerer Uptime des Servers durchaus als hoch anzusehen.
2. Gehärtete Kernel vergeben die PIDs unter Umständen nach einem Zufallsprinzip, um es Angreifern nicht zu erlauben, auf vorhersehbare PIDs zu treffen.
Da dein Skript alle PIDs betrachtet, und keine Annahmen über ein Maximum oder Minimum trifft, hat dieses Detail keinen Einfluß.
- Sven Rautenberg
Hallo Sven,
tut nichts zur Sache, also nur nebenbei: Diese Annahme ist falsch. Sind N Prozesse erzeugt worden, fährt das OS mit einer niedrigen Nummerierung fort.
Logischerweise. Aber dies ist im betrachteten Zeitraum sehr unwahrscheinlich.
Das würde ich nicht unbedingt sagen.
Es gibt zwei Fälle, in denen diese Annahme scheitert:
Es gibt schon in normalen Kerneln eine maximale PID, Werte darüber sind nicht erlaubt, es wird die nächste freie PID gesucht, die ab 1 wieder verfügbar ist. Die Wahrscheinlichkeit ist nach längerer Uptime des Servers durchaus als hoch anzusehen.
Gehärtete Kernel vergeben die PIDs unter Umständen nach einem Zufallsprinzip, um es Angreifern nicht zu erlauben, auf vorhersehbare PIDs zu treffen.
Stimmt, so habe ich das noch gar nicht betrachtet. Aber wie du bereits schriebst:
Da dein Skript alle PIDs betrachtet, und keine Annahmen über ein Maximum oder Minimum trifft, hat dieses Detail keinen Einfluß.
Genau so ist es. :)
Das einzige Problem, das auftreten könnte, ist eben dass zwischen dem Ermitteln der PIDs und dem Neustart-Signal an den Apache neue Apache-Prozesse dazukommen könnten - die dann nicht überwacht werden.
Daher habe ich noch 30 Sekunden Wartezeit eingebaut (die man ja auch noch variieren kann) - eine 100%ige Sicherheit gibt es hier trotzdem nicht.
Bevor ich vergesse, das noch zu erwähnen - wer es noch nicht durch Lesen des Skriptes herausgefunden hat:
Die Log-Dateien müssen "access_log" und "error_log" heißen, und sie müssen alle in folgenden Ordnern liegen:
/var/www/<Ordner>/logs/
Dies habe ich so eingerichtet, da ich bei mir eine VirtualHost-Umgebung mit Ordnern der Form
/var/www/example.com/htdocs/
und
/var/www/example.com/logs/
eingerichtet habe.
Lässt sich aber natürlich leicht an eure Bedürfnisse anpassen. :-)
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo Marc!
Ich habe es (auf Windows) mit einem Perl-Skript gelöst, das ich in den Taskplaner als geplanten Taskt mit Startzeit 00:00 Uhr eingefügt habe.
Da ich keine Ahnung habe, wie man unter Windows PIDs abfragen kann, nutze ich Win32::Process um den Apache zu stoppen und wieder zu starten. Das Problem dabei ist, dass der Apache beim Stop richtig gekillt wird, es dauert also ca. 20-30 Sekunden, bis er wieder zur Verfügung steht. Für den privaten Gebrauch ist es aber so hinnehmbar, denke ich.
Es werden Tageslogs erstellt, die zu Beginn eines neuen Monats noch gezippt werden, und zwar in je ein Verzeichnis für error und access-logs.
Bevor wieder die Bemerkung kommt ;)... das mit den Piped Logs habe ich unter Windows nicht zum Laufen bekommen (lauter Fehlermeldungen), daher habe ich mein eigenes Perl-Süppchen gekocht (selbst gekocht schmekt eh viel besser).
Falls jemand Interesse hat, kann ich das Skript vorstellen, sind hier und da sicher noch Verbesserungen denkbar!
Viele Grüße aus Frankfurt/Main,
Patrick
Hi,
Mein Problem ist nun: Für ein selbstgeschriebenes logrotate-Skript
Du hast das Rad neu erfunden?
http://httpd.apache.org/docs/1.3/logs.html#rotation
(auch das bei Piped Logs direkt drunter lesen!)
cu,
Andreas
Hallo MudGuard,
Mein Problem ist nun: Für ein selbstgeschriebenes logrotate-Skript
Du hast das Rad neu erfunden?
http://httpd.apache.org/docs/1.3/logs.html#rotation
(auch das bei Piped Logs direkt drunter lesen!)
rotatelogs (mit Pipe) habe ich verwendet bevor ich das neue Skript geschrieben habe. Mir hat einfach die Methode gefehlt alle Log-Einträge in einer einzigen komprimierten Datei abzulegen.
Aber trotzdem danke für die Erwähnung - andere fangen damit garantiert mehr an als ich. :-)
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Moin Moin!
Du hast das Rad neu erfunden?
Es lag mir auf der Zunge ...
(Funktioniert auch mit 2.0 und 2.2)
Siehe auch http://httpd.apache.org/docs/2.2/programs/rotatelogs.html#examples
(auch das bei Piped Logs direkt drunter lesen!)
rotatelogs (mit Pipe) habe ich verwendet bevor ich das neue Skript geschrieben habe. Mir hat einfach die Methode gefehlt alle Log-Einträge in einer einzigen komprimierten Datei abzulegen.
Piped Logs können genau das erledigen, OHNE dass Du den Server neu starten mußt. Die einzige Anforderung vom Apachen ist, dass das Programm an STDIN die Log-Zeilen einigermaßen flott einsammelt. Was es dann damit anstellt, ist dem Apachen egal. Es kann unkomprimierte Dateien schreiben und regelmäßig rotieren, dann hast Du rotatelogs. Es kann die Zeilen teilweise parsen und IP-Adressen in den Logs auflösen, dann hast Du logresolve. Es kann die Zeilen parsen, zerlegen und in eine Datenbank-Tabelle schreiben, dann hast Du SQL-basierendes Reporting. Oder es fügt die Log-Zeilen komprimiert an eine komprimierte Datei an.
Mir will nur nicht in den Kopf, was genau der Vorteil einer riesigen komprimierten Log-Datei sein soll. Sie ist schwer zu handhaben, weil man sie immer wieder dekomprimieren muß, sie ist irgendwann zu groß für gängige Transportmedien, erfordert ab einer gewissen Größe Unterstützung durch Betriebssystem und Dateisystemtreiber, und außer bei rsync werden beim Remote-Zugriff immer tonnenweise uralte Logs durchs Netzwerk geschleppt.
Für Reporting ist eine SQL-Tabelle deutlich einfacher. Auf Log-Dateien spezialisierte Reporting-Tools kommen auch mit mehreren Log-Dateien klar. Mehrere einzelne, unkomprimierte Log-Dateien sind jeweils kleiner und leichter zu transportieren. Klar, irgendwann sind alte Log-Dateien uninteressant und könnten komprimiert werden. Das wäre ein recht einfacher Patch für Apaches rotatelogs-Programm, das nach dem Wechsel auf eine neue Log-Datei gzip oder bzip2 abforkt und die alte Log-Datei komprimieren läßt. Währenddessen werden neue Log-Zeilen vom Apachen schon wieder in die neue, noch nicht komprimierte Log-Datei geschrieben.
Alexander
Hallo Alexander,
Piped Logs können genau das erledigen, OHNE dass Du den Server neu starten mußt.
Sie haben aber zwei große Nachteile:
Bei wenigen VHosts ist das noch relativ egal, bei vielen VHosts fällt das aber schon ins Gewicht.
Gut, bei den Access-Logs könnte man das im Prinzip noch irgendwie eindämmen (ein globales Log für alle Requests mit Info welcher VHost das ist + ein Script, das die aufteilt), aber bei den Error-Logs geht das schon wieder nicht mehr.
Viele Grüße,
Christian
Hallo Marc,
Welche Möglichkeit gibt es, in einem Shell-Skript zu ermitteln, ob alle notwendigen Apache-Instanzen *wirklich* komplett neu gestartet sind?
Für diesen Zweck ist es sinnvoll, einfach zu überprüfen, ob die Log-Dateien noch offen sind. Wenn dies der Fall ist, so ist der Apache noch nicht komplett neu gestartet - wenn alle Dateien bereits zu sind, schon.
Auf den SELF-Servern habe ich mir ein paar Python-Scripte für den Zweck programmiert. Hier die relevanten Ausschnitte:
lrutils.py: Hilfsfunktion, die überprüft, ob bestimmte Dateien noch offen sind:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Utility functions for rotating logfiles
import os
from stat import *
# Check whether any of the specified files is still in use.
# Will only work correctly if the files are only opened by programs run under
# the current user or when this script is run as root.
def filesInUse (files):
# Get Inode / Device number for all files to check and save them for
# later. Ignore non-existing files.
tocheck = []
for file in files:
try:
statinfo = os.stat (file)
tocheck.append ((statinfo[ST_INO], statinfo[ST_DEV]))
except OSError:
pass
# Nothing to check? No file in use
if not len (tocheck):
return False
# Search /proc
for pid in os.listdir ("/proc"):
# Only enter PID-type directories
if not pid.isdigit(): continue
try:
# Get all file descriptors for the process and compare
# the inode and device numbers with the inode and
# device numbers of the files we want to check. If at
# least one file is already open, we're done.
for fd in os.listdir ("/proc/%s/fd" % pid):
try:
statinfo = os.stat ("/proc/%s/fd/%s" % (pid, fd))
if tocheck.count ((statinfo[ST_INO], statinfo[ST_DEV])) > 0:
return True
except OSError:
# Ignore access errors
pass
except OSError:
# Ignore access errors
pass
# None of the files was found to be open
return False
rotatelogs.py (Teile davon zumindest): Rotieren von Logfiles
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Rotate logfiles
# Import needed modules
import lrutils, os, time, glob, sys
# Initial period to wait if not closed immediately
interval1 = 20
# Interval to wait subsequently
interval = 60
# The logfiles to copy
logfiles = ['/var/log/apache2/access_log', '/var/log/apache2/error_log', '/var/log/apache2/access_log.*', '/var/log/apache2/error_log.*']
# Get logfiles to rotate
logfiles = reduce (lambda x, y: x+y, [glob.glob(y) for y in logfiles])
rotated = [x + '.rotated' for x in logfiles]
# Rotate all logfiles
for logfile in logfiles:
os.rename (logfile, logfile + '.rotated')
# Reload apache
os.system ('/usr/sbin/apache2ctl graceful')
# Now definitely sleep at least 1 second - Apache will *never* be
# finished reloading *so* quickly
time.sleep (1);
# If logfiles are already closed: we're done
if not lrutils.filesInUse (rotated):
# Stelle etwas mit den rotierten Logfiles an
sys.exit (0)
# If not, wait first interval
time.sleep (interval1)
# While logfiles are still open: wait normal interval
while lrutils.filesInUse (rotated):
# Do another reload because sometimes apache does not close the logs
# for some reason.
os.system ('/usr/sbin/apache2ctl graceful')
time.sleep (interval)
# Stelle was mit den rotierten Logfiles an
Was macht der Code hier?
Die Logfiles werden von $logfile nach $logfile.rotated umbenannt. Der Apache schreibt dann natürlich in die .rotated-Dateien, da der Kernel sich nur um die Inode-Nummern kümmert.
Dem Apache wird ein graceful geschickt. Er macht dann auf jeden Fall die neuen Logfiles auf (d.h. im Verzeichnis existieren $logfile und $logfile.rotated).
In mehreren regelmäßigen Intervallen überprüft das Script, ob die $logfile.rotated noch in Gebrauch sind. Wenn dies nicht der Fall ist, hat der Apache alle Logs zugemacht und das Script kann etwas mit den Logs anstellen (das habe ich hier ausgelassen, weil das SELF-Server-spezifisch ist - wir verschieben die alle auf einen einzigen Server, lassen dort das Statistikprogramm drüberlaufen und löschen die dann allesamt).
Was noch auf meiner TODO-Liste hierfür steht (allerdings ziemlich weit unten, da nicht kritisch), wäre eine Möglichkeit, nach soundsolanger Zeit (ein paar Stunden z.B.) auch einen restart zu schicken, wenn die Logs dann immer noch nicht freigegeben wurden.
Wenn jemand was mit dem Code anfangen will, ich stelle ihn (sofern er überhaupt eine Schöpfungshöhe erreicht) unter die MIT-Lizenz.
Viele Grüße,
Christian
Hallo Christian,
Welche Möglichkeit gibt es, in einem Shell-Skript zu ermitteln, ob alle notwendigen Apache-Instanzen *wirklich* komplett neu gestartet sind?
Für diesen Zweck ist es sinnvoll, einfach zu überprüfen, ob die Log-Dateien noch offen sind. Wenn dies der Fall ist, so ist der Apache noch nicht komplett neu gestartet - wenn alle Dateien bereits zu sind, schon.
Ja, das macht Sinn - damit wäre das Problem elegant gelöst - denn der entscheidende Moment für das Logrotate-Skript ist ja genau dann gekommen, wenn alle betroffenen Log-Dateien nicht mehr gelesen werden.
Auf den SELF-Servern habe ich mir ein paar Python-Scripte für den Zweck programmiert.
Ja, der Python-Code ist sehr schick - aber da ich Python noch nicht kann (ist eine Sprache, die ich in Zukunft erlernen will), werde ich die Idee wohl zunächst in mein Shell-Skript übernehmen.
Was noch auf meiner TODO-Liste hierfür steht (allerdings ziemlich weit unten, da nicht kritisch), wäre eine Möglichkeit, nach soundsolanger Zeit (ein paar Stunden z.B.) auch einen restart zu schicken, wenn die Logs dann immer noch nicht freigegeben wurden.
Meinst du damit einen harten restart - oder wieder einen "graceful" restart?
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo Marc,
Was noch auf meiner TODO-Liste hierfür steht (allerdings ziemlich weit unten, da nicht kritisch), wäre eine Möglichkeit, nach soundsolanger Zeit (ein paar Stunden z.B.) auch einen restart zu schicken, wenn die Logs dann immer noch nicht freigegeben wurden.
Meinst du damit einen harten restart - oder wieder einen "graceful" restart?
Eine harten »restart«. Einen »graceful« schicke ich ja in meinem jetztigen Script sowieso alle paar Minuten.
Viele Grüße,
Christian
Hallo,
ich werf das jetzt einfach mal in den Raum, weil ich mich direkt wunder wieviel Umstände sich hier manche machen...
Ich handhabe das auf meinem Server so, dass nachts die Logfiles einfach ausgelesen und in eine neue Datei mit Datum versehen geschrieben werden. Danach schreibe ich schlichtweg einen leeren String in die Log-Datei des Apachen.
Das alles funktioniert problemlos, obwohl der Apache dabei läuft.
Mir ist klar, dass in der Zeit wo ich die Logdatei kopiere und sie dann lösche theoretisch ein neuer Eintrag eingetragen worden sein kann, aber damit kann ich leben - die Chance dazu ist auf meinem Server nachts sehr gering.
Wo ist der Fehler, den ich hier mache?
Hallo RFZ,
ich werf das jetzt einfach mal in den Raum, weil ich mich direkt wunder wieviel Umstände sich hier manche machen...
Ich handhabe das auf meinem Server so, dass nachts die Logfiles einfach ausgelesen und in eine neue Datei mit Datum versehen geschrieben werden. Danach schreibe ich schlichtweg einen leeren String in die Log-Datei des Apachen.
Das alles funktioniert problemlos, obwohl der Apache dabei läuft.
Fast richtig. Das alles funktioniert problemlos, solange nicht der unwahrscheinliche (aber mögliche) Fall eintritt, dass ein Prozess schreibt während der andere liest.
Mir ist klar, dass in der Zeit wo ich die Logdatei kopiere und sie dann lösche theoretisch ein neuer Eintrag eingetragen worden sein kann, aber damit kann ich leben - die Chance dazu ist auf meinem Server nachts sehr gering.
Wo ist der Fehler, den ich hier mache?
Im glücklichen Fall passiert dann das, was du vorhergesagt hast: Es gehen Informationen verloren.
Wenn du Pech hast kannst du hierdurch aber etwa fehlerhafte Log-Einträge erzeugen (die beispielsweise in der Mitte abgeschnitten sind) und die dann dem Log-File-Auswerter Probleme machen könnten.
Im schlimmsten Fall könnte eventuell Apache abstürzen (bitte korrigiert mich falls dies so nicht stimmt).
Sagen wir mal so: Hier siehst du, wie du es besser machen kannst - also pass deine Skripte doch bei Gelegenheit einfach an, um unwahrscheinliche aber mögliche Ungereimtheiten schon jetzt aus dem Weg zu räumen. :-)
Grüße
Marc Reichelt || http://www.marcreichelt.de/