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 
12 namespace Monolog\Handler;
13 
14 use Monolog\Logger;
15 
30 {
34  const API_V1 = 'v1';
35 
39  const API_V2 = 'v2';
40 
44  const MAXIMUM_NAME_LENGTH = 15;
45 
49  const MAXIMUM_MESSAGE_LENGTH = 9500;
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 }
const DEBUG
Detailed debug information.
Definition: Logger.php:32
const ERROR
Runtime errors.
Definition: Logger.php:57
Stores to any socket - uses fsockopen() or pfsockopen().
$records
Definition: simple_test.php:17
Sends notifications through the hipchat api to a hipchat room.
handleBatch(array $records)
{Handles a set of records at once.The records to handle (an array of record arrays)} ...
const API_V2
Use API version v2.
$header
const MAXIMUM_NAME_LENGTH
The maximum allowed length for the name used in the "from" field.
const MAXIMUM_MESSAGE_LENGTH
The maximum allowed length for the message.
getFormatter()
{Gets the formatter.FormatterInterface}
const WARNING
Exceptional occurrences that are not errors.
Definition: Logger.php:52
__construct($token, $room, $name='Monolog', $notify=false, $level=Logger::CRITICAL, $bubble=true, $useSSL=true, $format='text', $host='api.hipchat.com', $version=self::API_V1)
const CRITICAL
Critical conditions.
Definition: Logger.php:64
const API_V1
Use API version 1.
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.
buildHeader($content)
Builds the header of the API Call.
$messages
Definition: en-x-test.php:7
combineRecords($records)
Combines multiple records into one.
getAlertColor($level)
Assigns a color to each level of log records.
closeSocket()
Close socket, if open.
validateStringLength($str, $length)
Validates the length of a string.
buildContent($record)
Builds the body of API call.
const INFO
Interesting events.
Definition: Logger.php:39