不加载PHP OpenTelemetry SDK实现Trace‌与Logs

news2025/6/6 14:21:09

目录

  • 前言
  • 一、回到OpenTelemetry原理看问题
    • 1、数据接收(Receivers)
    • 2、数据处理(Processors)
    • 3、数据导出(Exporters)
  • 二、不加载OpenTelemetry SDK实现Trace‌与Logs示例

前言

前面两篇我们分别介绍了OpenTelemetry原理以及借助PHP OpenTelemetry SDK实现的分布式链路追踪Trace‌和日志Logs,按理说我们已经可以起飞了✈️。

基于OpenTelemetry的分布式链路追踪Trace‌实现(PHP篇)
基于OpenTelemetry的日志Logs实现(PHP篇)

但是实际情况可能各有不同,我们知道sdk对php版本的要求至少是v7.4+,0代码自动插桩的话甚至需要v8,有些PHP项目使用的PHP版本相对老旧,而且由于历史的原因升级是一件很麻烦的事。那怎么办呢?不能升级PHP版本就无法使用SDK且无法实现自己项目的OpenTelemetry 布式链路追踪Trace‌和日志Logs?答案当然是:❌。

在这里插入图片描述

一、回到OpenTelemetry原理看问题

我们之前说到,OpenTelemetry 其实就是个协议规范,原理可以回头参看《基于OpenTelemetry的分布式链路追踪Trace‌实现(PHP篇)》第三章OpenTelemetry的架构原理,也就是说如果遵循规范其实上报就不是问题。

可观测链路 OpenTelemetry 版支持接收应用的链路追踪、指标和日志数据,提供直接上报通过 OpenTelemetry Collector 转发两种上报方式。
在这里插入图片描述
Application: 一般的应用程序,同时使用了 OpenTelemetry 的 Library (实现了 API 的 SDK)。

OTel Libraty:也称为 SDK,负责在客户端程序里采集观测数据,包括 metrics,traces,logs,对观测数据进行处理,之后观测数据按照 exporter 的不同方式,通过 OTLP 方式发送到 Collector 或者直接发送到 Backend 中。

OTel Collector:负责根据 OpenTelemetry 的协议收集数据的组件,以及将观测数据导出到外部系统。这里的协议指的是 OTLP (OpenTelemetry Protocol)。不同的提供商要想能让观测数据持久化到自己的产品里,需要按照 OpenTelemetry 的标准 exporter 的协议接受数据和存储数据。同时社区已经提供了常见开源软件的输出能力,如 Prometheus,Jaeger,Kafka,zipkin 等。

Backend: 负责持久化观测数据Collector 本身不会去负责持久化观测数据,需要外部系统提供,在 Collector 的 exporter 部分,需要将 OTLP 的数据格式转换成 Backend 能识别的数据格式。目前社区的已经集成的厂商非常多,除了上述的开源的,常见的厂商包括 AWS,阿里,Azure,Datadog,Dynatrace,Google,Splunk,VMWare 等都实现了 Collector 的 exporter 能力。

在这里插入图片描述
otle collector是一种供应商无关的接收、处理和导出遥测数据的方式。如果不是直接发送到后端存储而是通过otel-collector处理转发,则我们需要将otel-collector部署运行起来。

为什么不直接将数据发送到可观测性后端?而是通过otel-collector处理转发?
对于大多数开发语言都有现成的sdk库可以使用,并将可观测数据导出到可观测性后端,例如jaeger,prometheus,对于小规模集群来说,这是一种快速获得价值体现的方式,但是也不利于统一管理。
所以一般来说,我们建议使用otel-collector,因为它允许快速卸载数据,并且otel-collector可以进行很多操作,例如重试、批处理、加密甚至敏感数据过滤。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

OpenTelemetry Collector 对追踪数据的处理流程遵循模块化管道设计,主要分为以下四个阶段,并由配置文件中定义的组件顺序决定执行逻辑:

