减少在 Sentry 中添加自定义检测的冗长

问题描述 投票:0回答:1

我正在使用 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');
}

这可能吗?

php laravel sentry
1个回答
0
投票

您可以编写一个 Service 类来处理和简化启动和停止 Sentry 事务和跨度的语法。

  1. 创建一个
    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());
        }
    }
}
  1. 创建一个
    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');
    }
}
  1. 要使辅助函数可见,您需要修改
    composer.json
    更具体地说是
    autoload
    键。在
    files
    内添加一个
    autoload
    数组。
"autoload": {
    "files": [
        "app/helpers.php"
    ],
    "classmap": [
        "database/seeds",
        "database/factories"
    ],
    "psr-4": {
        "App\\": "app/"
    }
},
  1. 添加文件后,您需要转储自动加载程序
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');
}
© www.soinside.com 2019 - 2024. All rights reserved.