公共 API编辑

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

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 代理监控服务时捕获的事件。事务有助于将多个 跨度 组合成逻辑组,它们是服务中的第一个 跨度。有关事务和跨度的更多信息,请参阅 APM 数据模型 文档。

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

TransactionInterface->getCurrentSpan编辑

返回此事务的当前跨度。

示例

$span = $transaction->getCurrentSpan();

TransactionInterface->beginCurrentSpan编辑

使用当前跨度作为新跨度的父跨度启动一个新跨度,并将新跨度设置为此事务的当前跨度。如果此事务没有当前跨度,则事务本身将被设置为新跨度的父跨度。

当跨度结束时,您必须调用 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,它确保 SpanInterface->end 在跨度结束时被调用。此 API

  • 使用此事务的当前跨度作为新跨度的父跨度启动一个新跨度,并将新跨度设置为此事务的当前跨度。如果此事务没有当前跨度,则事务本身将被设置为新跨度的父跨度。
  • 以新跨度形式执行提供的 callable
  • 结束新事务
  • 返回提供的 callable 返回的值

例如

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

TransactionInterface->beginChildSpan编辑

使用此事务作为新跨度的父跨度启动一个新跨度。

当跨度结束时,您必须调用 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,它确保 SpanInterface->end 在跨度结束时被调用。此 API

  • 使用此事务作为新跨度的父跨度启动一个新跨度
  • 以新跨度形式执行提供的 callable,并
  • 结束新跨度
  • 返回提供的 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 在属于同一逻辑跟踪的所有事务和跨度中保持一致,即使对于发生在另一个服务中的事务和跨度也是如此(假设该服务也由 Elastic APM 监控)。

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

示例

$traceId = $transaction->getTraceId();

TransactionInterface->getParentId编辑

获取父事务或跨度的 ID。

请参阅 TransactionInterface->getIdSpanInterface->getId

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

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

示例

$parentId = $transaction->getParentId();

TransactionInterface->ensureParentId()编辑

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

这使得能够将 JavaScript 真实用户监控 (RUM) 代理为初始页面加载创建的跨度与后端服务的交易相关联。如果您的后端服务动态生成 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 2xx 的 HTTP 状态码。

示例

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

TransactionInterface->end编辑

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

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

示例

$transaction->end();

SpanInterface编辑

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

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

有关如何获取当前跨度的信息,请参阅 TransactionInterface->getCurrentSpan

SpanInterface->setName编辑

设置跨度的名称。跨度名称是跨度在事务范围内的通用名称。

示例

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

SpanInterface->setType编辑

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

示例

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

SpanInterface->setSubtype编辑

设置跨度的子类型。跨度子类型是对类型的进一步细分。例如,对于类型 dbmysqlpostgresqlelasticsearch,对于类型 externalhttp 等。

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

示例

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

SpanInterface->setAction编辑

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

跨度操作是可选的,可以设置为 null。跨度操作默认值为 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编辑

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

如果此跨度表示一个空操作,则此方法将返回一个未指定的虚拟 ID。

示例

$spanId = $span->getId();

SpanInterface->getTraceId编辑

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

跟踪 ID 在属于同一逻辑跟踪的所有事务和跨度中保持一致,即使对于发生在另一个服务中的事务和跨度也是如此(假设该服务也由 Elastic APM 监控)。

如果此跨度表示一个空操作,则此方法将返回一个未指定的虚拟 ID。

示例

$traceId = $span->getTraceId();

SpanInterface->getTransactionId编辑

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

如果此跨度表示一个空操作,则此方法将返回一个未指定的虚拟 ID。

示例

$transactionId = $span->getTransactionId();

SpanInterface->getParentId编辑

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

如果此跨度表示一个空操作,则此方法将返回一个未指定的虚拟 ID。

示例

$parentId = $span->getParentId();

SpanInterface->beginChildSpan编辑

使用此跨度作为新跨度的父级开始一个新的跨度。

当跨度结束时,您必须调用 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,它确保 SpanInterface->end 在跨度结束时被调用。此 API

  • 使用此跨度作为新跨度的父级开始一个新的跨度。
  • 以新跨度形式执行提供的 callable
  • 结束新跨度
  • 返回提供的 callable 返回的值

例如

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

SpanInterface->end编辑

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

对已结束的跨度实例调用任何修改方法(例如,任何 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();