1、数据接收(Receivers)

多协议适配‌
Collector 通过 OTLP 接收器(Receiver)支持 HTTP 和 gRPC 两种传输协议,自动解析请求头中的 Content-Type(如 application/x-protobuf 或application/json) 完成数据解码。例如,HTTP 接收器监听特定端口(如 4318)接收 OTLP/HTTP 格式的追踪数据。

上下文重建‌
接收器解析请求体中的二进制 Protobuf 数据后,将其转换为包含 TraceID、SpanID、操作名称等上下文信息的标准化内部数据结构

2、数据处理(Processors)

数据经过接收器后进入处理管道,典型的处理步骤包括:

批处理优化‌
将多个 Span 合并为批次,减少对后端存储系统的写入压力。
数据过滤‌
根据配置规则丢弃低价值 Span(如健康检查请求)或敏感字段脱敏。
元数据增强‌
添加环境变量信息(如 Kubernetes 节点标签)或统一添加自定义业务标签。
错误重试‌
在网络波动导致导出失败时,通过内存队列暂存数据并重试发送。

3、数据导出(Exporters)

处理后的数据根据配置通过不同导出器发送到目标系统:

后端存储适配‌
支持 Jaeger、Zipkin、Prometheus 等主流监控系统的专用导出器,也支持通过通用 OTLP 导出器转发到其他 Collector
协议转换‌
自动将 OpenTelemetry 原生格式转换为目标系统兼容的格式(如 Jaeger 的 Thrift 结构)。

我们可以看到Collector 一共遵循两种传输协议:HTTP 和 gRPC,提交的数据可以有两种格式protobuf 和json,可以通过请求头中的Content-Type设定(如 application/x-protobuf 或application/json)。我们还注意到数据接收Receivers的时候还在组织构TraceID、SpanID等以使数据造符合标准化内部数据结构。之前使用SDK的时候这块都是无感知透明化的,也就是SDK已经处理得明明白白了,你只管提交到后端储存就可以啦。

比如我们再次感受下之前通过SDK上报的示例。

putenv('OTEL_SERVICE_NAME=demo1');
putenv('OTEL_PHP_AUTOLOAD_ENABLED=true');
putenv('OTEL_TRACES_EXPORTER=console');//导出协议  console  otlp...
putenv('OTEL_METRICS_EXPORTER=none');
putenv('OTEL_LOGS_EXPORTER=console');
#putenv('OTEL_EXPORTER_OTLP_PROTOCOL=grpc');//上报协议 Traces 支持 grpc、http/protobuf、http/json。 Metrics 支持 grpc、http/protobuf。
#putenv('OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318');//上报端点 http:4318,grpc:4317
#putenv('OTEL_EXPORTER_OTLP_HEADERS=');
#putenv('OTEL_PROPAGATORS=b3,baggage,tracecontext');

use OpenTelemetry\API\Globals;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require_once __DIR__ . '/vendor/autoload.php';

$tracer = Globals::tracerProvider()->getTracer('demo-tracer-name');

$app = AppFactory::create();

$app->get('/rolldice', function (Request $request, Response $response) use ($tracer) {
    $span = $tracer->spanBuilder('manual-span')->startSpan();
    try {

        $span->setAttribute('user_id', 12345);

        $result = random_int(1, 6);
        $response->getBody()->write(strval($result));

        $span->addEvent('rolled dice', ['result' => $result])->end();

        return $response;
    } catch (Exception $e) {

        $span->setStatus($e->getCode(), $e->getMessage());
        $span->end();

        $response->getBody()->write('exception');
        return $response;
    }

});

$app->run();


现在我们来看这样的一条HTTP上报路径。

[应用代码] --生成Span数据--> [SDK Exporter] --OTLP/HTTP序列化-->  
[Collector HTTP接收器] --数据处理管道--> [后端存储]

