PHP SDK 在从 IBM Cloud Functions 调用时不会向 Sentry 发送错误



我正在使用无服务器框架将我的PHP代码部署为IBM Cloud Function。

以下是操作 PHP 文件中的代码:

function main($args): array {
Sentryinit(['dsn' => 'SENTRY_DSN' ]);
try {
throw new Exception('Some error')
} catch (Throwable $exception) {
SentrycaptureException($exception);
}
}

这是 serverless.yml 文件:

service: cloudfunc
provider:
name: openwhisk
runtime: php
package:
individually: true
exclude:
- "**"
include:
- "vendor/**"
functions:
test-sentry:
handler: actions/test-sentry.main
annotations:
raw-http: true
events:
- http:
path: /test-sentry
method: post
resp: http
package:
include:
- actions/test-sentry.php
plugins:
- serverless-openwhisk

当我从本地环境(NGINX/PHP Docker容器)测试操作处理程序时,错误被发送到Sentry。

但是,当我尝试从 IBM Cloud 调用该操作时,哨兵控制台中没有任何内容。

编辑:

经过一段时间尝试调查问题的根源,我发现它与向Sentry发送http请求的异步性质有关(我还有其他库可以与Loggly,RabbitMQ,MySQL建立HTTP/TCP连接,它们都按预期工作):

vendor/sentry/sentry/src/Transport/HttpTransport.php

在发送实际 HTTP 请求的 Send 方法中:

public function send(Event $event): ?string
{
$request = $this->requestFactory->createRequest(
'POST',
sprintf('/api/%d/store/', $this->config->getProjectId()),
['Content-Type' => 'application/json'],
JSON::encode($event)
);
$promise = $this->httpClient->sendAsyncRequest($request);
//The promise state here is "pending"
//This line here is being logged in the stdout of the invoked action
var_dump($promise->getState());
// This function is defined in-line so it doesn't show up for type-hinting
$cleanupPromiseCallback = function ($responseOrException) use ($promise) {
//The promise state here is "fulfilled"
//This line here is never logged in the stdout of the invoked action
//Like the execution never happens here
var_dump($promise->getState());
$index = array_search($promise, $this->pendingRequests, true);
if (false !== $index) {
unset($this->pendingRequests[$index]);
}
return $responseOrException;
};
$promise->then($cleanupPromiseCallback, $cleanupPromiseCallback);
$this->pendingRequests[] = $promise;
return $event->getId();
}

异步注册的请求在HttpTransport实例的析构函数中发送,或者在 PHP 在注册关闭函数时关闭时发送。在 OpenWhisk 中,我们永远不会关闭,因为我们在一个永无止境的循环中运行,直到 Docker 容器被杀死。

更新:您现在可以调用$client-flush(),无需担心反射。

main()现在看起来像这样:

function main($args): array {
Sentryinit(['dsn' => 'SENTRY_DSN' ]);
try {
throw new Exception('Some error')
} catch (Throwable $exception) {
SentrycaptureException($exception);
}
$client = SentryStateHub::getCurrent()->getClient();
$client->flush();
return [
'body' => ['result' => 'ok']
];
}
<小时 />

原文说明:

因此,要使这项工作,我们需要调用Hub$client$transport属性的析构函数。不幸的是,这是私有的,所以最简单的方法是使用反射使其可见,然后调用它:

$client = SentryStateHub::getCurrent()->getClient();
$property = (new ReflectionObject($client))->getProperty('transport');
$property->setAccessible(true);
$transport = $property->getValue($client);
$transport->__destruct();

这将使$transport属性可见,以便我们可以检索它并调用其析构函数,析构函数又将调用cleanupPendingRequests(),然后将请求发送到 sentry.io。

因此,main()如下所示:

function main($args): array {
Sentryinit(['dsn' => 'SENTRY_DSN' ]);
try {
throw new Exception('Some error')
} catch (Throwable $exception) {
SentrycaptureException($exception);
}
$client = SentryStateHub::getCurrent()->getClient();
$property = (new ReflectionObject($client))->getProperty('transport');
$property->setAccessible(true);
$transport = $property->getValue($client);
$transport->__destruct();
return [
'body' => ['result' => 'ok']
];
} 

顺便说一句,我想知道这个哨兵SDK是否适用于Swoole?

函数运行时在平台的请求之间"暂停"。这意味着,如果在函数返回时未完成任何后台进程,它们将被阻止。

看起来异步 HTTP 请求在运行时暂停之前没有机会完成。

您需要找到某种方法来阻止从函数返回,直到该请求完成。如果 Sentry SDK 有一些回调处理程序或其他机制,可以在发送消息时收到通知,您可以使用它吗?

相关内容

  • 没有找到相关文章

最新更新