仪表化
Instrumention 是指您自己向应用程序添加可观察性代码的过程。
如果您正在 instrumenting 应用程序,您需要为您使用的语言使用 OpenTelemetry SDK。然后,您将使用 SDK 初始化 OpenTelemetry,并使用 API instrument 您的代码。这将从您的应用程序和任何也带有 instrumention 的已安装库中发出遥测数据。
如果您正在 instrumenting 库,请仅安装您语言的 OpenTelemetry API 包。您的库不会自行发出遥测数据。只有当它作为使用 OpenTelemetry SDK 的应用程序的一部分时,它才会发出遥测数据。有关 instrumenting 库的更多信息,请参阅 Libraries。
有关 OpenTelemetry API 和 SDK 的更多信息,请参阅 specification。
当您想要 instrument 的库的源代码不可用时,OpenTelemetry C++ 不支持自动 instrumention。
设置
请按照 Getting Started Guide 中的说明构建 OpenTelemetry C++。
追踪
初始化跟踪
auto provider = opentelemetry::trace::Provider::GetTracerProvider();
auto tracer = provider->GetTracer("foo_library", "1.0.0");
在第一步中获得的 TracerProvider 是一个单例对象,通常由 OpenTelemetry C++ SDK 提供。它用于为 API 接口提供特定的实现。如果没有使用 SDK,API 会提供一个默认的 TracerProvider 的 no-op 实现。
在第二步中获得的 Tracer 用于创建和启动 spans。
开始一个 span
auto span = tracer->StartSpan("HandleRequest");
这会创建一个 span,将其名称设置为 "HandleRequest",并将其开始时间设置为当前时间。有关用于丰富 span 的其他操作,请参阅 API 文档。
将 span 标记为活动状态
auto scope = tracer->WithActiveSpan(span);
这会将 span 标记为活动状态并返回一个 Scope 对象。scope 对象控制 span 的活动时间。span 在 scope 对象的生命周期内保持活动状态。
活动 span 的概念很重要,因为任何在没有显式指定父 span 的情况下创建的 span 都会以当前活动 span 为父 span。没有父 span 的 span 称为根 span。
创建嵌套 span
auto outer_span = tracer->StartSpan("Outer operation");
auto outer_scope = tracer->WithActiveSpan(outer_span);
{
auto inner_span = tracer->StartSpan("Inner operation");
auto inner_scope = tracer->WithActiveSpan(inner_span);
// ... perform inner operation
inner_span->End();
}
// ... perform outer operation
outer_span->End();
Span 可以嵌套,并与其他 span 具有父子关系。当一个给定的 span 处于活动状态时,新创建的 span 将继承活动 span 的 trace ID 和其他上下文属性。
上下文传播
// set global propagator
opentelemetry::context::propagation::GlobalTextMapPropagator::SetGlobalPropagator(
nostd::shared_ptr<opentelemetry::context::propagation::TextMapPropagator>(
new opentelemetry::trace::propagation::HttpTraceContext()));
// get global propagator
HttpTextMapCarrier<opentelemetry::ext::http::client::Headers> carrier;
auto propagator =
opentelemetry::context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
//inject context to headers
auto current_ctx = opentelemetry::context::RuntimeContext::GetCurrent();
propagator->Inject(carrier, current_ctx);
//Extract headers to context
auto current_ctx = opentelemetry::context::RuntimeContext::GetCurrent();
auto new_context = propagator->Extract(carrier, current_ctx);
auto remote_span = opentelemetry::trace::propagation::GetSpan(new_context);
Context 包含当前活动 Span 的元数据,包括 Span ID、Trace ID 和标志。Context Propagation 是分布式跟踪中跨服务边界传递此 Context 的重要机制,通常通过 HTTP 头传递。OpenTelemetry 使用基于文本的方法,通过 W3C Trace Context HTTP 头将 Context 传播到远程服务。
进一步阅读
指标
初始化导出器和读取器
初始化一个导出器和一个读取器。在这种情况下,您初始化一个 OStream Exporter,它默认打印到 stdout。读取器会定期从 Aggregation Store 收集指标并导出它们。
std::unique_ptr<opentelemetry::sdk::metrics::MetricExporter> exporter{new opentelemetry::exporters::OStreamMetricExporter};
std::unique_ptr<opentelemetry::sdk::metrics::MetricReader> reader{
new opentelemetry::sdk::metrics::PeriodicExportingMetricReader(std::move(exporter), options)};
初始化 MeterProvider
初始化一个 MeterProvider 并添加读取器。将来可以使用它来获取 Meter 对象。
auto provider = std::shared_ptr<opentelemetry::metrics::MeterProvider>(new opentelemetry::sdk::metrics::MeterProvider());
auto p = std::static_pointer_cast<opentelemetry::sdk::metrics::MeterProvider>(provider);
p->AddMetricReader(std::move(reader));
创建计数器
从 Meter 中创建一个 Counter instrument,并记录测量值。MeterProvider 返回的每个 Meter 指针都指向同一个 Meter。这意味着 Meter 可以组合从不同函数捕获的指标,而无需在库中不断传递 Meter。
auto meter = provider->GetMeter(name, "1.2.0");
auto double_counter = meter->CreateDoubleCounter(counter_name);
// Create a label set which annotates metric values
std::map<std::string, std::string> labels = {{"key", "value"}};
auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
double_counter->Add(val, labelkv);
创建直方图
从 meter 中创建一个直方图 instrument,并记录测量值。
auto meter = provider->GetMeter(name, "1.2.0");
auto histogram_counter = meter->CreateDoubleHistogram("histogram_name");
histogram_counter->Record(val, labelkv);
创建可观察计数器
从 meter 中创建一个可观察计数器 instrument,并添加一个回调。回调用于在指标收集期间记录测量值。确保 instrument 对象在收集期间保持活动状态。
auto meter = provider->GetMeter(name, "1.2.0");
auto counter = meter->CreateDoubleObservableCounter(counter_name);
counter->AddCallback(MeasurementFetcher::Fetcher, nullptr);
创建视图
将计数器 instrument 映射到 sum aggregation
创建一个视图将 Counter Instrument 映射到 Sum Aggregation。将此视图添加到 provider。视图创建是可选的,除非您想添加自定义聚合配置和属性处理器。Metrics SDK 会创建一个缺失的视图,并在 Instrument 和 Aggregation 之间进行默认映射。
std::unique_ptr<opentelemetry::sdk::metrics::InstrumentSelector> instrument_selector{
new opentelemetry::sdk::metrics::InstrumentSelector(opentelemetry::sdk::metrics::InstrumentType::kCounter, "counter_name")};
std::unique_ptr<opentelemetry::sdk::metrics::MeterSelector> meter_selector{
new opentelemetry::sdk::metrics::MeterSelector(name, version, schema)};
std::unique_ptr<opentelemetry::sdk::metrics::View> sum_view{
new opentelemetry::sdk::metrics::View{name, "description", opentelemetry::sdk::metrics::AggregationType::kSum}};
p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view));
将直方图 instrument 映射到直方图 aggregation
std::unique_ptr<opentelemetry::sdk::metrics::InstrumentSelector> histogram_instrument_selector{
new opentelemetry::sdk::metrics::InstrumentSelector(opentelemetry::sdk::metrics::InstrumentType::kHistogram, "histogram_name")};
std::unique_ptr<opentelemetry::sdk::metrics::MeterSelector> histogram_meter_selector{
new opentelemetry::sdk::metrics::MeterSelector(name, version, schema)};
std::unique_ptr<opentelemetry::sdk::metrics::View> histogram_view{
new opentelemetry::sdk::metrics::View{name, "description", opentelemetry::sdk::metrics::AggregationType::kHistogram}};
p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector),
std::move(histogram_view));
将可观察计数器 instrument 映射到 sum aggregation
std::unique_ptr<opentelemetry::sdk::metrics::InstrumentSelector> observable_instrument_selector{
new opentelemetry::sdk::metrics::InstrumentSelector(opentelemetry::sdk::metrics::InstrumentType::kObservableCounter,
"observable_counter_name")};
std::unique_ptr<opentelemetry::sdk::metrics::MeterSelector> observable_meter_selector{
new opentelemetry::sdk::metrics::MeterSelector(name, version, schema)};
std::unique_ptr<opentelemetry::sdk::metrics::View> observable_sum_view{
new opentelemetry::sdk::metrics::View{name, "description", opentelemetry::sdk::metrics::AggregationType::kSum}};
p->AddView(std::move(observable_instrument_selector), std::move(observable_meter_selector),
std::move(observable_sum_view));
进一步阅读
日志
日志 API 和 SDK 的文档缺失,您可以通过 编辑此页面 来帮助提供文档。
下一步
您还需要配置适当的导出器,以便将 遥测数据导出到一个或多个遥测后端。