在这个流程里我们计划采用HTTP的application/json格式上报。如果不使用SDK,那么就意味着我们需要自己完成后端存储节点之前的数据规范处理所有工作(我们甚至是否可以大胆地认为就是 [后端存储] 节点之前的所有工作,包含Collector内的动作)。撇开次要因素不提,主要就是一个构造 OTLP/HTTP JSON trace 数据的过程。那么首先我们得先要知道OTLP协议规范的必备数据格式是什么,下文将以例子直接展示。

二、不加载OpenTelemetry SDK实现Trace‌与Logs示例

通过上面的原理分析,事情就变得简单有趣了,直接上示例代码。

/**
 *  上报trace 参考案例
 *- 可以通过 HTTP 接口(如 OTLP/HTTP)手动上报追踪数据到 OpenTelemetry Collector。
 *- 需要自己构造符合 OTLP JSON 规范的数据包并发送。
 *- 推荐优先使用 SDK,接口方式适合特殊场景或兼容老环境。
 *
 */


// 需要 PHP 7.1+,并安装 guzzlehttp/guzzle
require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client();

$traceId = bin2hex(random_bytes(16)); // 16字节=32位hex
$spanId = bin2hex(random_bytes(8));   // 8字节=16位hex
$now = (int)(microtime(true) * 1e9);  // 纳秒

