公共 API

编辑

Elastic APM PHP 代理的公共 API 允许您自定义和手动创建 Span 和事务。

ElasticApm

编辑

这是公共 API 的入口点。它允许启动事务,让您访问当前事务等。

要使用 API,您需要在类 \Elastic\Apm\ElasticApm 上调用静态方法。

ElasticApm::beginCurrentTransaction

编辑

开始一个新的事务并将其设置为当前事务。使用此方法创建自定义事务。请注意,当使用自动检测时,代理会在您的应用程序收到传入的 HTTP 请求时自动开始新的事务,因此您只需要使用此方法来创建自定义事务。

当事务结束时,您必须调用 TransactionInterface->end

最佳实践是使用 try-finally 代码块。例如

use Elastic\Apm\ElasticApm;

$transaction = ElasticApm::beginCurrentTransaction(
    'transaction_name',
    'transaction_type'
);
try {
    // do your thing ...
} finally {
    $transaction->end();
}

有关如何自定义事务的信息,请参阅 TransactionInterface

ElasticApm::captureCurrentTransaction

编辑

这是一个便利的 API,可确保在事务结束时调用 TransactionInterface->end。此 API

  • 开始一个新的事务
  • 将新事务设置为当前事务
  • 将提供的 callable 作为新事务执行
  • 结束新事务
  • 返回提供的 callable 返回的值

例如

use Elastic\Apm\ElasticApm;
use Elastic\Apm\TransactionInterface;

ElasticApm::captureCurrentTransaction(
    'transaction_name',
    'transaction_type',
    function (TransactionInterface $transaction) {
        // do your thing...
    }
);

有关如何自定义事务的信息,请参阅 TransactionInterface

ElasticApm::getCurrentTransaction

编辑

返回当前事务。

use Elastic\Apm\ElasticApm;

$transaction = ElasticApm::getCurrentTransaction();

有关如何自定义事务的信息,请参阅 TransactionInterface

TransactionInterface

编辑

事务描述了由 Elastic APM 代理监控服务捕获的事件。事务有助于将多个 Span 合并为逻辑组,它们是服务的第一个 Span。有关事务和 Span 的更多信息,请参阅 APM 数据模型文档。

有关如何获取当前事务的引用,请参阅 ElasticApm::getCurrentTransaction

TransactionInterface->getCurrentSpan

编辑

返回此事务的当前 Span。

示例

$span = $transaction->getCurrentSpan();

TransactionInterface->beginCurrentSpan

编辑

开始一个新的 Span,并将当前 Span 作为新 Span 的父级,并将新 Span 设置为此事务的当前 Span。如果此事务没有当前 Span,则将事务本身设置为新 Span 的父级。

当 Span 结束时,您必须调用 SpanInterface->end

最佳实践是使用 try-finally 代码块。例如

$span = $transaction->beginCurrentSpan(
    'span_name',
    'span_type',
    'span_sub-type', // optional
    'span_action' // optional
);
try {
    // do your thing ...
} finally {
    $span->end();
}

TransactionInterface->captureCurrentSpan

编辑

这是一个便利的 API,可确保在 Span 结束时调用 SpanInterface->end。此 API

  • 开始一个新的 Span,并将此事务的当前 Span 作为新 Span 的父级,并将新 Span 设置为此事务的当前 Span。如果此事务没有当前 Span,则将事务本身设置为新 Span 的父级。
  • 将提供的 callable 作为新 Span 执行
  • 结束新事务
  • 返回提供的 callable 返回的值

例如

$parentSpan->captureCurrentSpan(
    'span_name',
    'span_type',
    function (SpanInterface $childSpan) {
        // do your thing...
    },
    'span_sub-type', // optional
    'span_action' // optional
);

TransactionInterface->beginChildSpan

编辑

开始一个新的 Span,并将此事务作为新 Span 的父级。

当 Span 结束时,您必须调用 SpanInterface->end

最佳实践是使用 try-finally 代码块。例如

$span = $transaction->beginChildSpan(
    'span_name',
    'span_type',
    'span_sub-type', // optional
    'span_action' // optional
);
try {
    // do your thing ...
} finally {
    $span->end();
}

TransactionInterface->captureChildSpan

编辑

这是一个便利的 API,可确保在 Span 结束时调用 SpanInterface->end。此 API

  • 开始一个新的 Span,并将此事务作为新 Span 的父级
  • 将提供的 callable 作为新 Span 执行,并且
  • 结束新 Span
  • 返回提供的 callable 返回的值

例如

$transaction->captureChildSpan(
    'span_name',
    'span_type',
    function (SpanInterface $span) {
        // do your thing...
    },
    'span_sub-type', // optional
    'span_action' // optional
);

TransactionInterface->setName

编辑

设置事务的名称。事务名称是单个服务范围内事务的通用名称(例如,GET /users/:id)。

示例

$transaction->setName('GET /users/:id');

TransactionInterface->setType

编辑

设置事务的类型。事务类型是服务域中具有特定相关性的关键字。例如,requestbackgroundjob 等。

