bzikarsky / gelf-php

A php implementation to send log-files to a gelf compatible backend like graylog
MIT License
408 stars 85 forks source link

Failed to write to socket: fwrite() #88

Closed fajnalowiec closed 7 years ago

fajnalowiec commented 7 years ago

I use this package to send logs via monolog logger to Graylog2 server via UDP. I also use tunelling from my machine to this server, cause I cannot reach it directly. I've configured it with socat based on this example:

http://zarb.org/~gc/html/udp-in-ssh-tunneling.html

Basically, everything works as a charm when the tunel is created. Although when the tunel is not there, then fwrite raises exception (what's more interesning: every 2nd time):

Exception raised 'Failed to write to socket: fwrite(): send of 361 bytes failed with errno=111 Connection refused (8) File: /var/www/paymentdating/vendor/graylog2/gelf-php/src/Gelf/Transport/StreamSocketClient.php, line# 225 (code 0)

so if my code looks like this:

$myLogger->alert('karamba'); $myLogger->alert('karamba'); $myLogger->alert('karamba'); $myLogger->alert('karamba');

The error is raised only for 2nd and 4th call. I thought that because of UDP protocol there will be no exceptions. In the end I like them even, cause I can check the Graylog server is unreachable, although in most cases the script is gonna log only once and then unfortunately no exception is raised by fwrite.

fajnalowiec commented 7 years ago

So it seems the issue is tunelling and to be more specific 127.0.0.1 ip used for UDP. Whenever you change it to external (even fake one) fwrite works fine without raising exceptions. I'm closing it.

gbourgeat commented 6 years ago

I have the same issue @fajnalowiec and I'm not on 127.0.0.1 and not ssh tunneling :(

Sometimes it's ok and sometimes I have this error and I choiced UDP transport just for avoid these errors.

fajnalowiec commented 6 years ago

Hi @gbourgeat; I use it for my logging purpose with monolog logger. For this case I have written my own GelfHandler, which looks smth like that: `use \Gelf\Transport\UdpTransport; use \Gelf\Publisher; use Monolog\Formatter\GelfMessageFormatter;

class GelfHandler extends \Monolog\Handler\GelfHandler { private $systemName; private $requestTime; private $requestSignature;

public function __construct(ConfigEnvEnitity $config, string $systemName, int $requestTime, string $requestSignature, bool $bubble = true)
{
    $this->systemName = $systemName;
    $this->requestTime = $requestTime;
    $this->requestSignature = $requestSignature;
    $configGH = $config->getGelfHandler();
    $transport = new UdpTransport($configGH->getIp(), $configGH->getPort(),
        UdpTransport::CHUNK_SIZE_LAN);
    $publisher = new Publisher();
    $publisher->addTransport($transport);
    return parent::__construct($publisher, $config->getLogLevel(), $bubble);
}

protected function write(array $record)
{
    try {
        parent::write($record);
    } catch (\Exception $e) {
        //do nothing, let the app working, not crushing. Rotating File Handler is gonna handle log
    }
}

public function handle(array $record)
{
    ...
}

}`

So basically, I've overwritten write method and intercept all errors returned by the lib itself. You probably need to do smth like this.

Rah1x commented 1 year ago

Still having this issue:

Failed to write to socket: fwrite(): send of 379 bytes failed with errno=111 Connection refused (8)' in /vendor/graylog2/gelf-php/src/Gelf/Transport/StreamSocketClient.php:226

Versions Checked: 1.7.1 = issue 1.7.0 = same issue 1.6.5 = same issue 1.5.5 = same issue 1.5.4 = same issue 1.5.3 = another issue: "Incomplete write: Only 0 of 371 written" 1.5.1 = same issue 1.5.0 = works fine 1.4.2 = works fine

bzikarsky commented 1 year ago

Hi @Rah1x!

If you get connection timeouts, refused connections, it is (almost) always a network problem. What can happen is that you need to tune a specific network config that is not properly exposes, but in that case you need to debug your network issue first and then tell us (me) what is missing. Then we can think of a good way to expose it.

Pointers for your analysis:

Please understand that I cannot debug individual network problems.

Rah1x commented 1 year ago

@bzikarsky Thanks a lot for the reply. basically, the issue is with the same local IP 127.0.0.1 as mentioned earlier by another person. I will further investigate and reply back.

bzikarsky commented 1 year ago

127.0.0.1 or locahost? Is there potentially a IPv4 vs IPv6 issue? (Your client and server using different IP stacks?)

Rah1x commented 1 year ago

@bzikarsky This is the exact error log if that helps:

Failed to write to socket: fwrite(): send of 367 bytes failed with errno=111 Connection refused (8)
#0 /vendor/graylog2/gelf-php/src/Gelf/Transport/UdpTransport.php(96): Gelf\Transport\StreamSocketClient->write('x\x9C\xA5Q\xCBj#1\x10\xFC\x95\xA0\xB3=\xEF...')
#1 /vendor/graylog2/gelf-php/src/Gelf/Publisher.php(76): Gelf\Transport\UdpTransport->send(Object(Gelf\Message))
#2 /vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php(55): Gelf\Publisher->publish(Object(Gelf\Message))
#3 /vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(39): Monolog\Handler\GelfHandler->write(Array)
#4 /vendor/monolog/monolog/src/Monolog/Logger.php(344): Monolog\Handler\AbstractProcessingHandler->handle(Array)
#5 /vendor/monolog/monolog/src/Monolog/Logger.php(628): Monolog\Logger->addRecord(100, 'lorem_ipsum_message', Array)
#6 /vendor/laravel/framework/src/Illuminate/Log/Writer.php(203): Monolog\Logger->debug('lorem_ipsum_message', Array)
#7 /vendor/laravel/framework/src/Illuminate/Log/Writer.php(162): Illuminate\Log\Writer->writeLog('debug', 'lorem_ipsum_message', Array)
#8 /bla/bla/bla/my_func: Illuminate\Log\Writer->debug('lorem_ipsum_message')
Rah1x commented 1 year ago

@bzikarsky ive tested almost all the versions around ~1.5.0, it works fine up to 1.5.0 and the error starts in any version above that. Clearly something changed in 1.5.1

bzikarsky commented 1 year ago

https://github.com/bzikarsky/gelf-php/compare/1.5.0...1.5.1

There were a few changes to StreamSocketClient::write. From a quick look I assume:

I am pretty sure that <1.5.1 will also fail if you add a heck for bytes written, as we did in 1.5.1

Rah1x commented 1 year ago

@bzikarsky Thanks for the reply and looking into it. Im literally running exact same message. it works when <1.5.0. Atm ive decided to stick to 1.5.0 unfortunately as ive tried every version above it with the same message and they all failed.

bzikarsky commented 1 year ago

:thinking:

Rah1x commented 1 year ago

Thanks for the reply. Sure will do, but first im trying to upgrade laravel and monolog to reduce the possibility of them being responsible for this issue.