vla*_*run 1 php sentry serverless-framework openwhisk ibm-cloud
我正在使用无服务器框架将 PHP 代码部署为 IBM Cloud Function。
以下是操作 PHP 文件中的代码:
function main($args): array {
Sentry\init(['dsn' => 'SENTRY_DSN' ]);
try {
throw new \Exception('Some error')
} catch (\Throwable $exception) {
Sentry\captureException($exception);
}
}
Run Code Online (Sandbox Code Playgroud)
这是 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
Run Code Online (Sandbox Code Playgroud)
当我从本地环境(NGINX/PHP Docker 容器)测试操作处理程序时,错误将被发送到 Sentry。
但是,当我尝试从 IBM Cloud 调用该操作时,Sentry 控制台中没有显示任何内容。
编辑:
经过一段时间尝试调查问题的根源后,我发现它与向 Sentry 发送 http 请求的异步性质有关(我有其他库可以与 Loggly、RabbitMQ、MySQL 建立 HTTP/TCP 连接,它们都按预期工作):
vendor/sentry/sentry/src/Transport/HttpTransport.php
Run Code Online (Sandbox Code Playgroud)
在发送实际 http 请求的 send 方法中:
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
Run Code Online (Sandbox Code Playgroud)
异步注册的请求在HttpTransport
实例的析构函数中发送,或者当 PHP 因注册关闭函数而关闭时发送。在 OpenWhisk 中,我们永远不会关闭,因为我们在永无休止的循环中运行,直到 Docker 容器被终止。
更新:您现在可以调用$client-flush()
,无需担心反射。
main()
现在看起来像这样:
function main($args): array {
Sentry\init(['dsn' => 'SENTRY_DSN' ]);
try {
throw new \Exception('Some error')
} catch (\Throwable $exception) {
Sentry\captureException($exception);
}
$client = Sentry\State\Hub::getCurrent()->getClient();
$client->flush();
return [
'body' => ['result' => 'ok']
];
}
Run Code Online (Sandbox Code Playgroud)
原文解释:
因此,为了使其工作,我们需要调用s$transport
属性的析构函数。不幸的是,这是私有的,因此最简单的方法是使用反射使其可见,然后调用它:Hub
$client
function main($args): array {
Sentry\init(['dsn' => 'SENTRY_DSN' ]);
try {
throw new \Exception('Some error')
} catch (\Throwable $exception) {
Sentry\captureException($exception);
}
$client = Sentry\State\Hub::getCurrent()->getClient();
$client->flush();
return [
'body' => ['result' => 'ok']
];
}
Run Code Online (Sandbox Code Playgroud)
这将使该$transport
属性可见,以便我们可以检索它并调用其析构函数,该析构函数将依次调用cleanupPendingRequests()
该析构函数,然后将请求发送到sentry.io。
因此main()
看起来像这样:
$client = Sentry\State\Hub::getCurrent()->getClient();
$property = (new ReflectionObject($client))->getProperty('transport');
$property->setAccessible(true);
$transport = $property->getValue($client);
$transport->__destruct();
Run Code Online (Sandbox Code Playgroud)
顺便问一下,这个Sentry SDK可以和Swoole一起使用吗?