Examples: Logging

Centralize your logging. Scale your application to multiple servers, aggregate logs from different languages, or just collect all your logs in a centralized format. You can leverage gearman to help collect logs from across a multitude of systems and aggregate them together or fan them back out as need through a central, scaleable service.

The Client

<?php

/**
* An extremely rudimentary logger that passes log messages through gearman
*/

class GearmanLogger {

static $instances = array();

/**
* Fetch (and create if needed) an instance of this logger.
*
* @param string $server
* @param int $port
* @param string $queue
* @return self
*/

public static function getInstance($server = '127.0.0.1', $port = 4730, $queue = 'log') {
$hash = $queue . $server . $port;
if (!array_key_exists($hash, self::$instances)) {
self::$instances[$hash] = new self($queue, $server, $port);
}

return self::$instances[$hash];
}

/** @var GearmanClient */
private $gmc;
/** @var string */
private $queue;

public function __construct($queue, $server, $port) {
$this->gmc = new GearmanClient();
$this->queue = $queue;
$this->gmc->addServer($server, $port);
}

/**
* Log a message
*
* @param mixed $message
* @param string $level
*/

public function log($message, $level = 'DEBUG') {
$this->gmc->doBackground($this->queue, json_encode(array(
'level' => $level,
'message' => $message,
'ts' => time(),
'host' => gethostname(),
)));
}

/**
* Log a warning
* @param mixed $message
*/

public function warn($message) {
$this->log($message, 'WARN');
}

/**
* Log an error
* @param mixed $message
*/

public function error($message) {
$this->log($message, 'ERROR');
}

}

GearmanLogger::getInstance()->log('A debug message');
GearmanLogger::getInstance()->warn('A warning');
GearmanLogger::getInstance()->error('A serious problem');
GearmanLogger::getInstance()->error(array('an array?', 'interesting...', 'structured log messages!'));
// todo
// todo

The Worker

<?php

$worker = new GearmanWorker();
$worker->addServer();

$worker->addFunction("log", function (GearmanJob $job) {
$workload = json_decode($job->workload());
// Save the logs to the database, write them to a single file, index them, ship them to splunk, whatever
printf(
"Log line receieved - (%s @ %s) [%s] %s\n"
, date(DATE_ISO8601, $workload->ts)
, $workload->host
, $workload->level
, json_encode($workload->message)
);
// You can do more interesting things too, like scan for specific errors
// and send out warnings, or having rolling counts of errors to alert on, etc
});

while ($worker->work());
// todo
// todo