Exporters
You are viewing the English version of this page because it has not yet been fully translated. Interested in helping out? See Contributing.
将遥测数据发送到 OpenTelemetry Collector,以确保其被正确导出。 在生产环境中使用 Collector 是最佳实践。若要可视化你的遥测数据,可将其导出到后端系统,例如 Jaeger、Zipkin、 Prometheus,或某个特定厂商的后端。
可用的导出器
镜像仓库中包含一份 C++ 可用导出器的列表。
在所有导出器中,OpenTelemetry 协议 (OTLP) 导出器是以 OpenTelemetry 数据模型为基础设计的, 能够无信息丢失地输出 OTel 数据。此外,许多处理遥测数据的工具都支持 OTLP (例如 Prometheus、Jaeger 和大多数厂商),在你需要时为你提供高度的灵活性。 若要了解更多关于 OTLP 的信息,请参阅 OTLP 规范。
本页面介绍了主要的 OpenTelemetry C++ 导出器以及如何进行配置。
OTLP
Collector 设置
如果你已经配置好 OTLP Collector 或后端,可以跳过此部分, 直接设置应用的 OTLP 导出器依赖。
为测试和验证你的 OTLP 导出器,你可以运行一个 Docker 容器形式的 Collector,将遥测数据直接输出到控制台。
在一个空目录下创建名为 collector-config.yaml
的文件,并添加以下内容:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
exporters: [debug]
metrics:
receivers: [otlp]
exporters: [debug]
logs:
receivers: [otlp]
exporters: [debug]
然后运行以下命令,在 Docker 容器中启动 Collector:
docker run -p 4317:4317 -p 4318:4318 --rm -v $(pwd)/collector-config.yaml:/etc/otelcol/config.yaml otel/opentelemetry-collector
现在,这个 Collector 已能通过 OTLP 接收遥测数据。 之后你可能需要配置 Collector,将遥测数据发送到你的可观测性后端。
Dependencies
If you want to send telemetry data to an OTLP endpoint (like the OpenTelemetry Collector, Jaeger or Prometheus), you can choose between two different protocols to transport your data:
- HTTP/protobuf
- gRPC
Make sure that you have set the right cmake build variables while building OpenTelemetry C++ from source:
-DWITH_OTLP_GRPC=ON
: To enable building OTLP gRPC exporter.-DWITH_OTLP_HTTP=ON
: To enable building OTLP HTTP exporter.
Usage
Next, configure the exporter to point at an OTLP endpoint in your code.
#include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_http_exporter_options.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/batch_span_processor_factory.h"
#include "opentelemetry/sdk/trace/batch_span_processor_options.h"
#include "opentelemetry/sdk/trace/tracer_provider_factory.h"
#include "opentelemetry/trace/provider.h"
#include "opentelemetry/sdk/trace/tracer_provider.h"
#include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h"
#include "opentelemetry/metrics/provider.h"
#include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h"
#include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h"
#include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_factory.h"
#include "opentelemetry/sdk/metrics/meter_context_factory.h"
#include "opentelemetry/sdk/metrics/meter_provider.h"
#include "opentelemetry/sdk/metrics/meter_provider_factory.h"
#include "opentelemetry/exporters/otlp/otlp_http_log_record_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_http_log_record_exporter_options.h"
#include "opentelemetry/logs/provider.h"
#include "opentelemetry/sdk/logs/logger_provider_factory.h"
#include "opentelemetry/sdk/logs/processor.h"
#include "opentelemetry/sdk/logs/simple_log_record_processor_factory.h"
namespace trace_api = opentelemetry::trace;
namespace trace_sdk = opentelemetry::sdk::trace;
namespace metric_sdk = opentelemetry::sdk::metrics;
namespace metrics_api = opentelemetry::metrics;
namespace otlp = opentelemetry::exporter::otlp;
namespace logs_api = opentelemetry::logs;
namespace logs_sdk = opentelemetry::sdk::logs;
void InitTracer()
{
trace_sdk::BatchSpanProcessorOptions bspOpts{};
otlp::OtlpHttpExporterOptions opts;
opts.url = "http://localhost:4318/v1/traces";
auto exporter = otlp::OtlpHttpExporterFactory::Create(opts);
auto processor = trace_sdk::BatchSpanProcessorFactory::Create(std::move(exporter), bspOpts);
std::shared_ptr<trace_api::TracerProvider> provider = trace_sdk::TracerProviderFactory::Create(std::move(processor));
trace_api::Provider::SetTracerProvider(provider);
}
void InitMetrics()
{
otlp::OtlpHttpMetricExporterOptions opts;
opts.url = "http://localhost:4318/v1/metrics";
auto exporter = otlp::OtlpHttpMetricExporterFactory::Create(opts);
metric_sdk::PeriodicExportingMetricReaderOptions reader_options;
reader_options.export_interval_millis = std::chrono::milliseconds(1000);
reader_options.export_timeout_millis = std::chrono::milliseconds(500);
auto reader = metric_sdk::PeriodicExportingMetricReaderFactory::Create(std::move(exporter), reader_options);
auto context = metric_sdk::MeterContextFactory::Create();
context->AddMetricReader(std::move(reader));
auto u_provider = metric_sdk::MeterProviderFactory::Create(std::move(context));
std::shared_ptr<metrics_api::MeterProvider> provider(std::move(u_provider));
metrics_api::Provider::SetMeterProvider(provider);
}
void InitLogger()
{
otlp::OtlpHttpLogRecordExporterOptions opts;
opts.url = "http://localhost:4318/v1/logs";
auto exporter = otlp::OtlpHttpLogRecordExporterFactory::Create(opts);
auto processor = logs_sdk::SimpleLogRecordProcessorFactory::Create(std::move(exporter));
std::shared_ptr<logs_api::LoggerProvider> provider =
logs_sdk::LoggerProviderFactory::Create(std::move(processor));
logs_api::Provider::SetLoggerProvider(provider);
}
#include "opentelemetry/exporters/otlp/otlp_grpc_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/batch_span_processor_factory.h"
#include "opentelemetry/sdk/trace/batch_span_processor_options.h"
#include "opentelemetry/sdk/trace/tracer_provider_factory.h"
#include "opentelemetry/trace/provider.h"
#include "opentelemetry/sdk/trace/tracer_provider.h"
#include "opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h"
#include "opentelemetry/metrics/provider.h"
#include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h"
#include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h"
#include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_factory.h"
#include "opentelemetry/sdk/metrics/meter_context_factory.h"
#include "opentelemetry/sdk/metrics/meter_provider.h"
#include "opentelemetry/sdk/metrics/meter_provider_factory.h"
#include "opentelemetry/exporters/otlp/otlp_grpc_log_record_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_grpc_log_record_exporter_options.h"
#include "opentelemetry/logs/provider.h"
#include "opentelemetry/sdk/logs/logger_provider_factory.h"
#include "opentelemetry/sdk/logs/processor.h"
#include "opentelemetry/sdk/logs/simple_log_record_processor_factory.h"
namespace trace_api = opentelemetry::trace;
namespace trace_sdk = opentelemetry::sdk::trace;
namespace metric_sdk = opentelemetry::sdk::metrics;
namespace metrics_api = opentelemetry::metrics;
namespace otlp = opentelemetry::exporter::otlp;
namespace logs_api = opentelemetry::logs;
namespace logs_sdk = opentelemetry::sdk::logs;
void InitTracer()
{
trace_sdk::BatchSpanProcessorOptions bspOpts{};
opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts;
opts.endpoint = "localhost:4317";
opts.use_ssl_credentials = true;
opts.ssl_credentials_cacert_as_string = "ssl-certificate";
auto exporter = otlp::OtlpGrpcExporterFactory::Create(opts);
auto processor = trace_sdk::BatchSpanProcessorFactory::Create(std::move(exporter), bspOpts);
std::shared_ptr<opentelemetry::trace_api::TracerProvider> provider =
trace_sdk::TracerProviderFactory::Create(std::move(processor));
// Set the global trace provider
trace_api::Provider::SetTracerProvider(provider);
}
void InitMetrics()
{
otlp::OtlpGrpcMetricExporterOptions opts;
opts.endpoint = "localhost:4317";
opts.use_ssl_credentials = true;
opts.ssl_credentials_cacert_as_string = "ssl-certificate";
auto exporter = otlp::OtlpGrpcMetricExporterFactory::Create(opts);
metric_sdk::PeriodicExportingMetricReaderOptions reader_options;
reader_options.export_interval_millis = std::chrono::milliseconds(1000);
reader_options.export_timeout_millis = std::chrono::milliseconds(500);
auto reader = metric_sdk::PeriodicExportingMetricReaderFactory::Create(std::move(exporter), reader_options);
auto context = metric_sdk::MeterContextFactory::Create();
context->AddMetricReader(std::move(reader));
auto u_provider = metric_sdk::MeterProviderFactory::Create(std::move(context));
std::shared_ptr<opentelemetry::metrics::MeterProvider> provider(std::move(u_provider));
metrics_api::Provider::SetMeterProvider(provider);
}
void InitLogger()
{
otlp::OtlpGrpcLogRecordExporterOptions opts;
opts.endpoint = "localhost:4317";
opts.use_ssl_credentials = true;
opts.ssl_credentials_cacert_as_string = "ssl-certificate";
auto exporter = otlp::OtlpGrpcLogRecordExporterFactory::Create(opts);
auto processor = logs_sdk::SimpleLogRecordProcessorFactory::Create(std::move(exporter));
nostd::shared_ptr<logs_api::LoggerProvider> provider(
logs_sdk::LoggerProviderFactory::Create(std::move(processor)));
logs_api::Provider::SetLoggerProvider(provider);
}
Console
To debug your instrumentation or see the values locally in development, you can use exporters writing telemetry data to the console (stdout).
While
building OpenTelemetry C++ from source
the OStreamSpanExporter
is included in the build by default.
#include "opentelemetry/exporters/ostream/span_exporter_factory.h"
#include "opentelemetry/sdk/trace/exporter.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/simple_processor_factory.h"
#include "opentelemetry/sdk/trace/tracer_provider_factory.h"
#include "opentelemetry/trace/provider.h"
#include "opentelemetry/exporters/ostream/metrics_exporter_factory.h"
#include "opentelemetry/sdk/metrics/meter_provider.h"
#include "opentelemetry/sdk/metrics/meter_provider_factory.h"
#include "opentelemetry/metrics/provider.h"
#include "opentelemetry/exporters/ostream/log_record_exporter_factory.h"
#include "opentelemetry/logs/provider.h"
#include "opentelemetry/sdk/logs/logger_provider_factory.h"
#include "opentelemetry/sdk/logs/processor.h"
#include "opentelemetry/sdk/logs/simple_log_record_processor_factory.h"
namespace trace_api = opentelemetry::trace;
namespace trace_sdk = opentelemetry::sdk::trace;
namespace trace_exporter = opentelemetry::exporter::trace;
namespace metrics_sdk = opentelemetry::sdk::metrics;
namespace metrics_api = opentelemetry::metrics;
namespace metrics_exporter = opentelemetry::exporter::metrics;
namespace logs_api = opentelemetry::logs;
namespace logs_sdk = opentelemetry::sdk::logs;
namespace logs_exporter = opentelemetry::exporter::logs;
void InitTracer()
{
auto exporter = trace_exporter::OStreamSpanExporterFactory::Create();
auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
std::shared_ptr<opentelemetry::trace::TracerProvider> provider = trace_sdk::TracerProviderFactory::Create(std::move(processor));
trace_api::Provider::SetTracerProvider(provider);
}
void InitMetrics()
{
auto exporter = metrics_exporter::OStreamMetricExporterFactory::Create();
auto u_provider = metrics_sdk::MeterProviderFactory::Create();
std::shared_ptr<opentelemetry::metrics::MeterProvider> provider(std::move(u_provider));
auto *p = static_cast<metrics_sdk::MeterProvider *>(u_provider.get());
p->AddMetricReader(std::move(exporter));
metrics_api::Provider::SetMeterProvider(provider);
}
void InitLogger()
{
auto exporter = logs_exporter::OStreamLogRecordExporterFactory::Create();
auto processor = logs_sdk::SimpleLogRecordProcessorFactory::Create(std::move(exporter));
nostd::shared_ptr<logs_api::LoggerProvider> provider(
logs_sdk::LoggerProviderFactory::Create(std::move(processor)));
logs_api::Provider::SetLoggerProvider(provider);
}
Jaeger
后端设置
Jaeger 原生支持 OTLP,用于接收链路(trace)数据。你可以通过运行一个 Docker 容器来启动 Jaeger,其 UI 默认在端口 16686 上可访问,并在端口 4317 和 4318 上启用 OTLP:
docker run --rm \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
-p 9411:9411 \
jaegertracing/all-in-one:latest
使用方法
现在,按照说明设置 OTLP exporters。
Prometheus
要将你的指标(metrics)数据发送到 Prometheus,
你可以选择
启用 Prometheus 的 OTLP 接收器
并且使用 OTLP exporter,或者使用 Prometheus exporter,这是一种 MetricReader
,
他启动一个 HTTP 服务器,根据请求收集指标并将数据序列化为 Prometheus 文本格式。
后端设置
如果你已经设置了 Prometheus 或兼容 Prometheus 的后端,可以跳过本节,直接为你的应用设置 Prometheus 或者 OTLP exporter 依赖。
你可以按照以下步骤在 Docker 容器中运行 Prometheus,并通过端口 9090 访问:
创建一个名为 prometheus.yml
的文件,并将以下内容写入文件:
scrape_configs:
- job_name: dice-service
scrape_interval: 5s
static_configs:
- targets: [host.docker.internal:9464]
使用以下命令在 Docker 容器中运行 Prometheus,UI 可通过端口 9090
访问:
docker run --rm -v ${PWD}/prometheus.yml:/prometheus/prometheus.yml -p 9090:9090 prom/prometheus --enable-feature=otlp-write-receive
当使用 Prometheus 的 OTLP 接收器(Reciever)时,确保在应用中设置 OTLP 端点为
http://localhost:9090/api/v1/otlp
。
并非所有的 Docker 环境都支持 host.docker.internal
。在某些情况下,你可能需要将 host.docker.internal
替换为 localhost
或你机器的 IP 地址。
Dependencies
To send your trace data to Prometheus, make sure that you have set the right cmake build variables while building OpenTelemetry C++ from source:
cmake -DWITH_PROMETHEUS=ON ...
Update your OpenTelemetry configuration to use the Prometheus Exporter:
#include "opentelemetry/exporters/prometheus/exporter_factory.h"
#include "opentelemetry/exporters/prometheus/exporter_options.h"
#include "opentelemetry/metrics/provider.h"
#include "opentelemetry/sdk/metrics/meter_provider.h"
#include "opentelemetry/sdk/metrics/meter_provider_factory.h"
namespace metrics_sdk = opentelemetry::sdk::metrics;
namespace metrics_api = opentelemetry::metrics;
namespace metrics_exporter = opentelemetry::exporter::metrics;
void InitMetrics()
{
metrics_exporter::PrometheusExporterOptions opts;
opts.url = "localhost:9464";
auto prometheus_exporter = metrics_exporter::PrometheusExporterFactory::Create(opts);
auto u_provider = metrics_sdk::MeterProviderFactory::Create();
auto *p = static_cast<metrics_sdk::MeterProvider *>(u_provider.get());
p->AddMetricReader(std::move(prometheus_exporter));
std::shared_ptr<metrics_api::MeterProvider> provider(std::move(u_provider));
metrics_api::Provider::SetMeterProvider(provider);
}
With the above you can access your metrics at http://localhost:9464/metrics. Prometheus or an OpenTelemetry Collector with the Prometheus receiver can scrape the metrics from this endpoint.
Zipkin
后端设置
如果你已经设置了 Zipkin 或兼容 Zipkin 的后端,可以跳过本节并直接为你的应用设置 Zipkin exporter 依赖。
你可以通过执行以下命令,在 Docker 容器中运行 Zipkin:
docker run --rm -d -p 9411:9411 --name zipkin openzipkin/zipkin
Dependencies
To send your trace data to Zipkin, make sure that you have set the right cmake build variables while building OpenTelemetry C++ from source:
cmake -DWITH_ZIPKIN=ON ...
Update your OpenTelemetry configuration to use the Zipkin Exporter and to send data to your Zipkin backend:
#include "opentelemetry/exporters/zipkin/zipkin_exporter_factory.h"
#include "opentelemetry/sdk/resource/resource.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/simple_processor_factory.h"
#include "opentelemetry/sdk/trace/tracer_provider_factory.h"
#include "opentelemetry/trace/provider.h"
namespace trace = opentelemetry::trace;
namespace trace_sdk = opentelemetry::sdk::trace;
namespace zipkin = opentelemetry::exporter::zipkin;
namespace resource = opentelemetry::sdk::resource;
void InitTracer()
{
zipkin::ZipkinExporterOptions opts;
resource::ResourceAttributes attributes = {{"service.name", "zipkin_demo_service"}};
auto resource = resource::Resource::Create(attributes);
auto exporter = zipkin::ZipkinExporterFactory::Create(opts);
auto processor = trace_sdk::SimpleSpanProcessorFactory::Create(std::move(exporter));
std::shared_ptr<opentelemetry::trace::TracerProvider> provider =
trace_sdk::TracerProviderFactory::Create(std::move(processor), resource);
// Set the global trace provider
trace::Provider::SetTracerProvider(provider);
}
自定义导出器(Exporter)
最后,你还可以编写自己的导出器。有关更多信息,请参见 API 文档中的 SpanExporter 接口.
批量处理 Span 和日志记录
OpenTelemetry SDK 提供了一组默认的 span 和日志记录处理器,允许你选择按单条(simple)或按批量(batch)方式导出一个或多个 span。推荐使用批量处理,但如果你不想批量处理 span 或日志记录,可以使用 simple 处理器,方法如下:
#include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_http_exporter_options.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/batch_span_processor_factory.h"
#include "opentelemetry/sdk/trace/batch_span_processor_options.h"
opentelemetry::sdk::trace::BatchSpanProcessorOptions options{};
auto exporter = opentelemetry::exporter::otlp::OtlpHttpExporterFactory::Create(opts);
auto processor = opentelemetry::sdk::trace::BatchSpanProcessorFactory::Create(std::move(exporter), options);
#include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_http_exporter_options.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/simple_processor_factory.h"
auto exporter = opentelemetry::exporter::otlp::OtlpHttpExporterFactory::Create(opts);
auto processor = opentelemetry::sdk::trace::SimpleSpanProcessorFactory::Create(std::move(exporter));
Feedback
Was this page helpful?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!