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);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |