我正在使用 Sentry 进行仪器测试,但我对必须在各处添加多少行代码感到非常沮丧。
根据 Sentry 文档,每次我想要测量某些东西时,我都必须添加所有这些行:
$sentryTransactionContext = (new TransactionContext('Something that needs measuring'));
$sentryTransactionContext->setOp('http.server');
$sentryTransaction = startTransaction($sentryTransactionContext);
SentrySdk::getCurrentHub()->setSpan($sentryTransaction);
$spanContext = (new SpanContext());
$spanContext->setOp('something.that.needs.measuring');
$span1 = $sentryTransaction->startChild($spanContext);
\Sentry\SentrySdk::getCurrentHub()->setSpan($span1);
// Do something that needs to be measured...
$span1->finish();
SentrySdk::getCurrentHub()->setSpan($sentryTransaction);
$sentryTransaction->finish();
所有这些东西真的应该放在我所有不同的控制器方法中,或者我需要测量一段代码需要多长时间的地方吗?这会是很多重复的代码。
理想情况下,我只想这样做:
public function create(HttpRequest $request)
{
sentry_measure_start('slow.task');
// Something slow that needs to be measured
sentry_measure_stop('slow.task');
}
这可能吗?
您可以编写一个 Service 类来处理和简化启动和停止 Sentry 事务和跨度的语法。
app/Services/SentryMeasureService.php
namespace App\Services;
use Sentry\Tracing\TransactionContext;
use Sentry\Tracing\SpanContext;
use Sentry\SentrySdk;
class SentryMeasure {
private static $transactions = [];
private static $spans = [];
/**
* Start measuring a transaction or span
*
* @param string $name Unique identifier for the transaction or span
* @param string $type Type of measurement (transaction or span)
* @param string|null $parentName Parent transaction/span name (optional)
*/
public static function start(string $name, string $type = 'transaction', ?string $parentName = null)
{
try {
if ($type === 'transaction') {
// Create and start a new transaction
$transactionContext = new \Sentry\Tracing\TransactionContext($name);
$transactionContext->setOp('http.server');
$transaction = \Sentry\startTransaction($transactionContext);
\Sentry\SentrySdk::getCurrentHub()->setSpan($transaction);
self::$transactions[$name] = $transaction;
} elseif ($type === 'span') {
if (!isset(self::$transactions[$parentName])) {
throw new \Exception("Parent transaction '{$parentName}' not found");
}
$parentTransaction = self::$transactions[$parentName];
$spanContext = new \Sentry\Tracing\SpanContext();
$spanContext->setOp($name);
$span = $parentTransaction->startChild($spanContext);
\Sentry\SentrySdk::getCurrentHub()->setSpan($span);
self::$spans[$name] = $span;
} else {
throw new \InvalidArgumentException("Invalid measurement type. Use 'transaction' or 'span'.");
}
} catch (\Exception $e) {
error_log("Sentry measurement start error: " . $e->getMessage());
}
}
/**
* Stop measuring a transaction or span
*
* @param string $name Unique identifier for the transaction or span to stop
* @param string $type Type of measurement (transaction or span)
*/
public static function stop(string $name, string $type = 'transaction')
{
try {
if ($type === 'transaction') {
if (isset(self::$transactions[$name])) {
$transaction = self::$transactions[$name];
$transaction->finish();
unset(self::$transactions[$name]);
}
} elseif ($type === 'span') {
if (isset(self::$spans[$name])) {
$span = self::$spans[$name];
$span->finish();
unset(self::$spans[$name]);
if (!empty(self::$transactions)) {
$lastTransactionName = array_key_last(self::$transactions);
$lastTransaction = self::$transactions[$lastTransactionName];
\Sentry\SentrySdk::getCurrentHub()->setSpan($lastTransaction);
}
}
} else {
throw new \InvalidArgumentException("Invalid measurement type. Use 'transaction' or 'span'.");
}
} catch (\Exception $e) {
error_log("Sentry measurement stop error: " . $e->getMessage());
}
}
}
app/helpers.php
文件来实现您的辅助功能use App\Services\SentryMeasureService;
if (!function_exists('sentry_measure_start')) {
function sentry_measure_start(string $name, ?string $parentName = null)
{
SentryMeasureService::start($name, $parentName === null ? 'transaction' : 'span', $parentName);
}
}
if (!function_exists('sentry_measure_stop')) {
function sentry_measure_stop(string $name)
{
SentryMeasureService::stop($name, 'span');
SentryMeasureService::stop($name, 'transaction');
}
}
composer.json
更具体地说是 autoload
键。在 files
内添加一个 autoload
数组。"autoload": {
"files": [
"app/helpers.php"
],
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
composer dump-autoload
现在您应该能够按照您建议的方式使用这些功能了:
public function create(Request $request)
{
sentry_measure_start('slow.task');
sleep(2); // example of a slow operation
sentry_measure_stop('slow.task');
}