ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
HipChatHandler.php
Go to the documentation of this file.
1<?php
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
12namespace Monolog\Handler;
13
15
30{
34 const API_V1 = 'v1';
35
39 const API_V2 = 'v2';
40
45
50
54 private $token;
55
59 private $room;
60
64 private $name;
65
69 private $notify;
70
74 private $format;
75
79 private $host;
80
84 private $version;
85
98 public function __construct($token, $room, $name = 'Monolog', $notify = false, $level = Logger::CRITICAL, $bubble = true, $useSSL = true, $format = 'text', $host = 'api.hipchat.com', $version = self::API_V1)
99 {
100 if ($version == self::API_V1 && !$this->validateStringLength($name, static::MAXIMUM_NAME_LENGTH)) {
101 throw new \InvalidArgumentException('The supplied name is too long. HipChat\'s v1 API supports names up to 15 UTF-8 characters.');
102 }
103
104 $connectionString = $useSSL ? 'ssl://'.$host.':443' : $host.':80';
105 parent::__construct($connectionString, $level, $bubble);
106
107 $this->token = $token;
108 $this->name = $name;
109 $this->notify = $notify;
110 $this->room = $room;
111 $this->format = $format;
112 $this->host = $host;
113 $this->version = $version;
114 }
115
122 protected function generateDataStream($record)
123 {
124 $content = $this->buildContent($record);
125
126 return $this->buildHeader($content) . $content;
127 }
128
135 private function buildContent($record)
136 {
137 $dataArray = array(
138 'notify' => $this->version == self::API_V1 ?
139 ($this->notify ? 1 : 0) :
140 ($this->notify ? 'true' : 'false'),
141 'message' => $record['formatted'],
142 'message_format' => $this->format,
143 'color' => $this->getAlertColor($record['level']),
144 );
145
146 // if we are using the legacy API then we need to send some additional information
147 if ($this->version == self::API_V1) {
148 $dataArray['room_id'] = $this->room;
149 $dataArray['from'] = $this->name;
150 }
151
152 return http_build_query($dataArray);
153 }
154
161 private function buildHeader($content)
162 {
163 if ($this->version == self::API_V1) {
164 $header = "POST /v1/rooms/message?format=json&auth_token={$this->token} HTTP/1.1\r\n";
165 } else {
166 // needed for rooms with special (spaces, etc) characters in the name
167 $room = rawurlencode($this->room);
168 $header = "POST /v2/room/{$room}/notification?auth_token={$this->token} HTTP/1.1\r\n";
169 }
170
171 $header .= "Host: {$this->host}\r\n";
172 $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
173 $header .= "Content-Length: " . strlen($content) . "\r\n";
174 $header .= "\r\n";
175
176 return $header;
177 }
178
185 protected function getAlertColor($level)
186 {
187 switch (true) {
188 case $level >= Logger::ERROR:
189 return 'red';
190 case $level >= Logger::WARNING:
191 return 'yellow';
192 case $level >= Logger::INFO:
193 return 'green';
194 case $level == Logger::DEBUG:
195 return 'gray';
196 default:
197 return 'yellow';
198 }
199 }
200
206 protected function write(array $record)
207 {
208 parent::write($record);
209 $this->closeSocket();
210 }
211
215 public function handleBatch(array $records)
216 {
217 if (count($records) == 0) {
218 return true;
219 }
220
221 $batchRecords = $this->combineRecords($records);
222
223 $handled = false;
224 foreach ($batchRecords as $batchRecord) {
225 if ($this->isHandling($batchRecord)) {
226 $this->write($batchRecord);
227 $handled = true;
228 }
229 }
230
231 if (!$handled) {
232 return false;
233 }
234
235 return false === $this->bubble;
236 }
237
246 private function combineRecords($records)
247 {
248 $batchRecord = null;
249 $batchRecords = array();
250 $messages = array();
251 $formattedMessages = array();
252 $level = 0;
253 $levelName = null;
254 $datetime = null;
255
256 foreach ($records as $record) {
257 $record = $this->processRecord($record);
258
259 if ($record['level'] > $level) {
260 $level = $record['level'];
261 $levelName = $record['level_name'];
262 }
263
264 if (null === $datetime) {
265 $datetime = $record['datetime'];
266 }
267
268 $messages[] = $record['message'];
269 $messageStr = implode(PHP_EOL, $messages);
270 $formattedMessages[] = $this->getFormatter()->format($record);
271 $formattedMessageStr = implode('', $formattedMessages);
272
273 $batchRecord = array(
274 'message' => $messageStr,
275 'formatted' => $formattedMessageStr,
276 'context' => array(),
277 'extra' => array(),
278 );
279
280 if (!$this->validateStringLength($batchRecord['formatted'], static::MAXIMUM_MESSAGE_LENGTH)) {
281 // Pop the last message and implode the remaining messages
282 $lastMessage = array_pop($messages);
283 $lastFormattedMessage = array_pop($formattedMessages);
284 $batchRecord['message'] = implode(PHP_EOL, $messages);
285 $batchRecord['formatted'] = implode('', $formattedMessages);
286
287 $batchRecords[] = $batchRecord;
288 $messages = array($lastMessage);
289 $formattedMessages = array($lastFormattedMessage);
290
291 $batchRecord = null;
292 }
293 }
294
295 if (null !== $batchRecord) {
296 $batchRecords[] = $batchRecord;
297 }
298
299 // Set the max level and datetime for all records
300 foreach ($batchRecords as &$batchRecord) {
301 $batchRecord = array_merge(
302 $batchRecord,
303 array(
304 'level' => $level,
305 'level_name' => $levelName,
306 'datetime' => $datetime
307 )
308 );
309 }
310
311 return $batchRecords;
312 }
313
329 private function validateStringLength($str, $length)
330 {
331 if (function_exists('mb_strlen')) {
332 return (mb_strlen($str) <= $length);
333 }
334
335 return (strlen($str) <= $length);
336 }
337}
getFormatter()
{Gets the formatter.FormatterInterface}
isHandling(array $record)
{Checks whether the given record will be handled by this handler.This is mostly done for performance ...
processRecord(array $record)
Processes a record.
Sends notifications through the hipchat api to a hipchat room.
const MAXIMUM_NAME_LENGTH
The maximum allowed length for the name used in the "from" field.
__construct($token, $room, $name='Monolog', $notify=false, $level=Logger::CRITICAL, $bubble=true, $useSSL=true, $format='text', $host='api.hipchat.com', $version=self::API_V1)
buildContent($record)
Builds the body of API call.
buildHeader($content)
Builds the header of the API Call.
const API_V1
Use API version 1.
handleBatch(array $records)
{{Handles a set of records at once.}}
write(array $record)
{Connect (if necessary) and write to the socket.UnexpectedValueException RuntimeException}
const MAXIMUM_MESSAGE_LENGTH
The maximum allowed length for the message.
const API_V2
Use API version v2.
validateStringLength($str, $length)
Validates the length of a string.
combineRecords($records)
Combines multiple records into one.
getAlertColor($level)
Assigns a color to each level of log records.
Stores to any socket - uses fsockopen() or pfsockopen().
closeSocket()
Close socket, if open.
Monolog log channel.
Definition: Logger.php:28
const ERROR
Runtime errors.
Definition: Logger.php:57
const CRITICAL
Critical conditions.
Definition: Logger.php:64
const WARNING
Exceptional occurrences that are not errors.
Definition: Logger.php:52
const INFO
Interesting events.
Definition: Logger.php:39
const DEBUG
Detailed debug information.
Definition: Logger.php:32
$header
$messages
Definition: en-x-test.php:7
$records
Definition: simple_test.php:17