MonologHandler.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. use Monolog\Logger;
  3. use Monolog\Handler\AbstractProcessingHandler;
  4. class Raven_Breadcrumbs_MonologHandler extends AbstractProcessingHandler
  5. {
  6. /**
  7. * Translates Monolog log levels to Raven log levels.
  8. */
  9. protected $logLevels = array(
  10. Logger::DEBUG => Raven_Client::DEBUG,
  11. Logger::INFO => Raven_Client::INFO,
  12. Logger::NOTICE => Raven_Client::INFO,
  13. Logger::WARNING => Raven_Client::WARNING,
  14. Logger::ERROR => Raven_Client::ERROR,
  15. Logger::CRITICAL => Raven_Client::FATAL,
  16. Logger::ALERT => Raven_Client::FATAL,
  17. Logger::EMERGENCY => Raven_Client::FATAL,
  18. );
  19. protected $excMatch = '/^exception \'([^\']+)\' with message \'(.+)\' in .+$/s';
  20. /**
  21. * @var Raven_Client the client object that sends the message to the server
  22. */
  23. protected $ravenClient;
  24. /**
  25. * @param Raven_Client $ravenClient
  26. * @param int $level The minimum logging level at which this handler will be triggered
  27. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
  28. */
  29. public function __construct(Raven_Client $ravenClient, $level = Logger::DEBUG, $bubble = true)
  30. {
  31. parent::__construct($level, $bubble);
  32. $this->ravenClient = $ravenClient;
  33. }
  34. /**
  35. * @param string $message
  36. * @return array|null
  37. */
  38. protected function parseException($message)
  39. {
  40. if (preg_match($this->excMatch, $message, $matches)) {
  41. return array($matches[1], $matches[2]);
  42. }
  43. return null;
  44. }
  45. /**
  46. * {@inheritdoc}
  47. */
  48. protected function write(array $record)
  49. {
  50. // sentry uses the 'nobreadcrumb' attribute to skip reporting
  51. if (!empty($record['context']['nobreadcrumb'])) {
  52. return;
  53. }
  54. if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Exception) {
  55. /**
  56. * @var Exception $exc
  57. */
  58. $exc = $record['context']['exception'];
  59. $crumb = array(
  60. 'type' => 'error',
  61. 'level' => $this->logLevels[$record['level']],
  62. 'category' => $record['channel'],
  63. 'data' => array(
  64. 'type' => get_class($exc),
  65. 'value' => $exc->getMessage(),
  66. ),
  67. );
  68. } else {
  69. // TODO(dcramer): parse exceptions out of messages and format as above
  70. if ($error = $this->parseException($record['message'])) {
  71. $crumb = array(
  72. 'type' => 'error',
  73. 'level' => $this->logLevels[$record['level']],
  74. 'category' => $record['channel'],
  75. 'data' => array(
  76. 'type' => $error[0],
  77. 'value' => $error[1],
  78. ),
  79. );
  80. } else {
  81. $crumb = array(
  82. 'level' => $this->logLevels[$record['level']],
  83. 'category' => $record['channel'],
  84. 'message' => $record['message'],
  85. );
  86. }
  87. }
  88. $this->ravenClient->breadcrumbs->record($crumb);
  89. }
  90. }