152 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
<?php
 | 
						|
 | 
						|
/*
 | 
						|
 * This file is part of the Monolog package.
 | 
						|
 *
 | 
						|
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 | 
						|
 *
 | 
						|
 * For the full copyright and license information, please view the LICENSE
 | 
						|
 * file that was distributed with this source code.
 | 
						|
 */
 | 
						|
 | 
						|
namespace Monolog\Handler;
 | 
						|
 | 
						|
use Monolog\Logger;
 | 
						|
 | 
						|
/**
 | 
						|
 * Logs to Cube.
 | 
						|
 *
 | 
						|
 * @link http://square.github.com/cube/
 | 
						|
 * @author Wan Chen <kami@kamisama.me>
 | 
						|
 */
 | 
						|
class CubeHandler extends AbstractProcessingHandler
 | 
						|
{
 | 
						|
    private $udpConnection;
 | 
						|
    private $httpConnection;
 | 
						|
    private $scheme;
 | 
						|
    private $host;
 | 
						|
    private $port;
 | 
						|
    private $acceptedSchemes = array('http', 'udp');
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a Cube handler
 | 
						|
     *
 | 
						|
     * @throws \UnexpectedValueException when given url is not a valid url.
 | 
						|
     *                                   A valid url must consist of three parts : protocol://host:port
 | 
						|
     *                                   Only valid protocols used by Cube are http and udp
 | 
						|
     */
 | 
						|
    public function __construct($url, $level = Logger::DEBUG, $bubble = true)
 | 
						|
    {
 | 
						|
        $urlInfo = parse_url($url);
 | 
						|
 | 
						|
        if (!isset($urlInfo['scheme'], $urlInfo['host'], $urlInfo['port'])) {
 | 
						|
            throw new \UnexpectedValueException('URL "'.$url.'" is not valid');
 | 
						|
        }
 | 
						|
 | 
						|
        if (!in_array($urlInfo['scheme'], $this->acceptedSchemes)) {
 | 
						|
            throw new \UnexpectedValueException(
 | 
						|
                'Invalid protocol (' . $urlInfo['scheme']  . ').'
 | 
						|
                . ' Valid options are ' . implode(', ', $this->acceptedSchemes));
 | 
						|
        }
 | 
						|
 | 
						|
        $this->scheme = $urlInfo['scheme'];
 | 
						|
        $this->host = $urlInfo['host'];
 | 
						|
        $this->port = $urlInfo['port'];
 | 
						|
 | 
						|
        parent::__construct($level, $bubble);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Establish a connection to an UDP socket
 | 
						|
     *
 | 
						|
     * @throws \LogicException           when unable to connect to the socket
 | 
						|
     * @throws MissingExtensionException when there is no socket extension
 | 
						|
     */
 | 
						|
    protected function connectUdp()
 | 
						|
    {
 | 
						|
        if (!extension_loaded('sockets')) {
 | 
						|
            throw new MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler');
 | 
						|
        }
 | 
						|
 | 
						|
        $this->udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0);
 | 
						|
        if (!$this->udpConnection) {
 | 
						|
            throw new \LogicException('Unable to create a socket');
 | 
						|
        }
 | 
						|
 | 
						|
        if (!socket_connect($this->udpConnection, $this->host, $this->port)) {
 | 
						|
            throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Establish a connection to a http server
 | 
						|
     * @throws \LogicException when no curl extension
 | 
						|
     */
 | 
						|
    protected function connectHttp()
 | 
						|
    {
 | 
						|
        if (!extension_loaded('curl')) {
 | 
						|
            throw new \LogicException('The curl extension is needed to use http URLs with the CubeHandler');
 | 
						|
        }
 | 
						|
 | 
						|
        $this->httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put');
 | 
						|
 | 
						|
        if (!$this->httpConnection) {
 | 
						|
            throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port);
 | 
						|
        }
 | 
						|
 | 
						|
        curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST");
 | 
						|
        curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * {@inheritdoc}
 | 
						|
     */
 | 
						|
    protected function write(array $record)
 | 
						|
    {
 | 
						|
        $date = $record['datetime'];
 | 
						|
 | 
						|
        $data = array('time' => $date->format('Y-m-d\TH:i:s.uO'));
 | 
						|
        unset($record['datetime']);
 | 
						|
 | 
						|
        if (isset($record['context']['type'])) {
 | 
						|
            $data['type'] = $record['context']['type'];
 | 
						|
            unset($record['context']['type']);
 | 
						|
        } else {
 | 
						|
            $data['type'] = $record['channel'];
 | 
						|
        }
 | 
						|
 | 
						|
        $data['data'] = $record['context'];
 | 
						|
        $data['data']['level'] = $record['level'];
 | 
						|
 | 
						|
        if ($this->scheme === 'http') {
 | 
						|
            $this->writeHttp(json_encode($data));
 | 
						|
        } else {
 | 
						|
            $this->writeUdp(json_encode($data));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    private function writeUdp($data)
 | 
						|
    {
 | 
						|
        if (!$this->udpConnection) {
 | 
						|
            $this->connectUdp();
 | 
						|
        }
 | 
						|
 | 
						|
        socket_send($this->udpConnection, $data, strlen($data), 0);
 | 
						|
    }
 | 
						|
 | 
						|
    private function writeHttp($data)
 | 
						|
    {
 | 
						|
        if (!$this->httpConnection) {
 | 
						|
            $this->connectHttp();
 | 
						|
        }
 | 
						|
 | 
						|
        curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']');
 | 
						|
        curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, array(
 | 
						|
            'Content-Type: application/json',
 | 
						|
            'Content-Length: ' . strlen('['.$data.']'),
 | 
						|
        ));
 | 
						|
 | 
						|
        Curl\Util::execute($this->httpConnection, 5, false);
 | 
						|
    }
 | 
						|
}
 |