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