You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法将OpenTelemetry追踪数据发送至OpenSearch求助

OpenTelemetry追踪数据无法写入OpenSearch

追踪数据能在Jaeger UI正常查看,但无法被OpenSearch摄取。尝试过配置Collector、创建管道,甚至先发送到Jaeger再转OpenSearch,都没解决问题。

OTel Collector配置文件(otel.yaml)

receivers:
  otlp:
    endpoint: "otelcol:4317"

exporters:
  opensearch:
    endpoint: "http://<domain-name>:9200"
    username: "username"
    password: "password"
    index: traces-otel-v1-%{yyyy.MM.dd}"

PHP应用代码(index.php)

<?php

use OpenTelemetry\API\Common\Instrumentation\Globals;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use OpenTelemetry\Contrib\Grpc\GrpcTransportFactory;
use OpenTelemetry\Contrib\Otlp\OtlpUtil;
use OpenTelemetry\Contrib\Otlp\SpanExporter;
use OpenTelemetry\SDK\Trace\SpanProcessor\SimpleSpanProcessor;
use OpenTelemetry\SDK\Trace\TracerProvider;
use OpenTelemetry\API\Common\Signal\Signals;

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

// Create a transport that connects to the OpenSearch endpoint
$transport = (new GrpcTransportFactory())->create('http://localhost:4317' . OtlpUtil::method(Signals::TRACE));

// Create a SpanExporter instance and pass the transport to the constructor
$exporter = new SpanExporter($transport);

// Create a TracerProvider instance and add the SpanProcessor
$tracerProvider = new TracerProvider(new SimpleSpanProcessor($exporter));

// Get the tracer for the current application
$tracer = $tracerProvider->getTracer('io.opentelemetry.contrib.php');

// Create an application
$app = AppFactory::create();

// Add routes to the application
$app->get('/', function (Request $request, Response $response) use ($tracer) {
    // Create a span for the home page request
    $span = $tracer->spanBuilder('home-page')->startSpan();

    // Write the home page HTML to the response body
    $response->getBody()->write('<h1>Welcome to our E-Commerce Store</h1>');
    $response->getBody()->write('<a href="/products">View Products</a>');
    // End the span
    $span->end();

    return $response;
});

$app->get('/products', function (Request $request, Response $response) use ($tracer) {
    // Create a span for the products page request
    $span = $tracer->spanBuilder('product-list')->startSpan();

    // Fetch product data from the database
    $products = [
        ['name' => 'Product 1', 'price' => 10.99],
        ['name' => 'Product 2', 'price' => 19.99],
        // ... more products
    ];

    // Write the products list HTML to the response body
    $response->getBody()->write('<h2>Product Listings</h2>');
    foreach ($products as $product) {
        $response->getBody()->write('<p>' . $product['name'] . ' - $' . $product['price'] . '</p>');
    }
    $response->getBody()->write('<a href="/cart">Go to Cart</a>');

    // End the span
    $span->end();

    return $response;
});

$app->get('/cart', function (Request $request, Response $response) use ($tracer) {
    // Create a span for the cart page request
    $span = $tracer->spanBuilder('cart')->startSpan();

    // Simulate fetching cart items from the session
    $cartItems = [
        ['product' => 'Product 1', 'quantity' => 2],
        // ... more cart items
    ];

    // Write the cart items HTML to the response body
    $response->getBody()->write('<h2>Shopping Cart</h2>');
    foreach ($cartItems as $item) {
        $response->getBody()->write('<p>' . $item['product'] . ' - Quantity: ' . $item['quantity'] . '</p>');
    }
    $response->getBody()->write('<a href="/checkout">Proceed to Checkout</a>');

    // End the span
    $span->end();

    return $response;
});

// Run the application
$app->run();

排查与修复建议

1. 修复Collector配置语法错误

你的otel.yaml中index字段末尾多了一个多余的双引号,会导致配置解析失败,Collector无法正常加载OpenSearch exporter:

# 错误写法
index: traces-otel-v1-%{yyyy.MM.dd}"
# 正确写法
index: traces-otel-v1-%{yyyy.MM.dd}

2. 补全Collector管道配置

Collector必须明确配置service.pipelines,将接收器、处理器(可选)和导出器串联,否则数据不会被转发到OpenSearch。补充完整配置:

receivers:
  otlp:
    endpoint: "otelcol:4317"
    protocols:
      grpc:
      http:  # 若应用用HTTP发送OTLP,需开启此协议

exporters:
  opensearch:
    endpoint: "http://<domain-name>:9200"
    username: "username"
    password: "password"
    index: traces-otel-v1-%{yyyy.MM.dd}
  jaeger:  # 保留Jaeger输出,确认数据正常流转
    endpoint: "jaeger:14250"
    tls:
      insecure: true

processors:
  batch:  # 批量处理提升性能,减少OpenSearch请求频率

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [opensearch, jaeger]

3. 验证Collector与OpenSearch连通性

在Collector所在容器/主机执行curl命令,测试OpenSearch访问权限:

curl -u username:password http://<domain-name>:9200/_cat/indices?v

若无法连接,检查网络策略、端口开放状态、OpenSearch访问控制配置。

4. 查看Collector运行日志

搜索opensearch相关错误,如认证失败、索引不存在、数据格式错误等:

# Docker部署场景查看日志
docker logs <otel-collector-container-name>

5. 确认OpenSearch索引模板存在

OpenSearch exporter需要对应索引模板处理追踪数据,确保配置中开启模板自动创建(默认开启):

exporters:
  opensearch:
    # ... 其他配置
    index_template:
      enabled: true

6. 检查OTLP协议一致性

PHP代码使用gRPC发送OTLP数据,需确保Collector的OTLP接收器开启gRPC协议(默认开启)。若Collector仅开启HTTP,需修改PHP代码使用HTTP传输:

// 替换gRPC传输为HTTP传输
use OpenTelemetry\Contrib\Http\HttpTransportFactory;

$transport = (new HttpTransportFactory())->create('http://localhost:4317' . OtlpUtil::method(Signals::TRACE));

内容的提问来源于stack exchange,提问作者Madiha Samad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:27:36