PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php

https://gitlab.com/Pasantias/pasantiasASLG
PHP | 289 lines | 154 code | 34 blank | 101 comment | 17 complexity | 44a204d7d99de22103c6ff2b3abf5cc8 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Monolog package.
  4. *
  5. * (c) Jordi Boggiano <j.boggiano@seld.be>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Monolog\Handler;
  11. use Monolog\Logger;
  12. use Monolog\Formatter\LineFormatter;
  13. /**
  14. * Sends notifications through Slack API
  15. *
  16. * @author Greg Kedzierski <greg@gregkedzierski.com>
  17. * @see https://api.slack.com/
  18. */
  19. class SlackHandler extends SocketHandler
  20. {
  21. /**
  22. * Slack API token
  23. * @var string
  24. */
  25. private $token;
  26. /**
  27. * Slack channel (encoded ID or name)
  28. * @var string
  29. */
  30. private $channel;
  31. /**
  32. * Name of a bot
  33. * @var string
  34. */
  35. private $username;
  36. /**
  37. * Emoji icon name
  38. * @var string
  39. */
  40. private $iconEmoji;
  41. /**
  42. * Whether the message should be added to Slack as attachment (plain text otherwise)
  43. * @var bool
  44. */
  45. private $useAttachment;
  46. /**
  47. * Whether the the context/extra messages added to Slack as attachments are in a short style
  48. * @var bool
  49. */
  50. private $useShortAttachment;
  51. /**
  52. * Whether the attachment should include context and extra data
  53. * @var bool
  54. */
  55. private $includeContextAndExtra;
  56. /**
  57. * @var LineFormatter
  58. */
  59. private $lineFormatter;
  60. /**
  61. * @param string $token Slack API token
  62. * @param string $channel Slack channel (encoded ID or name)
  63. * @param string $username Name of a bot
  64. * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise)
  65. * @param string|null $iconEmoji The emoji name to use (or null)
  66. * @param int $level The minimum logging level at which this handler will be triggered
  67. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
  68. * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style
  69. * @param bool $includeContextAndExtra Whether the attachment should include context and extra data
  70. * @throws MissingExtensionException If no OpenSSL PHP extension configured
  71. */
  72. public function __construct($token, $channel, $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $level = Logger::CRITICAL, $bubble = true, $useShortAttachment = false, $includeContextAndExtra = false)
  73. {
  74. if (!extension_loaded('openssl')) {
  75. throw new MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler');
  76. }
  77. parent::__construct('ssl://slack.com:443', $level, $bubble);
  78. $this->token = $token;
  79. $this->channel = $channel;
  80. $this->username = $username;
  81. $this->iconEmoji = trim($iconEmoji, ':');
  82. $this->useAttachment = $useAttachment;
  83. $this->useShortAttachment = $useShortAttachment;
  84. $this->includeContextAndExtra = $includeContextAndExtra;
  85. if ($this->includeContextAndExtra && $this->useShortAttachment) {
  86. $this->lineFormatter = new LineFormatter;
  87. }
  88. }
  89. /**
  90. * {@inheritdoc}
  91. *
  92. * @param array $record
  93. * @return string
  94. */
  95. protected function generateDataStream($record)
  96. {
  97. $content = $this->buildContent($record);
  98. return $this->buildHeader($content) . $content;
  99. }
  100. /**
  101. * Builds the body of API call
  102. *
  103. * @param array $record
  104. * @return string
  105. */
  106. private function buildContent($record)
  107. {
  108. $dataArray = $this->prepareContentData($record);
  109. return http_build_query($dataArray);
  110. }
  111. /**
  112. * Prepares content data
  113. *
  114. * @param array $record
  115. * @return array
  116. */
  117. protected function prepareContentData($record)
  118. {
  119. $dataArray = array(
  120. 'token' => $this->token,
  121. 'channel' => $this->channel,
  122. 'username' => $this->username,
  123. 'text' => '',
  124. 'attachments' => array(),
  125. );
  126. if ($this->useAttachment) {
  127. $attachment = array(
  128. 'fallback' => $record['message'],
  129. 'color' => $this->getAttachmentColor($record['level']),
  130. 'fields' => array(),
  131. );
  132. if ($this->useShortAttachment) {
  133. $attachment['title'] = $record['level_name'];
  134. $attachment['text'] = $record['message'];
  135. } else {
  136. $attachment['title'] = 'Message';
  137. $attachment['text'] = $record['message'];
  138. $attachment['fields'][] = array(
  139. 'title' => 'Level',
  140. 'value' => $record['level_name'],
  141. 'short' => true,
  142. );
  143. }
  144. if ($this->includeContextAndExtra) {
  145. if (!empty($record['extra'])) {
  146. if ($this->useShortAttachment) {
  147. $attachment['fields'][] = array(
  148. 'title' => "Extra",
  149. 'value' => $this->stringify($record['extra']),
  150. 'short' => $this->useShortAttachment,
  151. );
  152. } else {
  153. // Add all extra fields as individual fields in attachment
  154. foreach ($record['extra'] as $var => $val) {
  155. $attachment['fields'][] = array(
  156. 'title' => $var,
  157. 'value' => $val,
  158. 'short' => $this->useShortAttachment,
  159. );
  160. }
  161. }
  162. }
  163. if (!empty($record['context'])) {
  164. if ($this->useShortAttachment) {
  165. $attachment['fields'][] = array(
  166. 'title' => "Context",
  167. 'value' => $this->stringify($record['context']),
  168. 'short' => $this->useShortAttachment,
  169. );
  170. } else {
  171. // Add all context fields as individual fields in attachment
  172. foreach ($record['context'] as $var => $val) {
  173. $attachment['fields'][] = array(
  174. 'title' => $var,
  175. 'value' => $val,
  176. 'short' => $this->useShortAttachment,
  177. );
  178. }
  179. }
  180. }
  181. }
  182. $dataArray['attachments'] = json_encode(array($attachment));
  183. } else {
  184. $dataArray['text'] = $record['message'];
  185. }
  186. if ($this->iconEmoji) {
  187. $dataArray['icon_emoji'] = ":{$this->iconEmoji}:";
  188. }
  189. return $dataArray;
  190. }
  191. /**
  192. * Builds the header of the API Call
  193. *
  194. * @param string $content
  195. * @return string
  196. */
  197. private function buildHeader($content)
  198. {
  199. $header = "POST /api/chat.postMessage HTTP/1.1\r\n";
  200. $header .= "Host: slack.com\r\n";
  201. $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
  202. $header .= "Content-Length: " . strlen($content) . "\r\n";
  203. $header .= "\r\n";
  204. return $header;
  205. }
  206. /**
  207. * {@inheritdoc}
  208. *
  209. * @param array $record
  210. */
  211. protected function write(array $record)
  212. {
  213. parent::write($record);
  214. $res = $this->getResource();
  215. if (is_resource($res)) {
  216. @fread($res, 2048);
  217. }
  218. $this->closeSocket();
  219. }
  220. /**
  221. * Returned a Slack message attachment color associated with
  222. * provided level.
  223. *
  224. * @param int $level
  225. * @return string
  226. */
  227. protected function getAttachmentColor($level)
  228. {
  229. switch (true) {
  230. case $level >= Logger::ERROR:
  231. return 'danger';
  232. case $level >= Logger::WARNING:
  233. return 'warning';
  234. case $level >= Logger::INFO:
  235. return 'good';
  236. default:
  237. return '#e3e4e6';
  238. }
  239. }
  240. /**
  241. * Stringifies an array of key/value pairs to be used in attachment fields
  242. *
  243. * @param array $fields
  244. * @return string
  245. */
  246. protected function stringify($fields)
  247. {
  248. $string = '';
  249. foreach ($fields as $var => $val) {
  250. $string .= $var.': '.$this->lineFormatter->stringify($val)." | ";
  251. }
  252. $string = rtrim($string, " |");
  253. return $string;
  254. }
  255. }