Thanks to visit codestin.com
Credit goes to github.com

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 <[email protected]>
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)