示例

$transaction->setType('my custom transaction type');

TransactionInterface->context()->setLabel

编辑

按键设置标签。标签是用户定义的字符串键和字符串、数字或布尔值的扁平映射。

标签在 Elasticsearch 中建立索引,以便它们可搜索和可聚合。使用用户提供的数据(如 URL 参数)作为标签键时要特别注意,因为它可能导致 Elasticsearch 映射爆炸

示例

$transaction->context()->setLabel('my label with string value', 'some text');
$transaction->context()->setLabel('my label with int value', 123);
$transaction->context()->setLabel('my label with float value', 4.56);

TransactionInterface->getId

编辑

获取事务的 ID。事务 ID 是一个十六进制编码的 64 个随机位(== 8 个字节 == 16 个十六进制数字)ID。

如果此事务表示无操作,则此方法会返回一个未指定的虚拟 ID。

示例

$transactionId = $transaction->getId();

TransactionInterface->getTraceId

编辑

获取事务的跟踪 ID。跟踪 ID 是关联跟踪的十六进制编码的 128 个随机位(== 16 个字节 == 32 个十六进制数字)ID。

跟踪 ID 在属于同一逻辑跟踪的所有事务和 Span 中都是一致的,即使是发生在另一个服务中的事务和 Span(前提是该服务也受到 Elastic APM 的监控)。

如果此事务表示无操作,则此方法会返回一个未指定的虚拟 ID。

示例

$traceId = $transaction->getTraceId();

TransactionInterface->getParentId

编辑

获取父事务或 Span 的 ID。

请参阅 TransactionInterface->getIdSpanInterface->getId

跟踪的根事务没有父级,因此返回 null

如果此事务表示无操作,则此方法会返回一个未指定的虚拟 ID。

示例

$parentId = $transaction->getParentId();

TransactionInterface->ensureParentId()

编辑

如果事务还没有父 ID,则调用此方法会生成一个新的 ID,将其设置为此事务的父 ID,并将其作为 string 返回。

这使 JavaScript 真实用户监控 (RUM) 代理为初始页面加载创建的 Span 与后端服务的事务相关联。如果您的后端服务动态生成 HTML 页面,则使用此方法的值初始化 JavaScript RUM 代理可以分析在浏览器中花费的时间与在后端服务中花费的时间。

在 Laravel 应用程序中使用此 API 的示例可以在 https://github.com/elastic/opbeans-php/ 中找到。

isElasticApmEnabledelasticApmCurrentTransaction 属性添加到视图 (请参阅 opbeans-php 的 AppServiceProvider.php 中的相关部分),并在 HTML 页面的正文中添加类似于以下代码片段的代码,最好在其他 JS 库之前 (请参阅 opbeans-php 的 rendered_by_frontend.blade.php)

@if ($isElasticApmEnabled)
    <script>
        window.rumConfig = {
            serviceName: "{{ $elasticApmJsServiceName }}",
            serviceVersion: "{{ $elasticApmJsServiceVersion }}",
            serverUrl: "{{ $elasticApmJsServerUrl }}",
            pageLoadTraceId: "{{ $elasticApmCurrentTransaction->getTraceId() }}",
            pageLoadSpanId: "{{ $elasticApmCurrentTransaction->ensureParentId() }}",
            pageLoadSampled: {{ $elasticApmCurrentTransaction->isSampled() ? "true" : "false" }}
        }
    </script>
@endif

有关更多信息,请参阅 JavaScript RUM 代理文档

TransactionInterface->setResult

编辑

设置事务的结果。

事务结果是可选的,可以设置为 null。对于与 HTTP 相关的事务,结果是 HTTP 状态代码,格式为 HTTP 2xx

示例

$transaction->setResult('my custom transaction result');

TransactionInterface->end

编辑

结束事务并将其排队以报告给 APM 服务器。

在已结束的事务实例上调用任何更改方法(例如,任何 set... 方法都是更改方法)都是非法的。

示例

$transaction->end();

SpanInterface

编辑

Span 包含有关特定代码路径的信息,该代码路径作为事务的一部分执行。

例如,如果在记录的事务中发生数据库查询,则可以创建表示此数据库查询的 Span。在这种情况下,Span 的名称将包含有关查询本身的信息,类型将包含有关数据库类型的信息。

有关如何获取当前 Span,请参阅 TransactionInterface->getCurrentSpan

SpanInterface->setName

编辑

设置 Span 的名称。Span 名称是事务范围内 Span 的通用名称。

示例

$span->setName('SELECT FROM customer');

SpanInterface->setType

编辑

设置 Span 的类型。Span 类型是服务域中具有特定相关性的关键字。例如,dbexternal 等。

示例

$span->setType('my custom span type');

SpanInterface->setSubtype

编辑

设置 Span 的子类型。Span 子类型是类型的进一步细分。例如,mysqlpostgresqlelasticsearch 用于类型 dbhttp 用于类型 external 等。

