Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Declaration of Handler::write(array $record): void must be compatible with AbstractProcessingHandler::write(Monolog\LogRecord $record): void #81

Closed
mafftor opened this issue Jun 27, 2023 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@mafftor
Copy link

mafftor commented Jun 27, 2023

Describe the bug
Broken symfony logging bundle

To Reproduce
Steps to reproduce the behavior:

  1. Install laravel 10
  2. Install this bundle telebot
  3. Setup new logging channel described in docs laravel
  4. Specify default log_channel as newly created
  5. Log something
  6. perform request

Expected behavior
Message sent to the chat id

Screenshots
image

Additional context
Bundle v2.7.1

@mafftor mafftor added the bug Something isn't working label Jun 27, 2023
@mafftor
Copy link
Author

mafftor commented Jun 27, 2023

I've changed in Handler.php following:

use Monolog\LogRecord;
public function write(LogRecord $record): void
private function formatText(LogRecord $record): string
return view('telebot::log', array_merge(['formatted' => $record->formatted], $record->toArray(), [

Here is entire updated class:

<?php

namespace WeStacks\TeleBot\Laravel\Log;

use Monolog\Formatter\FormatterInterface;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\LogRecord;
use Monolog\Logger;
use WeStacks\TeleBot\TeleBot;

class Handler extends AbstractProcessingHandler
{
    /**
     * Bot instance.
     *
     * @var TeleBot
     */
    protected $bot;

    /**
     * Chat id to send log message.
     *
     * @var string
     */
    protected $chat_id;

    /**
     * App name.
     *
     * @var string
     */
    protected $app;

    /**
     * App env.
     *
     * @var string
     */
    protected $env;

    public function __construct(array $config)
    {
        $level = Logger::toMonologLevel($config['level']);

        parent::__construct($level, true);

        // define variables for making Telegram request
        $this->bot = app('telebot')->bot($config['bot'] ?? null);
        $this->chat_id = $config['chat_id'];

        // define variables for text message
        $this->app = config('app.name');
        $this->env = config('app.env');
    }

    public function write(LogRecord $record): void
    {
        $textChunks = str_split($this->formatText($record), 4096);

        foreach ($textChunks as $textChunk) {
            $this->sendMessage($textChunk);
        }
    }

    /**
     * {@inheritDoc}
     */
    protected function getDefaultFormatter(): FormatterInterface
    {
        return new LineFormatter("%message% %context% %extra%\n");
    }

    private function formatText(LogRecord $record): string
    {
        return view('telebot::log', array_merge(['formatted' => $record->formatted], $record->toArray(), [
            'app' => $this->app,
            'env' => $this->env,
        ]))->render();
    }

    private function sendMessage(string $text): void
    {
        $this->bot->exceptions(false)->async(false)->sendMessage([
            'chat_id' => $this->chat_id,
            'parse_mode' => 'html',
            'text' => $text,
        ]);
    }
}

@mafftor
Copy link
Author

mafftor commented Jun 27, 2023

Here is my logging config

'telegram' => [
            'formatter' => Monolog\Formatter\LineFormatter::class,
            'driver'    => 'custom',
            'via'       => TelegramLogger::class,
            'level'     => 'debug',
            'bot'       => 'bot',
            'chat_id'   => env('TELEGRAM_LOG_CHAT_ID')
        ]

Idk if formatter line is necessary

@mafftor
Copy link
Author

mafftor commented Jun 27, 2023

This is just a hotfix for my version, please do not copy&paste.
Save backward compatibility

@punyflash
Copy link
Member

Hello, thanks a lot for your bug request. This seems to be changed in Monolog v3. Fixed in fa70e8c

@mafftor
Copy link
Author

mafftor commented Jun 29, 2023

You're welcome! Nice bot integration repo! I've used it in my diploma project in university:)
Slava Ukraine! 🇺🇦

@mafftor
Copy link
Author

mafftor commented Jun 29, 2023

Small notice about your change commit. You've written type hint for array and LogRecord object, but you do ->toArray() for object, but when array will be passed it would throw an error that it is not possible to call toArray method for array.
I'd write some method that would prepare data and you can check whether it is array or object and always return array for format method :)

@punyflash
Copy link
Member

Small notice about your change commit. You've written type hint for array and LogRecord object, but you do ->toArray() for object, but when array will be passed it would throw an error that it is not possible to call toArray method for array. I'd write some method that would prepare data and you can check whether it is array or object and always return array for format method :)

There is a check if passed record is an instance of LogRecord, so there will be no error

if (is_a($record, LogRecord::class)) {
    $record = array_merge($record->toArray(), ['formatted' => $record->formatted]);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants