Laravel 5.3中的错误日志被截断了。

17

我在Laravel 5.3的日志中看到了下面这段信息:

  

[2016-12-22 17:23:37] local.ERROR: GuzzleHttp\Exception\ClientException:   客户端错误:POST https://api.sparkpost.com/api/v1/transmissions 的响应为 400 Bad Request:   {"errors":[{"message":"消息生成被拒绝","description":"由于客户 p 被压制,收件人地址被压制(截断...)

为什么重要的错误信息被截断了? 现在我无法确定出错的原因...

6个回答

22

由于您的请求引发了 Guzzle 异常,作为解决方法,您可以尝试以下操作而不是调用 $e->getMessage()

因为你的请求抛出Guzzle异常,作为解决办法,不要调用$e->getMessage(),改为尝试:

$e->getResponse()->getBody()->getContents();
如果您不想修改report()方法。 对我来说效果很好。

2
这个解决方案应该被接受为答案。简单明了。 - mp035
我接受这个答案,但并没有验证它是否有效...希望它有效。干杯! - Toskan
@Toskan 你应该在哪里做这个?你的问题是关于日志文件中的错误。如果你想修复它,你需要修改报告方法,就像我的答案所示(使用上面的代码获取消息内容),或者像你的答案一样热修复 Guzzle。 - patricus

14

截断是由Guzzle库完成的。它只显示响应的前120个字符。我假设这是因为响应可能非常长。

如果您想查看完整消息,您应该能够自定义如何处理guzzle异常。

app/Exceptions/Handler.php中更新report()方法,类似于:

public function report(Exception $exception)
{
    // this is from the parent method
    if ($this->shouldntReport($exception)) {
        return;
    }

    // this is from the parent method
    try {
        $logger = $this->container->make(\Psr\Log\LoggerInterface::class);
    } catch (Exception $ex) {
        throw $exception; // throw the original exception
    }

    // this is the new custom handling of guzzle exceptions
    if ($exception instanceof \GuzzleHttp\Exception\RequestException) {
        // get the full text of the exception (including stack trace),
        // and replace the original message (possibly truncated),
        // with the full text of the entire response body.
        $message = str_replace(
            rtrim($exception->getMessage()),
            (string) $exception->getResponse()->getBody(),
            (string) $exception
        );

        // log your new custom guzzle error message
        return $logger->error($message);
    }

    // make sure to still log non-guzzle exceptions
    $logger->error($exception);
}

注意:这是在report方法中完成的,因此它只会影响写入日志的内容。如果异常被转储到终端或浏览器中,仍然会显示缩短的消息。


我做了一些调整...问题是$message = (string) $e确实包含了堆栈跟踪。因此,substr($msg, 0, -135)将无法工作。现在要读取结果,必须在错误消息的最底部,实际上是在堆栈跟踪的底部阅读。 - Toskan
1
@Toskan 您是正确的,原始实现是不正确的(正如我所指出的,它没有经过测试)。我已经纠正了代码,并进行了实际测试,因此应该可以直接使用。我还更改了它,以便它将继续包括堆栈跟踪,而原始算法是设计为仅记录消息而不包括堆栈跟踪。 - patricus
如何在Laravel 4.1中处理相同的情况 - Parvez Alam
这对我不起作用。第二个if语句不成立,因此它不会运行。 - Martijn Hiemstra
@MartijnHiemstra 这是有意为之的。您只希望在处理\ GuzzleHttp \ Exception \ RequestException时运行额外的代码。 - patricus

12
作为替代方案:
热修复RequestException.php ta_integration/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php替换
$size = $body->getSize();
$summary = $body->read(120);
$body->rewind();

if ($size > 120) {

例如,带有:

    $size = $body->getSize();
    $summary = $body->read(999);
    $body->rewind();

    if ($size > 999) {

函数

getResponseBodySummary


2
这并不被推荐。如果你修改了供应商目录内的代码,那么在下一次执行 composer update 时,你的更改将会丢失。 - patricus
11
我完全知道这一点,而且它仅适用于说更新库时,并非每次运行"composer update"。但是它可以帮助程序员找出原始错误,解决问题并继续工作。 - Toskan
在当前版本中,此设置位于vendor/guzzlehttp/psr7/src/Message.php文件中的bodySummary方法的truncateAt参数中。 - Umair Ahmed

3

Edit vendor/guzzlehttp/psr7/src/Message.php

public static function bodySummary(MessageInterface $message, $truncateAt = 999)

编辑 vendor/guzzlehttp/psr7/src/functions.php

function get_message_body_summary(MessageInterface $message, $truncateAt = 999)

太棒了,这终于是一个修复了 :D - kevin ver
糟糕,非常糟糕的修复。你永远不要触碰供应商。 - Cranio

2

这里提供的解决方案都没有帮到我。我在这里找到了一个解决方案,由用户sidk2020提供。以下是他的解决方案,以防链接失效:

我做了一些非常冒险的事情。我修改了guzzel的异常处理程序。

guzzel特意只读取了120字节的信息并打印了截断的信息。

该文件位于:/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php

所以我修改了那个函数,下面是我的函数:

public static function getResponseBodySummary(ResponseInterface $response) { 
    $body = $response->getBody();

    if (!$body->isSeekable() || !$body->isReadable()) {
        return null;
    }

    $size = $body->getSize();

    if ($size === 0) {
        return null;
    }

    // Matches any printable character, including unicode characters:
    // letters, marks, numbers, punctuation, spacing, and separators.
    if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $body)) {
        return null;
    }

    return $body;

}

1
在 vendor/guzzlehttp/psr7/src/functions.php 文件中, 有一个函数:

function get_message_body_summary(MessageInterface $message, $truncateAt = 120)
{
    return Message::bodySummary($message, $truncateAt);
}

只需将 $truncateAt = 120 更改为您感到舒适的任何值即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接