Инструментирование ремесленных команд Laravel с помощью OpenTelemetry

Я использую OpenTelemetry для оснащения приложения Laravel и пытаюсь создать корневые диапазоны для консольных команд (хотя Laravel Artisan). Я заметил, что структура отправляет события CommandStarting и CommandFinished при запуске и завершении команды, которую я пытаюсь прослушать, чтобы построить свой корневой диапазон:

<?php

namespace App\OpenTelemetry\Instrumentation;

use Illuminate\Console\Events\CommandFinished;
use Illuminate\Console\Events\CommandStarting;
use OpenTelemetry\API\Trace\Span;
use OpenTelemetry\API\Trace\SpanKind;
use OpenTelemetry\API\Trace\TracerInterface;
use OpenTelemetry\Context\Context;

class ArtisanInstrumentation implements Instrumentation
{
    public function register(): void
    {
        app('events')->listen(CommandStarting::class, [$this, 'recordStartOfCommand']);
        app('events')->listen(CommandFinished::class, [$this, 'recordEndOfCommand']);
    }

    public function recordStartOfCommand(CommandStarting $event): void
    {
        /** @var TracerInterface $tracer */
        $tracer = app(TracerInterface::class);

        $span = $tracer
            ->spanBuilder($event->command)
            ->setSpanKind(SpanKind::KIND_SERVER)
            ->startSpan();
        $span->activate();
    }

    public function recordEndOfCommand(CommandFinished $event): void
    {
        $scope = Context::storage()->scope();
        $span = Span::fromContext($scope->context());
        $scope->detach();
        $span->end();
    }
}

Как вы можете видеть, я пытаюсь запустить интервал, когда команда начинает выполняться, и завершить его позже, когда команда завершится. Однако из приведенного выше кода я получаю следующую ошибку об отсутствующем вызове для отсоединения области:

  Scope: missing call to Scope::detach() for scope #3776, created 
        at OpenTelemetry.Context.Context.activate(Context.php:87)
        at OpenTelemetry.API.Trace.Span.activate(Span.php:51)
        at App.OpenTelemetry.Instrumentation.ArtisanInstrumentation.recordStartOfCommand(ArtisanInstrumentation.php:32)

Промежуток, который я получаю с помощью Span::fromContext($scope->context()), является правильным, что я подтвердил, выгрузив его и проверив его имя. Но вызов detach() на области явно не отсоединяет ее должным образом.

Я думаю, что я просто немного потерялся в генерировании того, как вообще работают области видимости и как получить область видимости диапазона где-то еще в кодовой базе. Все примеры в документации OpenTelemetry показывают использование области в контексте, в котором вы ее создали, а не динамическое получение ее из несвязанного кода.

Методом проб и ошибок я заставил это работать, сохранив результат $span->activate() в свойстве класса, а затем деактивировав его в методе recordEndOfCommand следующим образом:

$scope = Context::storage()->scope();
$span = Span::fromContext($scope->context());
$this->scope->detach();
$span->end();

но я не уверен, предпочтительнее ли это извлечения области из контекста?

Вы пробовали использовать автоинтрументацию? Команды перехвата должны быть описаны здесь: github.com/open-telemetry/opentelemetry-php-contrib/blob/mai‌​n/…

Bob Strecansky 11.06.2024 14:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
1
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы сталкиваетесь с предупреждением от DebugScope, функции OpenTelemetry, которая активна в PHP с поддержкой утверждений, которая существует, чтобы помочь вам определить, когда Scope не отсоединен должным образом (чего нет в recordStartOfCommand - он сразу выходит за рамки когда эта функция завершается, получает GC и вызывает ошибку, которую вы видите). Вы можете отключить эту функцию с помощью переменной среды OTEL_PHP_DEBUG_SCOPES_DISABLED=true или отключив утверждения PHP.

Если вы не хотите отслеживать область действия между функциями pre и post, вы можете управлять этим следующим образом:

public function recordStartOfCommand(CommandStarting $event): void
{
    $tracer = app(TracerInterface::class);
    $span = $tracer
        ->spanBuilder($event->command)
        ->setSpanKind(SpanKind::KIND_SERVER)
        ->startSpan();
    // do not `activate()` the span, but instead:
    Context::storage()->attach($span->storeInContext(Context::getCurrent()));
}

public function recordEndOfCommand(CommandFinished $event): void
{
    $scope = Context::storage()->scope();
    $scope->detach();
    Span::fromContext($scope->context())->end();
}

Спасибо, это работает хорошо, и я думаю, что начинаю понимать, как работает контекст, изучая вызовы методов, которые вы здесь даете.

Chris White 16.06.2024 04:32

Другие вопросы по теме