Malcolm Beck´s: Errorlog erweitern

hi,

ich hab das PHP-Interne error_log ein wenig erweitert und würde gerne eure Meinungen bzw. verbesserungsvorschläge dazu einholen.

Sinn ist der, dass ich mir eine möglichkeit geschaffen habe, die error_logs möglichst Flexibel im Admin-Backend auszuwerten.

  /*  
   * Param $_content: Die Fehlermeldung, bspw. Error 404 - not found  
   * Param $_connect: Datenbankverbindung, um Mysql-Fehler abzufragen  
   * Param $_errfile: Die Errorlog-Datei  
  */  
  function my_errorlog ($_content,$_connect,$_errfile=ErrorLogFile)  
  {  
    /*  
     * Prüfen, ob die Errorlog-Datei die vorgegebene Max.-Grösse überschreitet  
    */  
    if (file_exists($_errfile))  
      if (filesize($_errfile) >= 1610612736)  # 1610612736 Bytes ca. 1,5 GB -- Limit für die Error-Logs  
                                              # Wenn Limit erreicht, versuch die Datei zu löschen  
        /*  
         * Wenn löschen Erfolgreich, neue Errorlog-Datei anlegen und die Löschung der Alten Datei im neuen Errorlog speichern  
        */  
        if (unlink ($_errfile))  
          return error_log(sprintf("[%s] |>Error: Errolog zu Gross, Datei gelöscht\n"  
                                  , date("d M Y H:i:s")), 3, $_errfile);  
        /*  
         * Wenn löschen nicht geklappt hat, speichern  
        */  
        else  
          return error_log(sprintf("[%s] |>Error: Errorlog zu Gross, löschen Fehlgeschlagen\n"  
                                  , date("d M Y H:i:s")), 3, $_errfile);  
    /*  
     * Auftretende Fehler im gewünschten Format speichern  
    */  
    return error_log(sprintf("[%s] |>Error: %s |>Link: %s %s\n"  
                   , date("d M Y H:i:s")  
                   , $_content  
                   , $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ## URI speichern, in dem der Fehler aufgetreten ist  
                   /*  
                    * Wenn es einen mysql-error gibt, auch speichern, andernfalls Leer lassen  
                   */  
                   , (($_connect->error OR mysqli_connect_error()) ? '|>mysqli-Error: ' . $_connect->error . mysqli_connect_error() : '' )  
                   ), 3, $_errfile);  
  }

Aufruf:

  
# Errorlog definieren  
ini_set('error_log', 'error/error_log.inc.php');   ## Error-Log  
define('ErrorLogFile', ini_get('error_log'));      ## Error-Log-Pfad  
  
if (!$dbResult) ## Nur ein Beispiel  
  my_errorlog ('Seite existiert nicht, Error 404', $_DBconnect);

Was könnte da noch mit rein, was würde Sinn machen?

mfg

