[GH-ISSUE #1890] Truncated JsonFormatter logs at 8191 characters #809

Closed
opened 2026-03-04 02:18:13 +03:00 by kerem · 7 comments
Owner

Originally created by @Mad4T on GitHub (May 21, 2024).
Original GitHub issue: https://github.com/Seldaek/monolog/issues/1890

version
Monolog version: 3.0
Laravel: 10.0

Issue Description:
We're encountering log truncation at 8191 characters within our Laravel application deployed on AWS ECS. CloudWatch logs from this specific app are affected, while logs from other apps function normally.
We suspect a potential limitation within Monolog (version 3.0) might be causing this behavior.

Expected Behavior:
We expect CloudWatch logs from our Laravel app to be captured in their entirety without truncation.

Code Snippet (relevant part of logger.php):
'stderr' => [ 'driver' => 'monolog', 'handler' => StreamHandler::class, 'formatter' => env('LOG_STDERR_FORMATTER'), 'with' => [ 'stream' => 'php://stderr', ], ]

Originally created by @Mad4T on GitHub (May 21, 2024). Original GitHub issue: https://github.com/Seldaek/monolog/issues/1890 **version** Monolog version: 3.0 Laravel: 10.0 **Issue Description:** We're encountering log truncation at 8191 characters within our Laravel application deployed on AWS ECS. CloudWatch logs from this specific app are affected, while logs from other apps function normally. We suspect a potential limitation within Monolog (version 3.0) might be causing this behavior. **Expected Behavior:** We expect CloudWatch logs from our Laravel app to be captured in their entirety without truncation. **Code Snippet (relevant part of logger.php):** `'stderr' => [ 'driver' => 'monolog', 'handler' => StreamHandler::class, 'formatter' => env('LOG_STDERR_FORMATTER'), 'with' => [ 'stream' => 'php://stderr', ], ]`
kerem 2026-03-04 02:18:13 +03:00
  • closed this issue
  • added the
    Support
    label
Author
Owner

@Seldaek commented on GitHub (Jun 28, 2024):

AFAIK there is no such limit in Monolog itself, but I am not very familiar with ECS and there might be something else there.

<!-- gh-comment-id:2196498899 --> @Seldaek commented on GitHub (Jun 28, 2024): AFAIK there is no such limit in Monolog itself, but I am not very familiar with ECS and there might be something else there.
Author
Owner

@Mad4T commented on GitHub (Jun 30, 2024):

Issue happens in ECS and EKS. Also worth noting that logs from none php apps are not truncated.

<!-- gh-comment-id:2198457732 --> @Mad4T commented on GitHub (Jun 30, 2024): Issue happens in ECS and EKS. Also worth noting that logs from none php apps are not truncated.
Author
Owner

@Seldaek commented on GitHub (Jul 6, 2024):

Yeah sorry but that's something you'll have to debug yourself I am afraid.. There is too much environment specific stuff at play here for me to help much.

<!-- gh-comment-id:2211948689 --> @Seldaek commented on GitHub (Jul 6, 2024): Yeah sorry but that's something you'll have to debug yourself I am afraid.. There is too much environment specific stuff at play here for me to help much.
Author
Owner

@Seldaek commented on GitHub (Jul 11, 2024):

If you figure it out please share here, it may help someone else one day

<!-- gh-comment-id:2223936459 --> @Seldaek commented on GitHub (Jul 11, 2024): If you figure it out please share here, it may help someone else one day
Author
Owner

@Mad4T commented on GitHub (Jul 14, 2024):

if we ever find the reason will post it here, but we ended up doing a workaround to truncate the logs using Processor :

<?php

namespace App\Logging;

use Monolog\LogRecord;
use Monolog\Processor\ProcessorInterface;
use Throwable;

class TruncateStackTraceProcessor implements ProcessorInterface
{
    private int $traceLimit;

    public function __construct(int $traceLimit = 30)
    {
        $this->traceLimit = $traceLimit;
    }

    public function __invoke(LogRecord $record): LogRecord
    {
        $context = $record->context;
        if (isset($context['exception']) && $context['exception'] instanceof Throwable) {
            $exception = $record['context']['exception'];
            $trace = $exception->getTrace();

            if (count($trace) > $this->traceLimit) {
                $trace = array_slice($trace, 0, $this->traceLimit);
            }

            $context['exception'] = [
                'class' => get_class($record['context']['exception']),
                'message' => $record['context']['exception']->getMessage(),
                'code' => $record['context']['exception']->getCode(),
                'file' => $record['context']['exception']->getFile() . ':' . $record['context']['exception']->getLine(),
                'trace' => $this->formatStacktrace($trace),
            ];

            $record = $record->with(context: $context);
        }

        return $record;
    }

    private function formatStacktrace(array $trace): string {
        return collect($trace)
            ->map(function ($el) {
                $file = $el['file'] ?? '[unknown]';
                $line = $el['line'] ?? '[unknown]';
                $class = $el['class'] ?? '[unknown]';
                $function = $el['function'] ?? '[unknown]';
                $type = $el['type'] ?? '->';
                return "at {$class}{$type}{$function} ({$file}:{$line})";
            })
            ->join("\n");
    }
}
<!-- gh-comment-id:2227235899 --> @Mad4T commented on GitHub (Jul 14, 2024): if we ever find the reason will post it here, but we ended up doing a workaround to truncate the logs using Processor : ``` <?php namespace App\Logging; use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; use Throwable; class TruncateStackTraceProcessor implements ProcessorInterface { private int $traceLimit; public function __construct(int $traceLimit = 30) { $this->traceLimit = $traceLimit; } public function __invoke(LogRecord $record): LogRecord { $context = $record->context; if (isset($context['exception']) && $context['exception'] instanceof Throwable) { $exception = $record['context']['exception']; $trace = $exception->getTrace(); if (count($trace) > $this->traceLimit) { $trace = array_slice($trace, 0, $this->traceLimit); } $context['exception'] = [ 'class' => get_class($record['context']['exception']), 'message' => $record['context']['exception']->getMessage(), 'code' => $record['context']['exception']->getCode(), 'file' => $record['context']['exception']->getFile() . ':' . $record['context']['exception']->getLine(), 'trace' => $this->formatStacktrace($trace), ]; $record = $record->with(context: $context); } return $record; } private function formatStacktrace(array $trace): string { return collect($trace) ->map(function ($el) { $file = $el['file'] ?? '[unknown]'; $line = $el['line'] ?? '[unknown]'; $class = $el['class'] ?? '[unknown]'; $function = $el['function'] ?? '[unknown]'; $type = $el['type'] ?? '->'; return "at {$class}{$type}{$function} ({$file}:{$line})"; }) ->join("\n"); } } ```
Author
Owner

@sc0rp10 commented on GitHub (Apr 2, 2025):

@Mad4T please take a look to log_limit setting of php-fpm: it was the key to solving a similar problem in my case (I'm writing this mostly for folks from google).

@Seldaek It would be great if you added this information to the readme, very difficult to find the cause of this truncation.

<!-- gh-comment-id:2773695191 --> @sc0rp10 commented on GitHub (Apr 2, 2025): @Mad4T please take a look to [log_limit](https://www.php.net/manual/en/install.fpm.configuration.php#log-limit) setting of php-fpm: it was the key to solving a similar problem in my case (I'm writing this mostly for folks from google). @Seldaek It would be great if you added this information to the readme, very difficult to find the cause of this truncation.
Author
Owner

@Seldaek commented on GitHub (Apr 2, 2025):

Feel free to send a PR if you have a good understanding of the problem because I have zero context here so it'll take me much more effort and probably not get done..

<!-- gh-comment-id:2773722099 --> @Seldaek commented on GitHub (Apr 2, 2025): Feel free to send a PR if you have a good understanding of the problem because I have zero context here so it'll take me much more effort and probably not get done..
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#809
No description provided.