címkék

beleszóltak

amik jók

Ricsi megmondja:
java'nother blog

Ebben hiszek:
BMWfanatics.hu

PHP TalkBack. Hogy még beszédesebb legyen a programunk.

2008.01.14. 20:29 nullstring

Vannak helyzetek, mikor egy komplex rendszer működésének debugolásához még a Zend PDT sem elég, szeretnénk látni, hogy mi történik a háttérben, miközben kattintgatunk élesben. Erre az egyik számomra legszimpatikusabb módszer, ha indítunk egy TCP "szervert", és annak küldözgetjük rendszerünkből az infót.

Ehhez a kommunikációhoz kreálunk egy klienst is, ami képes az üzeneteinket egyszerűen továbbítani a szervernek. Van is egy a php freaks címről koppitott cucc, ami a fentebb írtakat tökéletesen lefedi. Vagyis apró módosítások hatására tökéletes része lehet rendszerünknek.

Alább a kódot láthatod. Az első maga a szerver, amivel nincs más teendő, csak el kell indítani konzolból, és lesni, hogy milyen infók jelennek meg rajta.
A második maga a "kliens", ami az én esetemben a BasicErrorHandler osztály tagja, meghívása pedig rém egyszerű. Pl. mikor készült a session handlerünk, akkor szerettük volna figyelemmel kísérni, hogy mikor íródnak be az adatbázisba ténylegesen a munkamenet adatok:

BasicErrorHandler::trace("Writing session, account is:" . self::$account);

De lássuk a "szerver" kódját:

#!/usr/bin/php -q
<?php
error_reporting(E_ALL);
ini_set("display_errors", 0);

/* Allow the script to hang around waiting for connections. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting
 * as it comes in. */
ob_implicit_flush();

$address = '127.0.0.1';
$port = 10002;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}

if (socket_bind($sock, $address, $port) === false) {
    echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}

if (socket_listen($sock, 5) === false) {
    echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}

do {
    if (($msgsock = socket_accept($sock)) === false) {
        echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    /* Send instructions. */
    //$msg = "\nWelcome to the PHP Talkback server. \n" .
        //"To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
    //socket_write($msgsock, $msg, strlen($msg));
	echo(date("Y-m-d H:i:s") . "    Client connected.\n");

    do {
        if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
            //echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n";
            break;
        }
        if (!$buf = trim($buf)) {
            continue;
        }
        if ($buf == 'quit') {
            break;
        }
        if ($buf == 'shutdown') {
            socket_close($msgsock);
            break 2;
        }
        //$talkback = "PHP: You said '$buf'.\n";
        //socket_write($msgsock, $talkback, strlen($talkback));
        echo str_replace("quit", "", $buf) . "\n";
    } while (true);
    socket_close($msgsock);
} while (true);

socket_close($sock);
?>

Mint azt a kód legelején lehet látni, megmondtuk a rendszernek jól, hogy mivel futtassa a fájlt (shebang line), esetünkben ez ugye a php értelmező. Ebből következik, hogy unix rendszereken minden további nélkül szimplán csak le kell futtatni a fájlt.

És a "kliens":

define("ERR_TRACE", true);
define("ERR_TRACE_HOST", "127.0.0.1");
define("ERR_TRACE_PORT", 10002);

class BasicErrorHandler {
[...]
    public static function trace($message)
    {
        if (ERR_TRACE) {
            $service_port = ERR_TRACE_PORT;
            $address = ERR_TRACE_HOST;
            $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

            if ($socket === false) {
                self::$socket = false;
                trigger_error("socket_create() failed: reason: " . socket_strerror(socket_last_error()), E_USER_WARNING);
            } else {
                $result = socket_connect($socket, $address, $service_port);

                if ($result === false) {
                    $socket = false;
                    trigger_error("socket_connect() failed: reason: " . socket_strerror(socket_last_error()), E_USER_WARNING);
                }
            }

            if ($socket && (strstr($_SERVER['REQUEST_URI'], ".jpg") === false) && (strstr($_SERVER['REQUEST_URI'], ".gif") === false) && (strstr($_SERVER['REQUEST_URI'], ".png") === false)) {
                $header = date("Y-m-d H:i:s") . "    " . session_id() . "    ";
                $indents = strlen($header);
                $ind = ">";

                for ($i = 0; $i < $indents; $i++) {
                    $ind .= " ";
                }

                $message = $header . $_SERVER['REQUEST_URI'] . "    " . $_SERVER['REMOTE_ADDR'] . str_replace("\n", "\n" . $ind, "\n" . $message) . "\n";
                socket_write($socket, $message, strlen($message));
                socket_write($socket, "quit\n", strlen("quit\n"));
            }

            if ($socket) {
                socket_close($socket);
            }
        }
    }
[..]
}

Ez lenne az a kódrészlet, ami segítségünkre van abban, hogy igazán egyszerűen küldjünk üzeneteket konzolunkra programunkból futás közben, ezzel könnyebbé téve a háttérben zajló történések figyelemmel kísérését.

2 komment

Címkék: debug php tutorial howto találtam

A bejegyzés trackback címe:

https://nullstring.blog.hu/api/trackback/id/tr49297066

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Benjamin · http://benjamin.hu/ 2008.02.23. 12:32:59

Tetszik, de mivel jobb / tobb ez mintha fileba loggolok es tail -el figyelem?

nullstring · http://www.bmwfanatics.hu 2008.02.23. 20:50:12

Hello,

Én ezt főleg olyan dolgokra használom, amiknek semmi keresni valójuk a logban, külön fájlt meg csak ezek miatt az üzenetek miatt feleslegesnek tartok létrehozni, mivel csak egyszer van rá szükségem például, hogy lássam mi történik. Másrészről valoszinű, hogy olyan dolgokat íratok ki vele, amik túl általánosak, és fél perc alatt generálnának egy 10 megás fájlt, aminek megintcsak nincs értelme :-)
A legfontosabb, hogy ezek az üzenetek nem olyan jellegűek, hogy logoljuk őket :-)



süti beállítások módosítása