Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
 
3
/*
4
 * This file is part of the Monolog package.
5
 *
6
 * (c) Jordi Boggiano <j.boggiano@seld.be>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Monolog\Handler;
13
 
14
use Monolog\Logger;
15
use Monolog\Utils;
16
 
17
/**
18
 * Logs to Cube.
19
 *
20
 * @link https://github.com/square/cube/wiki
21
 * @author Wan Chen <kami@kamisama.me>
22
 * @deprecated Since 2.8.0 and 3.2.0, Cube appears abandoned and thus we will drop this handler in Monolog 4
23
 */
24
class CubeHandler extends AbstractProcessingHandler
25
{
26
    /** @var resource|\Socket|null */
27
    private $udpConnection = null;
28
    /** @var resource|\CurlHandle|null */
29
    private $httpConnection = null;
30
    /** @var string */
31
    private $scheme;
32
    /** @var string */
33
    private $host;
34
    /** @var int */
35
    private $port;
36
    /** @var string[] */
37
    private $acceptedSchemes = ['http', 'udp'];
38
 
39
    /**
40
     * Create a Cube handler
41
     *
42
     * @throws \UnexpectedValueException when given url is not a valid url.
43
     *                                   A valid url must consist of three parts : protocol://host:port
44
     *                                   Only valid protocols used by Cube are http and udp
45
     */
46
    public function __construct(string $url, $level = Logger::DEBUG, bool $bubble = true)
47
    {
48
        $urlInfo = parse_url($url);
49
 
50
        if ($urlInfo === false || !isset($urlInfo['scheme'], $urlInfo['host'], $urlInfo['port'])) {
51
            throw new \UnexpectedValueException('URL "'.$url.'" is not valid');
52
        }
53
 
54
        if (!in_array($urlInfo['scheme'], $this->acceptedSchemes)) {
55
            throw new \UnexpectedValueException(
56
                'Invalid protocol (' . $urlInfo['scheme']  . ').'
57
                . ' Valid options are ' . implode(', ', $this->acceptedSchemes)
58
            );
59
        }
60
 
61
        $this->scheme = $urlInfo['scheme'];
62
        $this->host = $urlInfo['host'];
63
        $this->port = (int) $urlInfo['port'];
64
 
65
        parent::__construct($level, $bubble);
66
    }
67
 
68
    /**
69
     * Establish a connection to an UDP socket
70
     *
71
     * @throws \LogicException           when unable to connect to the socket
72
     * @throws MissingExtensionException when there is no socket extension
73
     */
74
    protected function connectUdp(): void
75
    {
76
        if (!extension_loaded('sockets')) {
77
            throw new MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler');
78
        }
79
 
80
        $udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0);
81
        if (false === $udpConnection) {
82
            throw new \LogicException('Unable to create a socket');
83
        }
84
 
85
        $this->udpConnection = $udpConnection;
86
        if (!socket_connect($this->udpConnection, $this->host, $this->port)) {
87
            throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port);
88
        }
89
    }
90
 
91
    /**
92
     * Establish a connection to an http server
93
     *
94
     * @throws \LogicException           when unable to connect to the socket
95
     * @throws MissingExtensionException when no curl extension
96
     */
97
    protected function connectHttp(): void
98
    {
99
        if (!extension_loaded('curl')) {
100
            throw new MissingExtensionException('The curl extension is required to use http URLs with the CubeHandler');
101
        }
102
 
103
        $httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put');
104
        if (false === $httpConnection) {
105
            throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port);
106
        }
107
 
108
        $this->httpConnection = $httpConnection;
109
        curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST");
110
        curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true);
111
    }
112
 
113
    /**
114
     * {@inheritDoc}
115
     */
116
    protected function write(array $record): void
117
    {
118
        $date = $record['datetime'];
119
 
120
        $data = ['time' => $date->format('Y-m-d\TH:i:s.uO')];
121
        unset($record['datetime']);
122
 
123
        if (isset($record['context']['type'])) {
124
            $data['type'] = $record['context']['type'];
125
            unset($record['context']['type']);
126
        } else {
127
            $data['type'] = $record['channel'];
128
        }
129
 
130
        $data['data'] = $record['context'];
131
        $data['data']['level'] = $record['level'];
132
 
133
        if ($this->scheme === 'http') {
134
            $this->writeHttp(Utils::jsonEncode($data));
135
        } else {
136
            $this->writeUdp(Utils::jsonEncode($data));
137
        }
138
    }
139
 
140
    private function writeUdp(string $data): void
141
    {
142
        if (!$this->udpConnection) {
143
            $this->connectUdp();
144
        }
145
 
146
        socket_send($this->udpConnection, $data, strlen($data), 0);
147
    }
148
 
149
    private function writeHttp(string $data): void
150
    {
151
        if (!$this->httpConnection) {
152
            $this->connectHttp();
153
        }
154
 
155
        if (null === $this->httpConnection) {
156
            throw new \LogicException('No connection could be established');
157
        }
158
 
159
        curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']');
160
        curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, [
161
            'Content-Type: application/json',
162
            'Content-Length: ' . strlen('['.$data.']'),
163
        ]);
164
 
165
        Curl\Util::execute($this->httpConnection, 5, false);
166
    }
167
}