ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 (!$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->closeSocket();
223  }
224 
228  public function handleBatch(array $records)
229  {
230  if (count($records) == 0) {
231  return true;
232  }
233 
234  $batchRecords = $this->combineRecords($records);
235 
236  $handled = false;
237  foreach ($batchRecords as $batchRecord) {
238  if ($this->isHandling($batchRecord)) {
239  $this->write($batchRecord);
240  $handled = true;
241  }
242  }
243 
244  if (!$handled) {
245  return false;
246  }
247 
248  return false === $this->bubble;
249  }
250 
259  private function combineRecords($records)
260  {
261  $batchRecord = null;
262  $batchRecords = array();
263  $messages = array();
264  $formattedMessages = array();
265  $level = 0;
266  $levelName = null;
267  $datetime = null;
268 
269  foreach ($records as $record) {
270  $record = $this->processRecord($record);
271 
272  if ($record['level'] > $level) {
273  $level = $record['level'];
274  $levelName = $record['level_name'];
275  }
276 
277  if (null === $datetime) {
278  $datetime = $record['datetime'];
279  }
280 
281  $messages[] = $record['message'];
282  $messageStr = implode(PHP_EOL, $messages);
283  $formattedMessages[] = $this->getFormatter()->format($record);
284  $formattedMessageStr = implode('', $formattedMessages);
285 
286  $batchRecord = array(
287  'message' => $messageStr,
288  'formatted' => $formattedMessageStr,
289  'context' => array(),
290  'extra' => array(),
291  );
292 
293  if (!$this->validateStringLength($batchRecord['formatted'], static::MAXIMUM_MESSAGE_LENGTH)) {
294  // Pop the last message and implode the remaining messages
295  $lastMessage = array_pop($messages);
296  $lastFormattedMessage = array_pop($formattedMessages);
297  $batchRecord['message'] = implode(PHP_EOL, $messages);
298  $batchRecord['formatted'] = implode('', $formattedMessages);
299 
300  $batchRecords[] = $batchRecord;
301  $messages = array($lastMessage);
302  $formattedMessages = array($lastFormattedMessage);
303 
304  $batchRecord = null;
305  }
306  }
307 
308  if (null !== $batchRecord) {
309  $batchRecords[] = $batchRecord;
310  }
311 
312  // Set the max level and datetime for all records
313  foreach ($batchRecords as &$batchRecord) {
314  $batchRecord = array_merge(
315  $batchRecord,
316  array(
317  'level' => $level,
318  'level_name' => $levelName,
319  'datetime' => $datetime,
320  )
321  );
322  }
323 
324  return $batchRecords;
325  }
326 
342  private function validateStringLength($str, $length)
343  {
344  if (function_exists('mb_strlen')) {
345  return (mb_strlen($str) <= $length);
346  }
347 
348  return (strlen($str) <= $length);
349  }
350 }
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().
Add rich text string
The name of the decorator.
$records
Definition: simple_test.php:22
Sends notifications through the hipchat api to a hipchat room.
$dataArray
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
if($is_dev) echo "Review changes write something in WHATSNEW and and then commit with log PHP_EOL
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)
Create styles array
The data for the language used.
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
Write to Excel2007 format
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