Skip to content

Commit 957d8c2

Browse files
committed
handle exception
1 parent acb81f8 commit 957d8c2

File tree

1 file changed

+42
-18
lines changed

1 file changed

+42
-18
lines changed

src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,24 @@
1616
use Monolog\Handler\AbstractHandler;
1717
use Monolog\Logger;
1818
use Symfony\Component\HttpClient\HttpClient;
19+
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
1920
use Symfony\Contracts\HttpClient\HttpClientInterface;
2021

2122
/**
2223
* Push logs directly to Elasticsearch and format them according to Logstash specification.
2324
*
24-
* This handler dials directly with the HTTP interface of elasticsearch. This
25-
* means it will slow down your application if elasticsearch takes times to
25+
* This handler dials directly with the HTTP interface of Elasticsearch. This
26+
* means it will slow down your application if Elasticsearch takes times to
2627
* answer. Even if all HTTP calls are done asynchronously.
2728
*
2829
* In a development environment, it's fine to keep the default configuration:
29-
* For each log, an HTTP request will be made to push the log to Elasticsearch.
30+
* for each log, an HTTP request will be made to push the log to Elasticsearch.
3031
*
31-
* But in a production environment, it's highly recommended to wrap this handler
32-
* in an handler with buffering capability (like the FingersCrossedHandler, or
33-
* BufferHandler) in order to call Elasticsearch only once. For even better
34-
* performance and fault tolerance, a proper ELK stack is recommended.
32+
* In a production environment, it's highly recommended to wrap this handler
33+
* in a handler with buffering capabilities (like the FingersCrossedHandler, or
34+
* BufferHandler) in order to call Elasticsearch only once with a bulk push. For
35+
* even better performance and fault tolerance, a proper ELK (https://www.elastic.co/what-is/elk-stack)
36+
* stack is recommended.
3537
*
3638
* @author Grégoire Pineau <lyrixx@lyrixx.info>
3739
*/
@@ -45,7 +47,7 @@ class ElasticsearchLogstashHandler extends AbstractHandler
4547
public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $index = 'monolog', HttpClientInterface $client = null, int $level = Logger::DEBUG, bool $bubble = true)
4648
{
4749
if (!interface_exists(HttpClientInterface::class)) {
48-
throw new \LogicException(sprintf('The %s handler needs symfony/http-client, please run `composer require symfony/http-client`.', __CLASS__));
50+
throw new \LogicException(sprintf('The %s handler needs an HTTP client. Try running "composer require symfony/http-client".', __CLASS__));
4951
}
5052

5153
parent::__construct($level, $bubble);
@@ -63,20 +65,16 @@ public function handle(array $record): bool
6365

6466
$this->sendToElasticsearch([$record]);
6567

66-
return false === $this->bubble;
68+
return !$this->bubble;
6769
}
6870

6971
public function handleBatch(array $records): void
7072
{
71-
$records = array_filter($records, function (array $record) {
72-
return $this->isHandling($record);
73-
});
73+
$records = array_filter($records, [$this, 'isHandling']);
7474

75-
if (!$records) {
76-
return;
75+
if ($records) {
76+
$this->sendToElasticsearch($records);
7777
}
78-
79-
$this->sendToElasticsearch($records);
8078
}
8179

8280
protected function getDefaultFormatter(): FormatterInterface
@@ -116,10 +114,36 @@ private function sendToElasticsearch(array $records)
116114

117115
$this->responses->attach($response);
118116

119-
foreach ($this->client->stream($this->responses, 0) as $response => $chunk) {
120-
if (!$chunk->isTimeout() && $chunk->isFirst()) {
117+
$this->wait(0.0, false);
118+
}
119+
120+
public function __destruct()
121+
{
122+
$this->wait(null, true);
123+
}
124+
125+
private function wait(?float $timeout, bool $errorOnTimeout)
126+
{
127+
$e = null;
128+
129+
foreach ($this->client->stream($this->responses) as $response => $chunk) {
130+
try {
131+
if ($chunk->isTimeout() && !$errorOnTimeout) {
132+
continue;
133+
}
134+
if (!$chunk->isFirst() && !$chunk->isLast()) {
135+
continue;
136+
}
137+
if ($chunk->isLast()) {
138+
$this->responses->detach($response);
139+
}
140+
} catch (ExceptionInterface $e) {
121141
$this->responses->detach($response);
122142
}
123143
}
144+
145+
if ($e) {
146+
error_log(sprintf("Could not push logs to Elasticsearch:\n%s", (string) $e));
147+
}
124148
}
125149
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy