[GH-ISSUE #1274] Cannot write to sftp file #525

Closed
opened 2026-03-04 02:15:43 +03:00 by kerem · 2 comments
Owner

Originally created by @troccoli on GitHub (Jan 2, 2019).
Original GitHub issue: https://github.com/Seldaek/monolog/issues/1274

I am trying to use the StreamHandler with an sftp resource.

My code looks like this

class SftpHandler extends StreamHandler
{

    public function __construct($host, $username, $password, $filename, $level)
    {
        $connection = ssh2_connect($host, 22);
        ssh2_auth_password($connection, $username, $password);
        $sftp = ssh2_sftp($connection);
        $this->stream = fopen("ssh2.sftp://" . (int)$sftp . '/./'. $filename, 'bw');

        parent::__construct($this->stream, $level);
    }
}

However, it seems that the fwrite fails silently. It doesn't return false nor any number of bytes written. To be clear, the following debugging code does not output anything

var_dump(fwrite($stream, (string) $record['formatted']));

Now, interestingly, if I try to write something in the constructor, e.g.

public function __construct($host, $username, $password, $filename, $level)
    {
        $connection = ssh2_connect($host, 22);
        ssh2_auth_password($connection, $username, $password);
        $sftp = ssh2_sftp($connection);
        $this->stream = fopen("ssh2.sftp://" . (int)$sftp . '/./'. $filename, 'bw');

        fwrite($this->stream, "testing\n");

        parent::__construct($this->stream, $level);
    }

I've got my testing string in the file.

Originally created by @troccoli on GitHub (Jan 2, 2019). Original GitHub issue: https://github.com/Seldaek/monolog/issues/1274 I am trying to use the StreamHandler with an sftp resource. My code looks like this ```php class SftpHandler extends StreamHandler { public function __construct($host, $username, $password, $filename, $level) { $connection = ssh2_connect($host, 22); ssh2_auth_password($connection, $username, $password); $sftp = ssh2_sftp($connection); $this->stream = fopen("ssh2.sftp://" . (int)$sftp . '/./'. $filename, 'bw'); parent::__construct($this->stream, $level); } } ``` However, it seems that the `fwrite` fails silently. It doesn't return `false` nor any number of bytes written. To be clear, the following debugging code does not output anything ```php var_dump(fwrite($stream, (string) $record['formatted'])); ``` Now, interestingly, if I try to write something in the constructor, e.g. ```php public function __construct($host, $username, $password, $filename, $level) { $connection = ssh2_connect($host, 22); ssh2_auth_password($connection, $username, $password); $sftp = ssh2_sftp($connection); $this->stream = fopen("ssh2.sftp://" . (int)$sftp . '/./'. $filename, 'bw'); fwrite($this->stream, "testing\n"); parent::__construct($this->stream, $level); } ``` I've got my `testing` string in the file.
kerem closed this issue 2026-03-04 02:15:43 +03:00
Author
Owner

@troccoli commented on GitHub (Jan 3, 2019):

Apparently the issue is that the stream is somehow closed, even if I store it in a protected property.

I have refactored the handler as follows and it works.

namespace App\Logging;

use Monolog\Handler\StreamHandler;

class SftpHandler extends StreamHandler
{
    protected $host;
    protected $username;
    protected $password;
    protected $filename;
    protected $sftpStream;

    public function __construct($host, $username, $password, $filename, $level)
    {
        $this->host = $host;
        $this->username = $username;
        $this->password = $password;
        $this->filename = $filename;

        $sftp = $this->getSftpResource();
        
        $this->stream = fopen("ssh2.sftp://" . (int)$sftp . '/./' . $this->filename, 'wt');

        parent::__construct($this->stream, $level);
    }

    protected function streamWrite($stream, array $record)
    {
        $sftp = $this->getSftpResource();

        $stream = fopen("ssh2.sftp://" . (int)$sftp . '/./' . $this->filename, 'at');

        parent::streamWrite($stream, $record);

        fclose($stream);
    }

    private function getSftpResource()
    {
        $connection = ssh2_connect($this->host, 22);
        ssh2_auth_password($connection, $this->username, $this->password);
        return ssh2_sftp($connection);
    }
}

However, it's not really great coding.

Since, as I said, I believe $stream is somehow closed prematurely, or in any case using it again does not work, I have to open a new stream every time. And I cannot refactor the opening of the stream in its own method as I would have the same problem, i.e. the stream is close prematurely. Besides, I need to change the opening mode, from w to a, although this may be because of an issue with the sftp server (which is not under my control, so I cannot know for sure).

For the time being I keep this code. If anyone has any suggestions on how to make it better please comment on this issue.

<!-- gh-comment-id:451107925 --> @troccoli commented on GitHub (Jan 3, 2019): Apparently the issue is that the stream is somehow closed, even if I store it in a protected property. I have refactored the handler as follows and it works. ```php namespace App\Logging; use Monolog\Handler\StreamHandler; class SftpHandler extends StreamHandler { protected $host; protected $username; protected $password; protected $filename; protected $sftpStream; public function __construct($host, $username, $password, $filename, $level) { $this->host = $host; $this->username = $username; $this->password = $password; $this->filename = $filename; $sftp = $this->getSftpResource(); $this->stream = fopen("ssh2.sftp://" . (int)$sftp . '/./' . $this->filename, 'wt'); parent::__construct($this->stream, $level); } protected function streamWrite($stream, array $record) { $sftp = $this->getSftpResource(); $stream = fopen("ssh2.sftp://" . (int)$sftp . '/./' . $this->filename, 'at'); parent::streamWrite($stream, $record); fclose($stream); } private function getSftpResource() { $connection = ssh2_connect($this->host, 22); ssh2_auth_password($connection, $this->username, $this->password); return ssh2_sftp($connection); } } ``` However, it's not really great coding. Since, as I said, I believe `$stream` is somehow closed prematurely, or in any case using it again does not work, I have to open a new stream every time. And I cannot refactor the opening of the stream in its own method as I would have the same problem, i.e. the stream is close prematurely. Besides, I need to change the opening mode, from `w` to `a`, although this may be because of an issue with the sftp server (which is not under my control, so I cannot know for sure). For the time being I keep this code. If anyone has any suggestions on how to make it better please comment on this issue.
Author
Owner

@Seldaek commented on GitHub (Jun 30, 2019):

Sorry but no idea about sftp/ssh2 in PHP so can't really help, doesn't look like this is directly something Monolog as a project can do so I will close this.

<!-- gh-comment-id:507049531 --> @Seldaek commented on GitHub (Jun 30, 2019): Sorry but no idea about sftp/ssh2 in PHP so can't really help, doesn't look like this is directly something Monolog as a project can do so I will close this.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/monolog#525
No description provided.