Span 子类型是可选的,可以设置为 null。Span 子类型的默认值为 null

示例

$span->setSubtype('my custom span sub-type');

SpanInterface->setAction

编辑

设置 Span 的操作。Span 操作是 Span 表示的子类型中特定类型的事件。例如,对于类型/子类型 db/mysqlquery,对于类型/子类型 db/cassandraconnect 等。

Span 操作是可选的,可以设置为 null。Span 操作的默认值为 null

示例

$span->setAction('my custom span action');

SpanInterface->context()->setLabel

编辑

按键设置标签。标签是用户定义的字符串键和字符串、数字或布尔值的扁平映射。

标签在 Elasticsearch 中建立索引,以便它们可搜索和可聚合。使用用户提供的数据(如 URL 参数)作为标签键时要特别注意,因为它可能导致 Elasticsearch 映射爆炸

示例

$span->context()->setLabel('my label with string value', 'some text');
$span->context()->setLabel('my label with int value', 123);
$span->context()->setLabel('my label with float value', 4.56);

SpanInterface->getId

编辑

获取 Span 的 ID。Span ID 是一个十六进制编码的 64 位随机数(== 8 字节 == 16 个十六进制数字)ID。

如果此 Span 代表一个空操作,则此方法返回一个未指定的虚拟 ID。

示例

$spanId = $span->getId();

SpanInterface->getTraceId

编辑

获取 Span 的 Trace ID。Trace ID 是一个十六进制编码的 128 位随机数(== 16 字节 == 32 个十六进制数字),用于关联的跟踪。

跟踪 ID 在属于同一逻辑跟踪的所有事务和 Span 中都是一致的,即使是发生在另一个服务中的事务和 Span(前提是该服务也受到 Elastic APM 的监控)。

如果此 Span 代表一个空操作,则此方法返回一个未指定的虚拟 ID。

示例

$traceId = $span->getTraceId();

SpanInterface->getTransactionId

编辑

获取关联事务的 ID。请参阅 TransactionInterface->getId

如果此 Span 代表一个空操作,则此方法返回一个未指定的虚拟 ID。

示例

$transactionId = $span->getTransactionId();

SpanInterface->getParentId

编辑

获取父事务或 Span 的 ID。如果此 Span 是关联事务的根 Span,则其父级是关联事务;否则,其父级是父 Span。请参阅 TransactionInterface->getIdSpanInterface->getId

如果此 Span 代表一个空操作,则此方法返回一个未指定的虚拟 ID。

示例

$parentId = $span->getParentId();

SpanInterface->beginChildSpan

编辑

开始一个新的 Span,并将此 Span 作为新 Span 的父级。

当 Span 结束时,您必须调用 SpanInterface->end

最佳实践是使用 try-finally 代码块。例如

$childSpan = $parentSpan->beginChildSpan(
    'span_name',
    'span_type',
    'span_sub-type', // optional
    'span_action' // optional
);
try {
    // do your thing ...
} finally {
    $childSpan->end();
}

SpanInterface->captureChildSpan

编辑

这是一个便利的 API,可确保在 Span 结束时调用 SpanInterface->end。此 API

  • 开始一个新的 Span,并将此 Span 作为新 Span 的父级
  • 将提供的 callable 作为新 Span 执行
  • 结束新 Span
  • 返回提供的 callable 返回的值

例如

$parentSpan->captureChildSpan(
    'span_name',
    'span_type',
    function (SpanInterface $childSpan) {
        // do your thing...
    },
    'span_sub-type', // optional
    'span_action' // optional
);

SpanInterface->end

编辑

结束 Span 并将其加入队列,以便报告给 APM Server。

在已结束的 Span 实例上调用任何修改方法(例如,任何 set... 方法都是修改方法)都是非法的。

示例

$span->end();

手动分布式追踪

编辑

Elastic APM PHP 代理自动为支持的技术传播分布式追踪上下文。如果您的服务通过不同的、不受支持的协议进行通信,您可以使用代理的 API 手动将分布式追踪上下文从发送服务传播到接收服务。

分布式追踪数据由多个键值对组成。例如,对于 HTTP 协议,这些键值对作为请求头传递。

在发送服务中,您必须将键值对添加到传出请求中。使用 injectDistributedTracingHeaders() API 从相应的 SpanInterfaceTransactionInterface 实例中获取分布式追踪数据

例如,假设传出请求与 $span 相关联

$span->injectDistributedTracingHeaders(
    function (string $headerName, string $headerValue) use ($myRequest): void {
        $myRequest->addHeader($headerName, $headerValue);
    }
);

在接收服务中,您必须将来自发送端的键值对传递给 ElasticApm::newTransaction API。

示例

$myTransaction = ElasticApm::newTransaction('my TX name', 'my TX type')
    ->distributedTracingHeaderExtractor(
        function (string $headerName) use ($myRequest): ?string {
            return $myRequest->hasHeader($headerName)
                ? $myRequest->getHeader($headerName)
                : null;
        }
    )->begin();