techdeco / elastic-apm-agent
Elastic 应用性能监控服务器的代理
Requires
- php: ^7.2
- php-http/async-client-implementation: ^1.0
- php-http/discovery: ^1.4
- php-http/httplug: ^1.1
- php-http/message-factory: ^1.0
- php-http/message-factory-implementation: ^1.0
- psr/cache: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^1.0
- psr/log-implementation: ^1.0
- ramsey/uuid: ^3.7
Requires (Dev)
- behat/behat: ^3.4
- cache/array-adapter: ^1.0
- gamez/psr-testlogger: ^2.0
- infection/infection: ^0.10.0
- jangregor/phpstan-prophecy: ^0.2.0
- lcobucci/behat-di-builder-extension: ^0.1.1
- lcobucci/di-builder: ^5.3
- northwoods/broker: ^2.0
- php-http/guzzle6-adapter: ^1.1
- php-http/message: ^1.6
- phpstan/phpstan: ^0.10.3
- phpstan/phpstan-phpunit: ^0.10.0
- phpunit/phpunit: ^7.0
- squizlabs/php_codesniffer: ^3.0
- techdeco/coding-standard: ^1.0
README
Elastic stack 6.2 版本的发布迎来了 应用性能监控 的新纪元。与它一起发布了多种语言的 APM 代理,但 不知何故 PHP 并不在其中 ─_(ツ)_/¯ 此库添加了 APM 代理,这样我们就可以愉快地将应用程序性能指标发送到 Elastic APM 服务器。
注意:Alpha 版本
目前该库处于 alpha 阶段,这意味着接口可能还会发生变化,并且尚未准备好用于生产使用。如果您能尝试当前版本并 报告遇到的问题,我将不胜感激。
安装
使用 Composer 将库添加到您的应用程序中
composer require techdeco/elastic-apm-agent
但是,这仅在您已安装以下虚拟包的实现的情况下才能工作(有关每个包的更多信息如下)
这可能对您来说有些麻烦,也许甚至有些懒惰——为什么不让我们这个包自己选择呢?——但它为您提供了最大的灵活性和最小的冲突风险。
假设您的项目中没有这些实现,并且您分别选择了 Guzzle 6、PHP HTTP 的 Message 和 Monolog;您可以使用以下命令安装此库
composer require techdeco/elastic-apm-agent \ php-http/guzzle6-adapter \ php-http/message \ monolog/monolog
HTTP 客户端依赖
为了将数据发送到 APM 服务器,此库中的 APM 代理需要一个 HTTP 客户端。为了避免强制您选择特定的 HTTP 客户端,该库依赖于 php-http/async-client-implementation
的实现。您的项目需要提供该实现,您可以在 PHP-HTTP 站点 找到可能的候选者。
HTTP 消息工厂依赖
同样,对于不强制您选择特定的 HTTP 消息工厂,这会让您的项目提供 php-http/message-factory-implementation
的实现,您可以在 PHP-HTTP 站点 找到可能的候选者。
PSR 日志依赖
并且对于日志记录,此包需要一个实现,以便客户端在出现问题时通知您。您可以在 Packagist 上找到所有 psr/log-implemtation
的实现。如果您不知道选择哪一个,Monolog 是一个非常好的选择。
配置
为了告诉库如何连接到APM服务器,至少初始化一个LoggerInterface
的实现和一个ClientConfiguration
对象,并将其提供给HttplugAsyncClient
。HTTP客户端和消息工厂是可选的;如果没有注入,客户端将尝试自动发现它们。
$config = (new ClientConfiguration('http://foo.bar'))->authenticatedByToken('alloy'); $httpClient = ... # Implementation of php-http/async-client-implementation $requestFactory = ... # implementation of php-http/message-factory-implementation $logger = ... # implementation of psr/log-implementation $client = new HttplugAsyncClient($logger, $config, $httpClient, $requestFactory);
用法
Elastic成功地将它无缝集成到许多语言和框架中。这个库希望为PHP社区提供同样的服务。您可以选择使用库提供的构建块来构建DIY解决方案,或者使用更高层次的便利组件,如中间件。
DIY
Elastic的APM服务器可以处理两种类型的事件:事务和错误。一旦创建了客户端,就可以分别使用该客户端发送TechDeCo\ElasticApmAgent\Request\Transaction
或TechDeCo\ElasticApmAgent\Request\Error
到APM服务器。要创建这两种类型请求,请查看\TechDeCo\ElasticApmAgent\Message
命名空间中所有需要的组件。
请注意,所有请求和消息对象都是不可变的,所以对方法的所有调用都将返回一个带有变异属性的新实例。请确保使用新实例而不是您执行调用时的实例。
# Bad example $error = new Error(...); $error->onSystem(...); // New instance is in the wind $error->inProcess(...) // New instance is in the wind # Good example $error = new Error(...); $error = $error->onSystem(...)->inProcess(...); // Got it!
中间件
为了测量响应时间并报告错误(通过捕获异常),您可以将PSR-15兼容的中间件连接到您的应用程序。如果您想根据请求或响应丰富您发送到APM服务器的事务,实现OpenTransactionRequestEnricher
或OpenTransactionResponseEnricher
并将其连接到中间件。
事务
TransactionMiddleware
将一个OpenTransaction
注入到转发请求的apm-transaction
属性名下(但最好使用常量TransactionMiddleware::TRANSACTION_ATTRIBUTE
来引用它)。
您可以为OpenTransaction
添加Span
并标记事件,当您给出响应时,中间件将收集它们并将它们与事务一起发送到APM服务器。这是一个可变对象之一,因此您不需要在每次更改内容时替换请求属性。
错误
如果您想捕获并报告Throwable
到APM,也请在中间件堆栈中包含ErrorMiddleware
。它将捕获任何Throwable
并尽可能多地从中提取信息。为了给错误提供更多上下文,您可以在中间件实例化时注入Context
对象。它将使用该对象作为构建上下文的基础。
丰富
有时您希望使用请求或响应的数据丰富事务。为此,连接到OpenTransactionRequestEnrichmentMiddleware
和OpenTransactionResponseEnrichmentMiddleware
,并注入您的OpenTransactionRequestEnricher
和OpenTransactionResponseEnricher
实现以向OpenTransaction
添加信息。
此库中还包含了一些丰富器的实现。
RequestHeaderBlacklistEnricher
:在Context
中的Request
中添加头信息,除非这些头信息的名称在黑名单中。ResponseHeaderBlacklistEnricher
:在Context
中的Response
中添加头信息,除非这些头信息的名称在黑名单中。
组合
显然,这两个中间件可以组合使用。推荐的做法是首先连接TransactionMiddleware
,然后是ErrorMiddleware
,最后是OpenTransactionRequestEnrichmentMiddleware
和OpenTransactionRequestEnrichmentMiddleware
。这样,事务将被丰富,任何错误都将与事务相关联,事务的持续时间将尽可能真实。
缓存
要监控您的缓存调用,将您的缓存实现库包装在符合PSR-6的缓存层中。PSR-6。它将为每个调用创建一个span。
在调用任何CacheItemPoolInterface
的方法之前,确保您已注入一个OpenTransaction
,请参阅下面的开放事务部分。
HTTPlug客户端
要监控您对外部HTTP服务的调用,将您的HTTPlug客户端包装在HttpClientWrapper
中。它将为您发送的每个http请求创建一个span。
包装器将在将请求转发之前向请求添加一个X-Correlation-ID
头。该头将包含一个UUID,并为您提供了在整个基础设施中关联级联http请求的机会。库中的中间件将获取该头并将关联ID添加到事务上下文的标签中。如果头中找不到关联ID,将创建一个新的ID。
在调用任何HttpClientInterface
的方法之前,确保您已注入一个OpenTransaction
,请参阅下面的开放事务部分。
开放事务
这个库中的几个便利类在使用之前需要OpenTransaction
。所有这些类都将实现OpenTransactionEnricher
接口。这是一个有意的决定,使用setter而不是在构造函数中要求OpenTransaction
,仅仅是因为它当时不存在,它需要运行时信息来创建。
您可以从请求属性中获取OpenTransaction
,如果您使用这个库中的中间件,或者您可以创建自己的,稍后将其转换为可以通过Client
发送到APM服务器的Transaction
。