在 PHP 中实现结构化和一致的日志记录
在较小的团队中,日志记录结构可能各不相同,开发人员可以采用不同的方法。然而,随着团队规模的扩大,维护强大且一致的日志记录层变得至关重要。这不仅可以提高开发团队的效率,还可以确保其他部门能够轻松理解日志数据。
在记录客户端 IP 地址时,存在多种选择,例如:
src
: 10.42.42.42client
_ip: 10.42.42.42apache2.access.remote_ip
: 10.42.42.42context.user.ip
: 10.42.42.42src_ip
: 10.42.42.42 没有明确的正确或错误答案,但重要的是建立一种标准化和紧凑的方式来跨所有平台记录数据。
挑战与解决方案
尽管目标明确,但实现日志记录一致性仍然是一个挑战。关键在于制定一个记录结构并确保其在团队中得到广泛采用。
命名变量是编程中具有挑战性的方面,正如第一个编程笑话所幽默地指出的那样。这是一个耗时的过程,需要多种知识来设计跨不同架构领域的标准方法。
Elasticsearch Common Schema (ECS) 是 Elasticsearch 的推荐数据模型。它提供了一个标准化的结构,用于存储和检索 Elasticsearch 数据。
在 PHP 中,从头开始实现 ECS 需要付出努力。适用于 ECS 的可用 PHP SDK 仅涵盖有限的一组字段。
Types
BaseType.php
Error.php
Service.php
Tracing.php
User.php
tests
PECS(PHP Elastic Common Schema) 旨在解决这一问题。它是一个开源项目,旨在将完整的 ECS 支持带入 PHP 世界。
PECS 旨在满足以下标准:
简单易学:PECS 的 API 设计简单、直观,易于理解和使用。 易于使用:PECS 无需大量文档即可使用。开发人员可以快速开始使用 PECS 来编写 ECS 兼容的 PHP 代码。 很难滥用:PECS 使用类型提示和其他机制来防止滥用。这有助于确保开发人员使用 PECS 生成的代码是安全和可靠的。 功能强大:PECS 支持 ECS 的所有字段。这使开发人员能够使用 PECS 构建复杂的 ECS 数据模型。 易于扩展:PECS 设计用于易于扩展。开发人员可以创建自己的字段类和枚举,以满足特定的需要。 适合目标受众:PECS 针对使用 ECS 的 PHP 开发人员设计。它提供了一种简单、快速和安全的方式来生成 ECS 兼容的 PHP 代码。
PECS 符合这些标准。该包将 ECS 规范转换为 JSON 配置,并使用内置生成器创建 ECS PHP 类。这些类使用本机类型和定义的类型类和枚举进行完全类型提示,从而最大限度地减少误用的风险。该包易于扩展,允许实例化字段并以预期的 ECS 格式呈现它们。
PECS 提供了一个 EcsFieldsCollection
类,用于在集合中创建 ECS 字段。以下是使用 EcsFieldsCollection
的示例:
use PECS\EcsFieldsCollection;
// 创建一个 EcsFieldsCollection 对象
$collection = new EcsFieldsCollection([
new Log(
filePath: 'app/Http/Controllers/Controller.php',
level: 'info',
logger: 'name',
originFileLine: 42,
originFileName: 'Controller.php',
originFunction: 'index',
),
new Client(
ip: '10.42.42.42',
geo: new Geo(
cityName: 'Amsterdam',
continentCode: 'EU',
continentName: 'Europe',
countryIsoCode: 'NL',
countryName: 'Netherlands',
location: new GeoPoint(52.37403, 4.88969),
),
user: new User(
id: 'e125a612-899e-11ee-b9d1-0242ac120002',
name: 'hamid',
roles: (new ValueList())->push('admin')->push('user'),
)
),
new Os(
kernel: '4.19.0-6-amd64',
name: 'Arch',
platform: 'x86_64',
type: OsType::LINUX
),
]);
// 渲染集合
$output = $collection->render();
这是输出,说明了渲染指定字段的结果:
{
"log": {
"file": {
"path": "app/Http/Controllers/Controller.php"
},
"level": "info",
"logger": "name",
"origin": {
"file": {
"line": 42,
"name": "Controller.php"
},
"function": "index"
}
},
"client": {
"ip": "10.42.42.42",
"geo": {
"city_name": "Amsterdam",
"continent_code": "EU",
"continent_name": "Europe",
"country_iso_code": "NL",
"country_name": "Netherlands",
"location": {
"lat": 52.37403,
"lon": 4.88969
}
},
"user": {
"id": "e125a612-899e-11ee-b9d1-0242ac120002",
"name": "hamid",
"roles": [
"admin",
"user"
]
}
}
}
一体化
PECS 认识到纯 PHP 不再是常态,因此将其作为第三方包列入了 Monolog(最流行的 PHP 日志记录包)。这使得 PECS 可以与 Symfony 和 Laravel 等使用 Monolog 作为日志记录库的框架无缝集成。
以下是使用 PECS 和 Monolog 进行日志记录的示例:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use PECS\EcsFormatter;
use PECS\Event;
// 创建一个 Logger 对象
$log = new Logger('my_app');
// 创建一个 StreamHandler 对象
$handler = new StreamHandler('php://stdout');
// 将 EcsFormatter 设置为 handler 的格式化器
$handler->setFormatter(new EcsFormatter());
// 将 handler 添加到 Logger 对象
$log->pushHandler($handler);
// 记录一条日志
$log->info('message', [
new Event(action: 'test event'),
]);
这种集成允许与Symfony和Laravel无缝使用,两者都在底层使用 Monolog。
本文提供了 PECS 的概述,介绍了其主要功能和特性。PECS 提供了一个全面的解决方案,用于在 PHP 中实现 Elastic Common Schema (ECS)。ECS 是一种标准的 JSON 数据格式,用于存储和检索 Elasticsearch
数据。PECS 使用完全类型提示来确保数据的结构化和一致性,从而跨不同平台实现高效的数据分析。
发表评论