PDA

View Full Version : Transparent Listener


TheMalefactor
02-07-2010, 03:08 PM
Hey All,

I'm developing an intranet system, using PHP, MySQL, Ajax etc.

I need to log when users run certain types of queries, and display them on the server in a log application (written in Java).

What I'm looking for is a way to use this program like a transparent tunnel, so when PHP wants to get something from the database, it connects to this Java app which just queries the database and spits out the resultset, just as if PHP went straight to the DB.

The Java application can then check if the query was something that needed to be logged and displayed as it is being called, and do the logging functions.

I'm assuming this needs to be done with a socket, but I can't seem to find anything on google to help with this issue.

Thanks in advance for your help!

Ta,
Ryan.

RossMcCaughrain
02-08-2010, 05:18 PM
Sounds to me like your over complicating by adding in a java component. Why not just use PHP to log and extend your PHP database access layer? I use PDO for connecting to my MySQL database and use the Pear Log package for logging. I then extend the PDO class and add my call to log in there i.e.

Create a singleton class for Logging (doesnt have to be a singleton but i find it handy)

class Logger {

private function __construct() {

$stdConf = array(
'timeFormat' => '%d/%m %H:%M:%S',
'eol' => '<br/>'
);

$this->_fileLogger = &Log::singleton('file', LOG_PATH.'/serverLog.html', ' - ', $stdConf, PEAR_LOG_DEBUG);
}

/**
* Get the single instance
* @return Singleton
*/
public static function getInstance() {
if(self::$_instance === null)
self::$_instance = new self();
return self::$_instance;
}

/** Disallow cloning */
private function __clone() {}

public function getLogLevel() {
return $this->_logLevel;
}

public function log($message, $priority) {
$this->_fileLogger->log($message, $priority);
}

/** Static instance */
private static $_instance;

private $_logLevel = PEAR_LOG_INFO;

private $_fileLogger;
}

Then extend your PDO class

<?php

/**
* DB Wrapper Class
* @author Ross McCaughrain
*
*/
class MySqlConn extends PDO
{
/**
* Constructor
* @param String $host The Database
* @param String $dbName The Database name
* @param String $username The Database username
* @param String $password The Database password
*/
public function __construct($host, $dbName, $username, $password) {
$dsn = "mysql:host=$host;dbname=$dbName";
try {
parent::__construct($dsn, $username, $password);

$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->setAttribute(PDO::ATTR_PERSISTENT, true);

Logger::getInstance()->log(get_class($this) .': PDO Database Connection made', PEAR_LOG_INFO);
}
catch(PDOException $ex) {
throw new Exception($ex);
}
}

public function query($query) {
$statement = parent::query($query);
Logger::getInstance()->log(get_class($this) .': Query ['.$query.'] executed', PEAR_LOG_DEBUG);

if(!$statement)
throw new Exception('Statement execution failed: ['.print_r($statement->errorInfo(), true).']');

return $statement;
}

public function exec($query) {
$affected = parent::exec($query);
Logger::getInstance()->log(get_class($this) .': Exec query ['.$query."] affected [$affected] rows", PEAR_LOG_DEBUG);

if($affected === false)
throw new Exception('Query failed: ['.$query.']');

return $affected;
}

private $_query = null;
}

?>

So basically anywhere you need to log you call

Logger::getInstance()->log('Message', Log_Level);

TheMalefactor
02-09-2010, 05:52 PM
Thanks for your suggestion Ross,

I'll definitely need to implement something similar to that in another project I'm working on.

However, there are other functions that the Java program needs to handle.
The logging is just part of a bigger picture.
In the beginning it is going to be used for downloading auto updates to the php code, handling backups and as the system expands it will need to perform more functions.
The only issue I'm having with the app at the moment is the real-time database logging, without having to poll the db for changes.

One of the reasons I want to log through an external application, is because the queries that need to be logged will change over time, and I don't really want to be rewriting the code too often to change which queries are and aren't logged in dozens of PHP files.

If it helps, the application will be running on the machine all the time, it is the same machine as the web server, and MySQL installation.

I was thinking, is a PHP MySQL result set the same as a Java one?
ie: Using JDBC, if I passed a java resultset through the socket to the PHP file, can i use it the same was as if I called the mysql_query() function in PHP? '
Thanks guys.

Ta,
Ryan.