ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 (!$this->validateStringLength($dataArray['message'], static::MAXIMUM_MESSAGE_LENGTH)) {
147 if (function_exists('mb_substr')) {
148 $dataArray['message'] = mb_substr($dataArray['message'], 0, static::MAXIMUM_MESSAGE_LENGTH).' [truncated]';
149 } else {
150 $dataArray['message'] = substr($dataArray['message'], 0, static::MAXIMUM_MESSAGE_LENGTH).' [truncated]';
151 }
152 }
153
154 // if we are using the legacy API then we need to send some additional information
155 if ($this->version == self::API_V1) {
156 $dataArray['room_id'] = $this->room;
157 }
158
159 // append the sender name if it is set
160 // always append it if we use the v1 api (it is required in v1)
161 if ($this->version == self::API_V1 || $this->name !== null) {
162 $dataArray['from'] = (string) $this->name;
163 }
164
165 return http_build_query($dataArray);
166 }
167
174 private function buildHeader($content)
175 {
176 if ($this->version == self::API_V1) {
177 $header = "POST /v1/rooms/message?format=json&auth_token={$this->token} HTTP/1.1\r\n";
178 } else {
179 // needed for rooms with special (spaces, etc) characters in the name
180 $room = rawurlencode($this->room);
181 $header = "POST /v2/room/{$room}/notification?auth_token={$this->token} HTTP/1.1\r\n";
182 }
183
184 $header .= "Host: {$this->host}\r\n";
185 $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
186 $header .= "Content-Length: " . strlen($content) . "\r\n";
187 $header .= "\r\n";
188
189 return $header;
190 }
191
198 protected function getAlertColor($level)
199 {
200 switch (true) {
201 case $level >= Logger::ERROR:
202 return 'red';
203 case $level >= Logger::WARNING:
204 return 'yellow';
205 case $level >= Logger::INFO:
206 return 'green';
207 case $level == Logger::DEBUG:
208 return 'gray';
209 default:
210 return 'yellow';
211 }
212 }
213
219 protected function write(array $record)
220 {
221 parent::write($record);
222 $this->finalizeWrite();
223 }
224
231 protected function finalizeWrite()
232 {
233 $res = $this->getResource();
234 if (is_resource($res)) {
235 @fread($res, 2048);
236 }
237 $this->closeSocket();
238 }
239
243 public function handleBatch(array $records)
244 {
245 if (count($records) == 0) {
246 return true;
247 }
248
249 $batchRecords = $this->combineRecords($records);
250
251 $handled = false;
252 foreach ($batchRecords as $batchRecord) {
253 if ($this->isHandling($batchRecord)) {
254 $this->write($batchRecord);
255 $handled = true;
256 }
257 }
258
259 if (!$handled) {
260 return false;
261 }
262
263 return false === $this->bubble;
264 }
265
274 private function combineRecords($records)
275 {
276 $batchRecord = null;
277 $batchRecords = array();
278 $messages = array();
279 $formattedMessages = array();
280 $level = 0;
281 $levelName = null;
282 $datetime = null;
283
284 foreach ($records as $record) {
285 $record = $this->processRecord($record);
286
287 if ($record['level'] > $level) {
288 $level = $record['level'];
289 $levelName = $record['level_name'];
290 }
291
292 if (null === $datetime) {
293 $datetime = $record['datetime'];
294 }
295
296 $messages[] = $record['message'];
297 $messageStr = implode(PHP_EOL, $messages);
298 $formattedMessages[] = $this->getFormatter()->format($record);
299 $formattedMessageStr = implode('', $formattedMessages);
300
301 $batchRecord = array(
302 'message' => $messageStr,
303 'formatted' => $formattedMessageStr,
304 'context' => array(),
305 'extra' => array(),
306 );
307
308 if (!$this->validateStringLength($batchRecord['formatted'], static::MAXIMUM_MESSAGE_LENGTH)) {
309 // Pop the last message and implode the remaining messages
310 $lastMessage = array_pop($messages);
311 $lastFormattedMessage = array_pop($formattedMessages);
312 $batchRecord['message'] = implode(PHP_EOL, $messages);
313 $batchRecord['formatted'] = implode('', $formattedMessages);
314
315 $batchRecords[] = $batchRecord;
316 $messages = array($lastMessage);
317 $formattedMessages = array($lastFormattedMessage);
318
319 $batchRecord = null;
320 }
321 }
322
323 if (null !== $batchRecord) {
324 $batchRecords[] = $batchRecord;
325 }
326
327 // Set the max level and datetime for all records
328 foreach ($batchRecords as &$batchRecord) {
329 $batchRecord = array_merge(
330 $batchRecord,
331 array(
332 'level' => $level,
333 'level_name' => $levelName,
334 'datetime' => $datetime,
335 )
336 );
337 }
338
339 return $batchRecords;
340 }
341
357 private function validateStringLength($str, $length)
358 {
359 if (function_exists('mb_strlen')) {
360 return (mb_strlen($str) <= $length);
361 }
362
363 return (strlen($str) <= $length);
364 }
365}
An exception for terminatinating execution or to throw for unit testing.
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.
finalizeWrite()
Finalizes the request by reading some bytes and then closing the socket.
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:29
const ERROR
Runtime errors.
Definition: Logger.php:58
const CRITICAL
Critical conditions.
Definition: Logger.php:65
const WARNING
Exceptional occurrences that are not errors.
Definition: Logger.php:53
const INFO
Interesting events.
Definition: Logger.php:40
const DEBUG
Detailed debug information.
Definition: Logger.php:33
PHP_EOL
Definition: complexTest.php:7
$messages
Definition: en.php:5
foreach($_POST as $key=> $value) $res
$records
Definition: simple_test.php:22