Pergunta

I have a very intersting problem, and I wonder if there's someone who has a good solution for me:

I'm logging every possible error in a log-file. Including exceptions, fatal errors, warnings, notices, JS-errors (sent via Ajax),...

Now, for debugging-purposes, I wanted to display all these errors on the HTML-page too (so I don't need to check the log-file).

For this reason, I'm storing every new error inside the Session-Variable. And when the User saw it, it's beeing removed from the Session.

My Problem:

The php-backtrace of an error / exceptions contains lots of information. Including global Variables like $_SESSION.

And since I store all the information in the session, the session-size doubles after each error. (Each error-message in the session contains the whole content of the session before this error)

For example:

No error:

$_SESSION = array();

First error:

$_SESSION = array(error1=>array("msg"="foo", session=array()));

Second Error:

$_SESSION = array(error1=>array("msg"="foo", session=array()), error2 => array("msg"="foo2", session = array(error1=>array("msg"="foo", session=array()))));

(this is only a simplified example)

After 5 Errors, the Session is already so big, that I can't load it from my local server anymore (timeout).

I thought about cutting of every element from an array after the depth of 5 or sth. like that. Or is it possible to prevent php from storing global variables in the backtrace?

In the moment, I don't store the trace in the Session, but maybe someone knows a better solution, where I can still see basic trace-info

Foi útil?

Solução

If I may understand you correctly, what you're trying to do is to have some sort of per-session error log, which can be read later on.

My suggestion is to create separate log file per session, you can identify the log file by using the session id, which is unique per session.

<?php
define('PER_SESSION_LOG_PATH', '/tmp/logs/'); //or whatever path
/* return log handle */

class SessionLogger {

    static $fh;

    static function log_path() {
        return PER_SESSION_LOG_PATH . session_id() . '.log';
    }

    static function log_open() {
        if (!self::$fh) {
            self::$fh = fopen(self::log_path(), 'a+');
        }
        return self::$fh;
    }

    static function add_log($errors) {
        if (self::log_open()) {
            fwrite(self::$fh, serialize($errors) . PHP_EOL);
        }
    }

    static function log_close() {
        if (self::$fh) {
            fclose(self::$fh);
        }
    }

    //note that if the size of the log file is larger than memory_limit, you
    //may run into problems.
    //returns all the logs
    static function get_logs($truncate = TRUE) {
        $logs = array();
        if (self::log_open()) {
            while (!feof(self::$fh)) {
                $logs[] = unserialize(fgets(self::$fh));
            }
            //if the logs should be clear, then...
            if ($truncate) {
                fclose(self::$fh); //close and nullify handle 
                self::$fh = null;
                unlink(self::log_path()); //then delete log file.
            }
        }
        return $logs;
    }

}

Then you can add errors by doing

SessionLogger::add_log($error);

You can also read the logs by doing

SessionLogger::get_logs(true); //or false if you don't want to delete file.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top