--
echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
array(2) {
  ["SELFCODE"]=>
  string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
  ["Meaningful"]=>
  string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
}
  1. Moin Moin!

    Wenn Limit erreicht, versuch die Datei zu löschen

    * Wenn löschen Erfolgreich, neue Errorlog-Datei anlegen und die Löschung der Alten Datei im neuen Errorlog speichern

    Was könnte da noch mit rein, was würde Sinn machen?

    Warum willst Du die alte Datei unbedingt löschen? Damit machst Du es Angreifern einfacher, ihre Spuren zu verwischen. Benenn die alte Datei um und lege eine neue Datei an. Komprimiere die alte Datei, wenn Du Platz sparen willst.

    Weil das wirklich oft gebraucht wird, haben sich ein paar Leute dafür schon Tools gebaut, die auch die kleinen Gemeinheiten berücksichtigen. logrotate ist so ein Tool, das so ziemlich jedes Logfile durchrotiert und die entsprechenden Programme ggf. über das neue Logfile informiert. Apaches rotatelogs  und DJBs multilog arbeiten genau anders herum: Sie werden STATT des Logfiles per Pipe angesprochen und kümmern sich selbständig um das Rotieren der Logfiles. rotatelogs wird vom loggenden Programm (in aller Regel httpd) selbst gestartet, das loggende Programm schreibt in die selbst angelegte Pipe. multilog wird von einem Service-Manager (supervise via svscan) gestartet und überwacht, das loggende Programm schreibt stumpf nach STDOUT oder STDERR.

    Also erfinde nicht das Rad zum Milliardsten Mal neu, nutze fertige Tools.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
    1. hi,

      Warum willst Du die alte Datei unbedingt löschen? Damit machst Du es Angreifern einfacher, ihre Spuren zu verwischen. Benenn die alte Datei um und lege eine neue Datei an. Komprimiere die alte Datei, wenn Du Platz sparen willst.

      Auf diese Idee bin ich garnicht gekommen, Danke für den Hinweis, werde es heute Nacht anpassen.

      Weil das wirklich oft gebraucht wird, haben sich ein paar Leute dafür schon Tools gebaut, die auch die kleinen Gemeinheiten berücksichtigen. logrotate ist so ein Tool, das so ziemlich jedes Logfile durchrotiert und die entsprechenden Programme ggf. über das neue Logfile informiert. Apaches rotatelogs  und DJBs multilog arbeiten genau anders herum: Sie werden STATT des Logfiles per Pipe angesprochen und kümmern sich selbständig um das Rotieren der Logfiles. rotatelogs wird vom loggenden Programm (in aller Regel httpd) selbst gestartet, das loggende Programm schreibt in die selbst angelegte Pipe. multilog wird von einem Service-Manager (supervise via svscan) gestartet und überwacht, das loggende Programm schreibt stumpf nach STDOUT oder STDERR.

      Danke für die Links, die muss ich mir mal in Ruhe anschauen und sehen, was für mich nützlich sein kann.

      Also erfinde nicht das Rad zum Milliardsten Mal neu, nutze fertige Tools.

      Das Problem bei mir ist, dass ich nicht nur PHP-Interne Fehler abfangen möchte, sondern auch solche, die mein CMS verusacht, wie Bspw. 404er Seiten, oder 410er, ohne die Logs dafür auszuwerten.

      Ich hab mal, um den Einsatz der Funktion zu zeigen, meine index.php ein wenig gekürzt:

      http://dj-tut.de/z_test/selfhtml/on_index.php

      Für meine Zwecke ist diese Funktion an sich schon sehr Praktisch und vor allem Schlank.

      mfg

      --
      echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
      array(2) {
        ["SELFCODE"]=>
        string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
        ["Meaningful"]=>
        string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
      }
      1. hi,

        Tom und Alexander,

        ich Danke euch beiden für die Links, allerdings helfen mir die Tipps nicht wirklich weiter, da ich bei 1und1 (1&1 Home 5.0) keines der genannten Optionen verwenden kann -- alle .htaccess-Optionen zum Errorloggen produzieren 500er Server-Error (Lokal übrigens auch, da einige Module nicht aktiviert), leider.

        Ich muss darauf achten, dass das, was ich Lokal mache, auch Online funktioniert.

        Ich werde einfach das, was ich habe, noch ein wenig verfeinern, so wie von Sven vorgeschlagen.

        mfg

        --
        echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
        array(2) {
          ["SELFCODE"]=>
          string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
          ["Meaningful"]=>
          string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
        }
  2. Hello,

    anstatt ein neues Log zu erfinden, dass ja auch nur loggen kann, wenn das benutzende Script als Ressource angesprochen werden konnte, würde ich lieber die vorhandenen Logmechanismen und das Format umstellen.

    Da gehört mMn z.B. noch rein die Größe des Requests incl. Upload.
    Und die Formatierung lässt etwas zu wünschen übrig.

    Aber beides kann man beim Apachen mit LogFormat gerade rücken

    http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#logformat
    http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. hi,

      anstatt ein neues Log zu erfinden, dass ja auch nur loggen kann, wenn das benutzende Script als Ressource angesprochen werden konnte, würde ich lieber die vorhandenen Logmechanismen und das Format umstellen.

      Ich erfinde es ja nicht neu, ich habe nur den zugriff auf error_log für mich erleichtert; error_log an sich speichert die Fehler mit zig umbrüchen und whitespaces, dass ist beim bearbeiten sehr umständlich.
      http://de2.php.net/function.error-log#function.error-log.examples -- das erste Bsp. ist nicht sehr schön, dass dritte hingegen kann ich frei formatieren.

      Da gehört mMn z.B. noch rein die Größe des Requests incl. Upload.

      Wie frage ich diese ab? Ich stehe jetzt ziemlich auf dem Schlauch, was du meinst.

      Aber beides kann man beim Apachen mit LogFormat gerade rücken

      http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#logformat
      http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats

      Danke für die Links, nur das Problem ist, dass diese Funktionen bei 1und1 nicht funktionieren, bzw. Logrotate habe ich schon getestet, ohne Erfolg, 500er Server-Error, die  verlinkten kann ich heute Abend mal testen, ich denke aber, wird sich nicht viel ändern.

      mfg

      --
      echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
      array(2) {
        ["SELFCODE"]=>
        string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
        ["Meaningful"]=>
        string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
      }
  3. Moin!

    ich hab das PHP-Interne error_log ein wenig erweitert und würde gerne eure Meinungen bzw. verbesserungsvorschläge dazu einholen.

    Über das korrekte Loggen habe sich schon Generationen von Programmierern so ihre Gedanken gemacht. Deine Variante gefällt mir aus mehreren Gründen nicht:

    1. Ich muß eine DB-Connection haben, wenn ich loggen will. Habe ich nicht immer. Und die Abhängigkeit der Log-Funktion von DB-Funktionen ist auch extrem unschön, weil Datenbankzugriffe einfach nicht in den Machtbereich eines Loggers gehören.

    2. error_log() arbeitet mit diversen Logzielen, die in der php.ini konfiguriert werden können - nicht nur mit Dateien! Deine Erweiterung geht aber fest von einer eigenständigen Datei aus, die auch noch löschbar sein soll. Diese Erwartungshaltung verträgt sich nicht mit der Verwendung von error_log(). Wenn du schon einen Datei-only-Logger schreibst, warum schickst du dann die Meldungen nicht per Dateifunktion ins Logfile?

    3. Die Konstante ErrorLogFile ist mir unbekannt.

    4. Das Löschen einer zu großen Logdatei ist nicht Aufgabe des Loggers, sondern der Logfile-Rotation.

    Wenn man diese vier Punkte mal abzieht, kommt eine vernünftige Logmessage-Formatierfunktion für error_log heraus, die dem Logfile ein paar typische Informationen hinzufügen wie z.B. HTTP_HOST und REQUEST_URI.

    Unsinnig ist es hingegen, die Datenbank hier mit einzufügen, denn einen DB-Fehler loggt man dann, wenn man sieht, dass einer aufgetreten ist. Man loggt nicht pauschal, um eventuell auch einen DB-Fehler zu erfassen. Die Generierung und Anhübschung des DB-Fehlers gehört also nicht in den Logger selbst, sondern extern in eine Meldungsgenerierungsfunktion.

    - Sven Rautenberg

    1. hi,

      erstmal Sorry, ich hätte wohl erwähnen sollen, dass ich dieses ErrorLog einzig und allein für mein kleines CMS geschrieben habe, sprich genau auf meine Bedürfnisse angepasst habe.

      Bei meinem kleinen CMS können Fehler auftreten, die mit PHP nichts zutun haben, aber dennoch Fehler sind (404er Seiten Bspw.); mir ging es nur darum, diese mitzuloggen, vorher hatte ich sie sozusagen völlig "ignoriert".

      1. Ich muß eine DB-Connection haben, wenn ich loggen will. Habe ich nicht immer. Und die Abhängigkeit der Log-Funktion von DB-Funktionen ist auch extrem unschön, weil Datenbankzugriffe einfach nicht in den Machtbereich eines Loggers gehören.

      Es geht aber auch ohne die DB-Connection, also die Fehler werden trotzdem geloggt, auch wenn sie nichts mit der DB zutun haben, zwar nicht im gewünschten Format, aber ich bekomme sie zu sehen.

      1. error_log() arbeitet mit diversen Logzielen, die in der php.ini konfiguriert werden können - nicht nur mit Dateien!

      Wo kann ich sie denn noch speichern? Ich muss ja die möglichkeit haben, diese auszulesen.

      Deine Erweiterung geht aber fest von einer eigenständigen Datei aus, die auch noch löschbar sein soll. Diese Erwartungshaltung verträgt sich nicht mit der Verwendung von error_log().

      Bei meinen Tests, Lokal und Online funktioniert es, auch wenn die Datei nicht existiert, wird sie von PHP angelegt; sicherlich, wenn ich eine Funktion bauen will, die ich dann Offiziell freigeben würde, müsste ich viel ändern.

      Wenn du schon einen Datei-only-Logger schreibst, warum schickst du dann die Meldungen nicht per Dateifunktion ins Logfile?

      Durch error_log werden auch PHP-Fehler gespeichert, ich weiss nicht, wie ich diese selbst abfangen und dann speichern kann.

      1. Die Konstante ErrorLogFile ist mir unbekannt.

      Muss ja auch erst definiert werden ;) Dafür sind ja Konstanten gedacht, denke ich mal.

      1. Das Löschen einer zu großen Logdatei ist nicht Aufgabe des Loggers, sondern der Logfile-Rotation.

      Was ist eine Logfile-Rotation?
      Da hat aber auch der Alexander einen wichtigen Punkt angesprochen; wenn die Datei zu gross ist, werde ich sie zippen und speichern, dass ist wohl Sinnvoller, als sie einfach zu löschen.

      Unsinnig ist es hingegen, die Datenbank hier mit einzufügen, denn einen DB-Fehler loggt man dann, wenn man sieht, dass einer aufgetreten ist. Man loggt nicht pauschal, um eventuell auch einen DB-Fehler zu erfassen. Die Generierung und Anhübschung des DB-Fehlers gehört also nicht in den Logger selbst, sondern extern in eine Meldungsgenerierungsfunktion.

      Wie gesagt, mir ging es nur um mein CMS, ich kann jetzt z. B. mitloggen, wenn jemand eine nicht existierende Seite aufruft, oder irgendeinen Schwachsinn in die URI schreibt, aber ich werde deine Vorschläge berücksichtigen und mir noch ein wenig den Kopf darüber zerbrechen, so ganz gefällt es mir das, was ich jetzt habe, auch noch nicht.

      mfg

      --
      echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
      array(2) {
        ["SELFCODE"]=>
        string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
        ["Meaningful"]=>
        string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
      }
      1. Moin!

        Bei meinem kleinen CMS können Fehler auftreten, die mit PHP nichts zutun haben, aber dennoch Fehler sind (404er Seiten Bspw.); mir ging es nur darum, diese mitzuloggen, vorher hatte ich sie sozusagen völlig "ignoriert".

        404-Seiten gehören im Access-Log geloggt - indem das CMS HTTP-Status 404 zurückliefert anstelle von 200. Wenn dein CMS das bislang noch nicht kann, gehört diese Funktion schleunigst integriert. Dann können dir auch alle gewöhnlichen Logfile-Statistik-Programme die Info zusammenfassen.

        »» 1. Ich muß eine DB-Connection haben, wenn ich loggen will. Habe ich nicht immer. Und die Abhängigkeit der Log-Funktion von DB-Funktionen ist auch extrem unschön, weil Datenbankzugriffe einfach nicht in den Machtbereich eines Loggers gehören.

        Es geht aber auch ohne die DB-Connection, also die Fehler werden trotzdem geloggt, auch wenn sie nichts mit der DB zutun haben, zwar nicht im gewünschten Format, aber ich bekomme sie zu sehen.

        Aber deine Logfunktion erfordert zwingend einen zweiten Parameter, der ein Objekt mit der Eigenschaft "error" sein muss, und greift außerdem auf mysqli_connect_error() zu.

        »» 2. error_log() arbeitet mit diversen Logzielen, die in der php.ini konfiguriert werden können - nicht nur mit Dateien!

        Wo kann ich sie denn noch speichern? Ich muss ja die möglichkeit haben, diese auszulesen.

        Die Liste von http://de.php.net/manual/en/function.error-log.php ist ja recht ausführlich.

        Allerdings hatte ich übersehen, dass du explizit Typ 3 festlegst. Andererseits: Diese explizite Festlegung hat ihre Nachteile dann, wenn dein CMS nicht von dir auf deinem Host eingesetzt werden soll, sondern woanders. Üblicherweise würde man vermutlich erwarten, dass die Fehler genau in dem Logfile auftauchen, welches von der php.ini definiert wurde.

        »» Wenn du schon einen Datei-only-Logger schreibst, warum schickst du dann die Meldungen nicht per Dateifunktion ins Logfile?

        Durch error_log werden auch PHP-Fehler gespeichert, ich weiss nicht, wie ich diese selbst abfangen und dann speichern kann.

        Aber diese Fehler landen nur dann in DIESEM Logfile, wenn die php.ini entsprechend konfiguriert ist - oder du einen eigenständigen Error-Handler definiert hast, der dann wieder deine eigene Logfunktion benutzt.

        »» 3. Die Konstante ErrorLogFile ist mir unbekannt.

        Muss ja auch erst definiert werden ;) Dafür sind ja Konstanten gedacht, denke ich mal.

        Dann ist die Definition eines dritten optionalen Parameters in der Funktion überflüssig. Entweder der Dateiname wird als Konstante definiert, oder der Dateinamenparameter nutzt einen "vernünftigen" statischen Defaultwert.

        »» 4. Das Löschen einer zu großen Logdatei ist nicht Aufgabe des Loggers, sondern der Logfile-Rotation.

        Was ist eine Logfile-Rotation?
        Da hat aber auch der Alexander einen wichtigen Punkt angesprochen; wenn die Datei zu gross ist, werde ich sie zippen und speichern, dass ist wohl Sinnvoller, als sie einfach zu löschen.

        Beides ist nicht die Aufgabe des Loggers. Denn der Logvorgang hat gefälligst maximal schnell abzulaufen - das Zippen einer Gigabyte-Logdatei dauert hingegen seine Zeit.

        Wenn du es vernünftiger lösen willst, dann schreibst du dir einen Mechanismus, der pro Tag, Woche oder Monat einen neuen Logfilenamen verwendet, und bietest in deinem Admin-Backend eine Möglichkeit, die generierten Logfiles zu verwalten, zu zippen, auszuwerten oder zu löschen.

        »» Unsinnig ist es hingegen, die Datenbank hier mit einzufügen, denn einen DB-Fehler loggt man dann, wenn man sieht, dass einer aufgetreten ist. Man loggt nicht pauschal, um eventuell auch einen DB-Fehler zu erfassen. Die Generierung und Anhübschung des DB-Fehlers gehört also nicht in den Logger selbst, sondern extern in eine Meldungsgenerierungsfunktion.

        ich kann jetzt z. B. mitloggen, wenn jemand eine nicht existierende Seite aufruft

        Braucht bzw. verursacht die Fehlermeldung scheiternde Datenbankzugriffe?

        oder irgendeinen Schwachsinn in die URI schreibt

        Wenn das Datenbankfehler erzeugt, ist auch irgendwas ganz böse falsch in deinem Datenbankcode. Es taucht aber in jedem Fall im Access-Log auf, dafür ist das ja da.

        aber ich werde deine Vorschläge berücksichtigen und mir noch ein wenig den Kopf darüber zerbrechen, so ganz gefällt es mir das, was ich jetzt habe, auch noch nicht.

        Wie gesagt: Wenn die Datenbank irgendwelche Fehler produziert, dann willst du das loggen, indem du die DB-Fehlermeldung in die Logdatei schreibst. Gerne auch mit Host, URL und Uhrzeit dabei. Du willst aber nicht irgendwas loggen, und nebenbei auch noch den letzten DB-Fehler - ich glaube nämlich nicht, dass jemals diese Konstellation auftritt, dass beim Aufruf der Log-Funktion auch noch unbemerkt ein DB-Fehler existiert.

        - Sven Rautenberg

        1. hi,

          404-Seiten gehören im Access-Log geloggt - indem das CMS HTTP-Status 404 zurückliefert anstelle von 200. Wenn dein CMS das bislang noch nicht kann, gehört diese Funktion schleunigst integriert. Dann können dir auch alle gewöhnlichen Logfile-Statistik-Programme die Info zusammenfassen.

          Mein CMS generiert schon die richtigen Header, nur möchte ich so kleinigkeiten nicht direkt aus den Access-Logs rausfiltern. Mit meiner Variante ist es einfacher zu Handhaben, da ich kaum was zu beachten brauche, ausser das error_logs auf dem Webspace verfügbar sind.

          Aber deine Logfunktion erfordert zwingend einen zweiten Parameter, der ein Objekt mit der Eigenschaft "error" sein muss, und greift außerdem auf mysqli_connect_error() zu.

          Nein, der zweite Parameter erwartet lediglich die Variable für $_dbConnect, das auch nur, weil ich diese nicht in der Funktion als global deklarieren wollte.
          Ich hate schon Gestern ein wenig weiter gebastelt, werde es aber jetzt nochmal komplett neu schreiben.

            /*  
             * eigenes Error_log  
             *  
             * Param $_content: Die Fehlermeldung, bspw. Error 404 - not found  
             * Param $_connect: Datenbankverbindung, um Mysql-Fehler abzufragen  
             * Param $_errfile: Die Errorlog-Datei  
            */  
            function my_errorlog ($_content,$_connect,$_errfile=ErrorLogFile)
          

          Diese explizite Festlegung hat ihre Nachteile dann, wenn dein CMS nicht von dir auf deinem Host eingesetzt werden soll, sondern woanders. Üblicherweise würde man vermutlich erwarten, dass die Fehler genau in dem Logfile auftauchen, welches von der php.ini definiert wurde.

          Ja, dieses Problem ist mir bewusst, leider kann ich noch nicht soweit denken ;)
          Wenn
          ini_set('error_log', 'error/error_log.inc.php'); ## Error-Log
          nicht funktioniert, gibt es halt kein error_log ;)

          Aber diese Fehler landen nur dann in DIESEM Logfile, wenn die php.ini entsprechend konfiguriert ist - oder du einen eigenständigen Error-Handler definiert hast, der dann wieder deine eigene Logfunktion benutzt.

          Das ist bei mir ja der Fall, meine php.ini ist für meinen Fall angepasst; klar, wenn ich dieses Script weiter gebe, könnte es Probleme geben, nur steht das derzeit ausser Frage, da dass CMS bei weitem nicht massentauglich ist.

          Dann ist die Definition eines dritten optionalen Parameters in der Funktion überflüssig. Entweder der Dateiname wird als Konstante definiert

          Das habe ich korrigiert, Danke für den Hinweis.

          Beides ist nicht die Aufgabe des Loggers. Denn der Logvorgang hat gefälligst maximal schnell abzulaufen - das Zippen einer Gigabyte-Logdatei dauert hingegen seine Zeit.

          Im Admin-Backend habe ich schon eine Option zum speichern der Error_logs, nur, wenn ich mal vergesse, das Admin-Backend aufzurufen (Bsp. wegen Urlaub) und die Datei schon 1,5 GB gross ist, soll es spätestens an diesem Punkt abgefangen werden.

          Wenn du es vernünftiger lösen willst, dann schreibst du dir einen Mechanismus, der pro Tag, Woche oder Monat einen neuen Logfilenamen verwendet, und bietest in deinem Admin-Backend eine Möglichkeit, die generierten Logfiles zu verwalten, zu zippen, auszuwerten oder zu löschen.

          Das würde wohl Cronjob voraussetzen, was 1und1 leider nur gegen aufpreis anbietet; mein nächster Provider wird all-inkl sein, dass steht schon mal fest.

          » ich kann jetzt z. B. mitloggen, wenn jemand eine nicht existierende Seite aufruft

          Braucht bzw. verursacht die Fehlermeldung scheiternde Datenbankzugriffe?

          Quasi ;)
          Ja,ich weiss, in den Access-Logs werden diese Aufrufe auch mitgeloggt, aber ich möchte ja auch ein wenig Datenhandling lernen.

          Wenn das Datenbankfehler erzeugt, ist auch irgendwas ganz böse falsch in deinem Datenbankcode. Es taucht aber in jedem Fall im Access-Log auf, dafür ist das ja da.

          Mein CMS generiert hier auch die richtigen Header, nur ist mir die auswertung der Access-Logs mit zuviel arbeit verbunden, meine Variante habe ich mit 4-5 Funktionen sehr gut im Griff.
          Im Admin-Backend sieht es derzeit so aus (Links funktionieren natürlich nicht).

          Wie gesagt: Wenn die Datenbank irgendwelche Fehler produziert, dann willst du das loggen, indem du die DB-Fehlermeldung in die Logdatei schreibst. Gerne auch mit Host, URL und Uhrzeit dabei. Du willst aber nicht irgendwas loggen,

          An sich hatte ich mir gedacht, wenn ich schon dabei bin, logge ich einfach alles mit, was in meinen Augen ein Fehler ist, ist dass der falsche Ansatz?

          Aktuell sieht meine index.php so aus, allerdings bastel ich noch dran.

          mfg

          --
          echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
          array(2) {
            ["SELFCODE"]=>
            string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
            ["Meaningful"]=>
            string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
          }
          1. Moin!

            »» Aber deine Logfunktion erfordert zwingend einen zweiten Parameter, der ein Objekt mit der Eigenschaft "error" sein muss, und greift außerdem auf mysqli_connect_error() zu.

            Nein, der zweite Parameter erwartet lediglich die Variable für $_dbConnect, das auch nur, weil ich diese nicht in der Funktion als global deklarieren wollte.

            Diese Variable wird aber in der Funktion verwendet, und es wird ohne weitere Checks einfach davon ausgegangen, dass sie ein Objekt mit Eigenschaft "error" ist.

            Abgesehen davon zeigt dein Logfile-Auszug ja, dass die Fehler allesamt ohne Datenbankmeldung ablaufen. Ich ziehe sehr stark in Zweifel, dass überhaupt mal ein Datenbankfehler auf diese Weise geloggt wird.

            Auf der anderen Seite sieht man sehr schön, dass die Behandlung des DB-Zugriffs bei dir noch verbesserungswürdig ist, denn sonst würde ein Fall wie "Zuviele DB-Connections" keine PHP-Fehlermeldungskaskade erzeugen, sondern rechtzeitig abbrechen und Status 500 auswerfen.

            Die Notice mit unbekannter Variable ist auch heilbar.

            Und wie du selbst siehst: Der Zugriff auf mysqli_error() funktioniert nicht, wenn kein MySQLi-Objekt in der Log-Funktion verfügbar ist.

            Abgesehen davon sind mir zwei Dinge in Bezug auf die ErrorLogFile-Konstante aufgefallen:

            1. Du übergibst die Konstante immer - außer an einer Stelle. Warum ist sie dann in der Funktion optional gemacht und als Default-Wert mit dieser Konstanten ausgestattet?

            2. Was erwartest du hier?

              ini_set('error_log', 'error/error_log.inc.php');   ## Error-Log  
              define('ErrorLogFile', ini_get('error_log'));      ## Error-Log-Pfad
            

            Wenn ich mal deine Dateizugriffslogik hernehme: Sollte ini_set() NICHT erfolgreich den Logdatei-Pfad setzen können, wird dein eigenes Error-Logging in das Logziel geschrieben, das von der Installation vorgesehen ist.

            error_log enthält aber nicht zwingend einen Datei- bzw. Pfadnamen. Und da dein eigener Aufruf von error_log() ja ohnehin fest die Optionen für das Logging in eine Datei enthält, ist das Resultat dieses Konstruktes hier potentiell böse.

            Ich würde vorschlagen: Definition einer Konstanten mit dem Error-Log-Dateinamen, und zwar als fixer String. Dann ini_set() des error_log-Wertes. Entfernung des optionalen dritten Parameters aus der Logfunktion, und Nutzung der Konstanten als Dateiname im Aufruf von error_log().

            Weiterhin: Die DB-Fehler gehören nicht in deiner Logfunktion abgefragt, sondern im Bedarfsfall von der Applikation als Logmeldung ausgegeben. An vielen Stellen, an denen eine Logmeldung erzeugt wird, ist gar kein DB-Zugriff erfolgt - und an den Stellen, wo er erfolgt, sollte die Fehlerbehandlung auch explizit greifen, und Errorlogging gehört nun mal dazu.

            Aktuell sieht meine index.php so aus, allerdings bastel ich noch dran.

            Ja, ich erinnere mich - diese komische Filterfunktion, die einfach mal pauschal alles, was irgendwie "böse" aussieht, in der URL rausfischt, kommt mir extrem bekannt vor - wir hatten schon mal diskutiert, dass das absolut nicht gerechtfertigt und notwendig ist.

            Interessant übrigens auch deine Redirect-Funktion. Warum steht die ganz am Ende, nachdem für den Request schon wahnsinnig viel Arbeit geleistet wurde, und prüft dann einfach nur die aufgerufene Domain? Sowas gehört ganz an den Anfang des Skripts, ohne Ausgabe irgendwelcher HTML-Inhalte (wobei der Standard empfiehlt, aber nicht zwingend vorschreibt, dass der Seiteninhalt einer Redirect-Antwort einen Link auf das Redirect-Ziel enthält.

            Was mir hingegen als Verbesserung deines Loggings eingefallen ist: Der Referrer fehlt. Nur mit dieser Info weißt du, wo der fehlerhafte Link aufzufinden ist, dessen Ergebnis du da gerade loggst.

            - Sven Rautenberg

            1. hi,

              Danke erstmal für die vielen Tipps und die hilfe, da war und ist noch viel aufzuräumen.

              Diese Variable wird aber in der Funktion verwendet, und es wird ohne weitere Checks einfach davon ausgegangen, dass sie ein Objekt mit Eigenschaft "error" ist.

              Ja, stimmt. Ich hatte gar nicht weiter drüber nachgedacht und versucht, alles in diese Funktion zu bauen, habe ich jetzt geändert.

              Auf der anderen Seite sieht man sehr schön, dass die Behandlung des DB-Zugriffs bei dir noch verbesserungswürdig ist, denn sonst würde ein Fall wie "Zuviele DB-Connections" keine PHP-Fehlermeldungskaskade erzeugen, sondern rechtzeitig abbrechen und Status 500 auswerfen.

              Das verstehe ich allerdings selber nicht; da muss was auf dem Server bei 1und1 schief laufen, denn soviel ist auf meiner Seite nicht los. Ich werde Morgen mal den Support anrufen und nachhaken.
              max_connections 250 -- show variables like 'max_connections';
              mysql.allow_persistent = off // zeigt auch keine wirkung

              Ich würde vorschlagen: Definition einer Konstanten mit dem Error-Log-Dateinamen, und zwar als fixer String. Dann ini_set() des error_log-Wertes. Entfernung des optionalen dritten Parameters aus der Logfunktion, und Nutzung der Konstanten als Dateiname im Aufruf von error_log().

              Ich habe jetzt alle Parameter bis auf $_content entfernt, du hast recht, alles andere ist Sinnlos.
              Ich muss mir noch mal Gedanken über die Struktur meiner index machen, ich habe mittlerweile den Überblick verloren.

              Ja, ich erinnere mich - diese komische Filterfunktion, die einfach mal pauschal alles, was irgendwie "böse" aussieht, in der URL rausfischt, kommt mir extrem bekannt vor - wir hatten schon mal diskutiert, dass das absolut nicht gerechtfertigt und notwendig ist.

              Habe ich geändert, so gesehen auch eine Überflüssige Prüfung, da ich eh nichts unescaped durch meine Selects jage.
              Neue Index

              Interessant übrigens auch deine Redirect-Funktion. Warum steht die ganz am Ende, nachdem für den Request schon wahnsinnig viel Arbeit geleistet wurde, und prüft dann einfach nur die aufgerufene Domain?

              Ich hatte schon öfters versucht, diesen Aufruf ganz oben in die index zu schreiben, nur hat das nie funktioniert; jetzt gerade habe ich rausgefunden, warum.

              Die 2 redirects, die ich habe, funktionieren erst nach dem ersten
              header("HTTP/1.1 200 ok");
              im Dokument, ist das ein Bug oder so gewollt?

              Was mir hingegen als Verbesserung deines Loggings eingefallen ist: Der Referrer fehlt. Nur mit dieser Info weißt du, wo der fehlerhafte Link aufzufinden ist, dessen Ergebnis du da gerade loggst.

              Ja, stimmt, daran hatte ich auch gedacht, kam aber nicht auf Referer.
              Nur jetzt habe ich ein Problem mit dem Referer, mit:

              ((isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : 'No Matches')

              bekomme ich immer 'No Matches', also keinen Referer, was mache ich denn hier falsch?

              mfg

              --
              echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
              array(2) {
                ["SELFCODE"]=>
                string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                ["Meaningful"]=>
                string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
              }
              1. hi,

                ((isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : 'No Matches')

                bekomme ich immer 'No Matches', also keinen Referer, was mache ich denn hier falsch?

                Die Lösung dieses Problemes:

                    if (isset($_SERVER['REDIRECT_URL']))  
                      $_ref = $_SERVER['REDIRECT_URL'];  
                    else if (isset($_SERVER['HTTP_REFERER']))  
                      $_ref = $_SERVER['HTTP_REFERER'];  
                    else  
                      $_ref = 'No Matches';
                

                mfg

                --
                echo '<pre>'; var_dump($Malcolm_Beck`s); echo '</pre>';
                array(2) {
                  ["SELFCODE"]=>
                  string(74) "ie:( fl:) br:> va:? ls:? fo:) rl:| n4:# ss:{ de:? js:} ch:? sh:( mo:? zu:("
                  ["Meaningful"]=>
                  string(?) "Der Sinn des Lebens ist deinem Leben einen Sinn zu geben"
                }