ElasticSearchHandler.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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\Formatter\FormatterInterface;
  12. use Monolog\Formatter\ElasticaFormatter;
  13. use Monolog\Logger;
  14. use Elastica\Client;
  15. use Elastica\Exception\ExceptionInterface;
  16. /**
  17. * Elastic Search handler
  18. *
  19. * Usage example:
  20. *
  21. * $client = new \Elastica\Client();
  22. * $options = array(
  23. * 'index' => 'elastic_index_name',
  24. * 'type' => 'elastic_doc_type',
  25. * );
  26. * $handler = new ElasticSearchHandler($client, $options);
  27. * $log = new Logger('application');
  28. * $log->pushHandler($handler);
  29. *
  30. * @author Jelle Vink <jelle.vink@gmail.com>
  31. */
  32. class ElasticSearchHandler extends AbstractProcessingHandler
  33. {
  34. /**
  35. * @var Client
  36. */
  37. protected $client;
  38. /**
  39. * @var array Handler config options
  40. */
  41. protected $options = array();
  42. /**
  43. * @param Client $client Elastica Client object
  44. * @param array $options Handler configuration
  45. * @param int $level The minimum logging level at which this handler will be triggered
  46. * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
  47. */
  48. public function __construct(Client $client, array $options = array(), $level = Logger::DEBUG, $bubble = true)
  49. {
  50. parent::__construct($level, $bubble);
  51. $this->client = $client;
  52. $this->options = array_merge(
  53. array(
  54. 'index' => 'monolog', // Elastic index name
  55. 'type' => 'record', // Elastic document type
  56. 'ignore_error' => false, // Suppress Elastica exceptions
  57. ),
  58. $options
  59. );
  60. }
  61. /**
  62. * {@inheritDoc}
  63. */
  64. protected function write(array $record)
  65. {
  66. $this->bulkSend(array($record['formatted']));
  67. }
  68. /**
  69. * {@inheritdoc}
  70. */
  71. public function setFormatter(FormatterInterface $formatter)
  72. {
  73. if ($formatter instanceof ElasticaFormatter) {
  74. return parent::setFormatter($formatter);
  75. }
  76. throw new \InvalidArgumentException('ElasticSearchHandler is only compatible with ElasticaFormatter');
  77. }
  78. /**
  79. * Getter options
  80. * @return array
  81. */
  82. public function getOptions()
  83. {
  84. return $this->options;
  85. }
  86. /**
  87. * {@inheritDoc}
  88. */
  89. protected function getDefaultFormatter()
  90. {
  91. return new ElasticaFormatter($this->options['index'], $this->options['type']);
  92. }
  93. /**
  94. * {@inheritdoc}
  95. */
  96. public function handleBatch(array $records)
  97. {
  98. $documents = $this->getFormatter()->formatBatch($records);
  99. $this->bulkSend($documents);
  100. }
  101. /**
  102. * Use Elasticsearch bulk API to send list of documents
  103. * @param array $documents
  104. * @throws \RuntimeException
  105. */
  106. protected function bulkSend(array $documents)
  107. {
  108. try {
  109. $this->client->addDocuments($documents);
  110. } catch (ExceptionInterface $e) {
  111. if (!$this->options['ignore_error']) {
  112. throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e);
  113. }
  114. }
  115. }
  116. }