// 构造 OTLP/HTTP JSON trace 数据
$traceData = [
    "resourceSpans" => [
        [
            "resource" => [
                "attributes" => [
                    [
                        "key" => "service.name",
                        "value" => ["stringValue" => "php-manual-otel"]
                    ]
                ]
            ],
            "scopeSpans" => [
                [
                    "scope" => [
                        "name" => "manual-php",
                        "version" => "1.0.0"
                    ],
                    "spans" => [
                        [
                            "traceId" => $traceId,
                            "spanId" => $spanId,
                            "name" => "manual-span",
                            "kind" => 1, // SPAN_KIND_INTERNAL
                            "startTimeUnixNano" => $now,
                            "endTimeUnixNano" => $now + 1000000, // +1ms
                            "attributes" => [
                                [
                                    "key" => "http.method",
                                    "value" => ["stringValue" => "GET"]
                                ]
                            ],
                            "status" => [
                                "code" => 1 // STATUS_CODE_UNSET
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];

try {
    $response = $client->post('http://collector:4318/v1/traces', [
        'headers' => [
            'Content-Type' => 'application/json',
            'xxxx-token' => 'xxx'
        ],
        'body' => json_encode($traceData),
    ]);
    echo "Status: " . $response->getStatusCode() . "\n";
    echo "Response: " . $response->getBody() ."| traceId={$traceId}". "\n";
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

/**
 *  上报logs 参考案例
 *- 可以通过 HTTP 接口(如 OTLP/HTTP)手动上报追踪数据到 OpenTelemetry Collector。
 *- 需要自己构造符合 OTLP JSON 规范的数据包并发送。
 *- 推荐优先使用 SDK,接口方式适合特殊场景或兼容老环境。
 *
 */

// 需要 PHP 7.1+,并安装 guzzlehttp/guzzle
require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client();

$now = (int)(microtime(true) * 1e9);  // 纳秒

// 构造 OTLP/HTTP JSON log 数据
$logData = [
    "resourceLogs" => [
        [
            "resource" => [
                "attributes" => [
                    [
                        "key" => "service.name",
                        "value" => ["stringValue" => "php-manual-otel-logs"]
                    ]
                ]
            ],
            "scopeLogs" => [
                [
                    "scope" => [
                        "name" => "manual-php",
                        "version" => "1.0.0"
                    ],
                    "logRecords" => [
                        [
                            "timeUnixNano" => $now,
                            "severityNumber" => 9, // INFO
                            "severityText" => "INFO",
                            "body" => ["stringValue" => "This is a manual log from PHP"],
                            "attributes" => [
                                [
                                    "key" => "http.method",
                                    "value" => ["stringValue" => "GET"]
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];

try {
    $response = $client->post('http://collector:4318/v1/logs', [
        'headers' => [
            'Content-Type' => 'application/json',
            'xxxx-token' => 'xxx'
        ],
        'body' => json_encode($logData),
    ]);
    echo "Status: " . $response->getStatusCode() . "\n";
    echo "Response: " . $response->getBody() . "\n";
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

至此,我们不加载OpenTelemetry SDK实现Trace‌与Logs就完成啦。当然这只是个简单的例子抛砖引玉供参考,在实际的应用中不加载SDK终归要自己处理很多业务之外繁琐的事情,甚至与可能丢失Collector 很多优化的环节。正如示例所说,接口方式适合特殊场景或兼容老环境的临时解决方案,能升级版本解决的尽量使用SDK,推荐优先使用 SDK。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2394471.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Three.js搭建小米SU7三维汽车实战(6)颜色切换

颜色切换 接下来我们来实现懂车帝的颜色切换效果 可以让ai帮我们生成页面结构以及样式,注意changeCarBodyColor这个函数需要我们自己来写 // 创建颜色选择器UI function createColorSelector() {const colors [{ name: "深海蓝", hex: "#1A9CB0&qu…

mysql慢sql的实际处理方案之一

复习mysql架构图 当大批量慢sql过来,显然就是占用了线程池的链接,然后长久不释放,所以会出现线程池满的问题,致使正常业务sql也全部阻塞,影响整个业务。 AI搜索如下: 可以考虑一种方案: 将线…

4.2.3 Spark SQL 手动指定数据源

在本节实战中,我们学习了如何在Spark SQL中手动指定数据源以及如何使用format()和option()方法。通过案例演示,我们读取了不同格式的数据文件,包括CSV、JSON,并从JDBC数据源读取数据,展示了如何将这些数据转换为DataFr…

【论文解读】CVPR2023 PoseFormerV2:3D人体姿态估计(附论文地址)

论文链接:https://arxiv.org/pdf/2303.17472 源码链接:https://github.com/QitaoZhao/PoseFormerV2 Abstract 本文提出了 PoseFormerV2,通过探索频率域来提高 3D 人体姿态估计的效率和鲁棒性。PoseFormerV2 利用离散余弦变换(DC…

Maven工程演示

软件:idea 一、项目创建 操作截图file -> New -> Projectnextnext -> Name:工程名称;Location:项目路径;项目创建完成;文件夹基本样例:(如果不完整自己创建即可)MANIFEST.MF内容 二、导入依赖 …

uniapp分包配置,uniapp设置subPackages

在使用uniapp开发过程中,由于项目比较大,无法直接上传,需要分包后才可以上传。 步骤: 1、在pages同级目录下创建分包的目录(pages_second),把要分包的文件放到该目录下; 2、在pag…

C++八股 —— 手撕线程池

文章目录 一、背景二、线程池实现1. 任务队列和工作线程2. 构造和析构函数3. 添加任务函数4. 完整代码 三、阻塞队列实现1. 基础队列2. 升级版队列 四、测试代码五、相关问题六、其他实现方式 来自:华为C一面:手撕线程池_哔哩哔哩_bilibili 华为海思&am…

RPA如何支持跨平台和跨浏览器的自动化

RPA,即机器人流程自动化(Robotic Process Automation),正日益成为企业实现业务流程高效自动化的关键技术。在复杂的数字化环境中,跨平台和跨浏览器的自动化需求极为迫切,RPA 通过多种技术手段和策略来满足这…

【笔记】Windows 成功部署 Suna 开源的通用人工智能代理项目部署日志

#工作记录 本地部署运行截图 kortix-ai/suna: Suna - 开源通用 AI 代理 项目概述 Suna 是一个完全开源的 AI 助手,通过自然对话帮助用户轻松完成研究、数据分析等日常任务。它结合了强大的功能和直观的界面,能够理解用户需求并提供结果。其强…

Linux531rsync定时同步 再回忆

rsync定时同步 环境配置 关闭防火墙,selinux systemctl stop firewalld systemctl disable firewall setenforce 0 cat /etc/selinux/configpei SELINUXdisable设置主机名 systemctl set-hostname code systemctl set-hostname backup设置静态IP rsync由于要设…

【KWDB 创作者计划】_探秘浪潮KWDB数据库:从时间索引到前沿技术

探秘浪潮KWDB数据库:从时间索引到前沿技术 文章目录 探秘浪潮KWDB数据库:从时间索引到前沿技术引言1.浪潮KWDB数据库时间索引深度解析1.1时间索引工作原理1.2时间索引创建与管理实践 2.浪潮KWDB数据库前沿产品技术纵览2.1多模融合存储引擎2.2就地计算技术…

安卓逆向篇LSP 模块HOOK 添加技术绕过检测算法解密逻辑验证

前置解释: 0 、 Magisk : 是当前 Android 社区用来获取 root 权限的主流方式开源工具 1 、 LSP 框架: XPosed 框架因只支持安卓 8 及以下,故高版本应使用 MagiskLSPosed 2 、 HOOK 技术: 钩子技术&…

第一节 51单片机概述

目录 一、单片机系统组成 (一)、单片机硬件系统 (二)单片机的软件系统 二、STC89C52单片机 (1)、基本信息 (2)、命名规则 (3)、单片机内部结构图 &am…

Google car key:安全、便捷的汽车解锁新选择

有了兼容的汽车和 Android 手机,Google car key可让您将Android 手机用作车钥匙。您可以通过兼容的 Android 手机锁定、解锁、启动汽车并执行更多功能。但是,Google car key安全吗?它是如何工作的?如果我的手机电池没电了怎么办&a…

720全景展示:VR全景的技术原理及应用

VR720全景展示:技术原理及应用探索 720全景技术,作为当前全球范围内迅速崛起流行的视觉新技术,为用户带来了全新的真实现场感和交互式的体验。凭借全方位、无死角的视觉展示特性,在VR(虚拟现实)领域中得到…

定制一款国密浏览器(13):预置国密根证书到浏览器

由于国密算法没有得到国外的认可,所以 Chromium、Firefox 等浏览器均不支持国密算法。即使我们修改了 Chromium 的源码,增加了国密算法的支持,但还不能在浏览器中正常使用。因为这涉及到证书的信任问题,国密证书都是国内厂商签发的,国密根证书并没有集成到系统和浏览器中。…

PowerBI企业运营分析——线性回归销售预测

PowerBI企业运营分析——线性回归销售预测 欢迎来到Powerbi小课堂,在竞争激烈的市场环境中,企业运营分析平台成为提升竞争力的核心工具。 该平台通过整合多源数据,实现关键指标的实时监控,从而迅速洞察业务动态,精准…

LangFuse:开源LLM工程平台的革新实践

文章目录 一 架构设计与技术栈二 增强型监控能力三 提示词工程支持(新增)四 性能优化实践五 LangFuse部署(docker)和代码集成5.1 LangFuse平台部署5.2 LangFuse代码集成和检测体验 一 架构设计与技术栈 LangFuse采用模块化架构设…

新视角!经济学顶刊QJE用文本分析探究新技术扩散

美国圣路易斯联邦储备银行Aakash Kalyani、美国斯坦福大学与国家经济研究局Nicholas Bloom、英国伦敦商学院Marcela Carvalho和其合作者们共同研究的“The Diffusion of New Technologies(新技术的扩散)”在顶刊The Quarterly Journal of Economics中发表…

5月31日day41打卡

简单CNN 知识回顾 数据增强卷积神经网络定义的写法batch归一化:调整一个批次的分布,常用与图像数据特征图:只有卷积操作输出的才叫特征图调度器:直接修改基础学习率 卷积操作常见流程如下: 1. 输入 → 卷积层 → Batch…