<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://doc.ruscomtech.ru/index.php?action=history&amp;feed=atom&amp;title=Rust_OpenTelemetry</id>
	<title>Rust OpenTelemetry - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://doc.ruscomtech.ru/index.php?action=history&amp;feed=atom&amp;title=Rust_OpenTelemetry"/>
	<link rel="alternate" type="text/html" href="https://doc.ruscomtech.ru/index.php?title=Rust_OpenTelemetry&amp;action=history"/>
	<updated>2026-05-02T12:06:00Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://doc.ruscomtech.ru/index.php?title=Rust_OpenTelemetry&amp;diff=5869&amp;oldid=prev</id>
		<title>IKuznetsov: Новая страница: «В этом пошаговом руководстве показано, как добавить возможность наблюдения в ваше прило...»</title>
		<link rel="alternate" type="text/html" href="https://doc.ruscomtech.ru/index.php?title=Rust_OpenTelemetry&amp;diff=5869&amp;oldid=prev"/>
		<updated>2025-10-16T15:51:53Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «В этом пошаговом руководстве показано, как добавить возможность наблюдения в ваше прило...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;В этом пошаговом руководстве показано, как добавить возможность наблюдения в ваше приложение '''Rust''' с помощью библиотек и инструментов '''OpenTelemetry Rust'''.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Особенность&lt;br /&gt;
!Поддержка&lt;br /&gt;
|-&lt;br /&gt;
|Автоматические инструменты&lt;br /&gt;
|Нет&lt;br /&gt;
|-&lt;br /&gt;
|Трассировки&lt;br /&gt;
|Да&lt;br /&gt;
|-&lt;br /&gt;
|Метрики&lt;br /&gt;
|Да&lt;br /&gt;
|-&lt;br /&gt;
|Логи&lt;br /&gt;
|Да&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Предустановка ==&lt;br /&gt;
&lt;br /&gt;
* Ключ-АСТРОМ версии '''1.222+'''&lt;br /&gt;
* Для трассировки включен контекст трассировки '''W3C'''.&lt;br /&gt;
*# Перейдите в '''Настройки &amp;gt; Предпочтения &amp;gt; Функции ЕдиногоАгента'''.&lt;br /&gt;
*# Включите опцию '''Отправлять HTTP-заголовки контекста трассировки W3C'''.&lt;br /&gt;
&lt;br /&gt;
== Получение данных для доступа к Ключ-АСТРОМ ==&lt;br /&gt;
&lt;br /&gt;
=== Определение базового URL API ===&lt;br /&gt;
Подробную информацию о сборке базового '''URL-адреса''' конечной точки '''OTLP''' см. в разделе [[Экспорт с помощью OTLP]]. URL-адрес должен заканчиваться на &amp;lt;code&amp;gt;/api/v2/otlp&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Получение токена доступа API ===&lt;br /&gt;
Токен доступа для сбора трассировок, логов и метрик можно создать в разделе [[Токен доступа|Токены доступа]].&lt;br /&gt;
&lt;br /&gt;
Экспорт с помощью '''OTLP''' содержит более подробную информацию о формате и необходимых областях доступа.&lt;br /&gt;
&lt;br /&gt;
== Настройка OpenTelemetry ==&lt;br /&gt;
1. Добавьте следующее в ваш файл &amp;lt;code&amp;gt;Cargo.toml&amp;lt;/code&amp;gt;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|opentelemetry = { version = &amp;quot;~0&amp;quot;, features = [&amp;quot;trace&amp;quot;, &amp;quot;metrics&amp;quot;] }&lt;br /&gt;
&lt;br /&gt;
opentelemetry_sdk = { version = &amp;quot;~0&amp;quot;, features = [&amp;quot;rt-tokio&amp;quot;, &amp;quot;metrics&amp;quot;, &amp;quot;logs&amp;quot;, &amp;quot;spec_unstable_metrics_views&amp;quot;] }&lt;br /&gt;
&lt;br /&gt;
opentelemetry-otlp = { version = &amp;quot;~0&amp;quot;, features = [&amp;quot;http-proto&amp;quot;, &amp;quot;http-json&amp;quot;, &amp;quot;logs&amp;quot;, &amp;quot;reqwest-client&amp;quot;, &amp;quot;reqwest-rustls&amp;quot;] }&lt;br /&gt;
&lt;br /&gt;
opentelemetry-http = { version = &amp;quot;~0&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
opentelemetry-appender-log = { version = &amp;quot;~0&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
opentelemetry-semantic-conventions = { version = &amp;quot;~0&amp;quot; }&lt;br /&gt;
|}&lt;br /&gt;
2. Добавьте в свой код следующие объявления &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;use std::{env, convert::Infallible, net::SocketAddr, collections::HashMap, io::{BufRead, BufReader, Read}};&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
use opentelemetry_sdk::trace::SdkTracerProvider;&lt;br /&gt;
&lt;br /&gt;
use opentelemetry_sdk::{logs::SdkLoggerProvider, metrics::{PeriodicReader, SdkMeterProvider}, propagation::TraceContextPropagator, Resource};&lt;br /&gt;
&lt;br /&gt;
use opentelemetry_otlp::{LogExporter, MetricExporter, Protocol, SpanExporter, WithExportConfig, WithHttpConfig};&lt;br /&gt;
&lt;br /&gt;
use opentelemetry_semantic_conventions::trace;&lt;br /&gt;
&lt;br /&gt;
use opentelemetry_http::{Bytes, HeaderExtractor, HeaderInjector};&lt;br /&gt;
&lt;br /&gt;
use opentelemetry_appender_log::OpenTelemetryLogBridge;&lt;br /&gt;
&lt;br /&gt;
use opentelemetry::{global, trace::{FutureExt, Span, SpanKind, TraceContextExt, Tracer}, Context, KeyValue};&lt;br /&gt;
|}&lt;br /&gt;
3. Добавьте следующую функцию в ваш стартовый файл.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|fn init_opentelemetry() {&lt;br /&gt;
&lt;br /&gt;
    // Helper function to read potentially available OneAgent data&lt;br /&gt;
&lt;br /&gt;
    fn read_dt_metadata() -&amp;gt;  Vec&amp;lt;KeyValue&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
        fn read_single(path: &amp;amp;str, metadata: &amp;amp;mut Vec&amp;lt;KeyValue&amp;gt;) -&amp;gt; std::io::Result&amp;lt;()&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
            let mut file = std::fs::File::open(path)?;&lt;br /&gt;
&lt;br /&gt;
            if path.starts_with(&amp;quot;dt_metadata&amp;quot;) {&lt;br /&gt;
&lt;br /&gt;
                let mut name = String::new();&lt;br /&gt;
&lt;br /&gt;
                file.read_to_string(&amp;amp;mut name)?;&lt;br /&gt;
&lt;br /&gt;
                file = std::fs::File::open(name)?;&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            for line in BufReader::new(file).lines() {&lt;br /&gt;
&lt;br /&gt;
                if let Some((k, v)) = line?.split_once('=') {&lt;br /&gt;
&lt;br /&gt;
                    metadata.push(KeyValue::new(k.to_string(), v.to_string()))&lt;br /&gt;
&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            Ok(())&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        let mut metadata = Vec::new();&lt;br /&gt;
&lt;br /&gt;
        for name in [&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;dt_metadata_e617c525669e072eebe3d0f08212e8f2.properties&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;/var/lib/astromkey/enrichment/dt_metadata.properties&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;quot;/var/lib/astromkey/enrichment/dt_host_metadata.properties&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        ] {&lt;br /&gt;
&lt;br /&gt;
            let _ = read_single(name, &amp;amp;mut metadata);&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return metadata;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // ===== GENERAL SETUP =====&lt;br /&gt;
&lt;br /&gt;
    let dt_api_token = env::var(&amp;quot;DT_API_TOKEN&amp;quot;).unwrap(); // TODO: change&lt;br /&gt;
&lt;br /&gt;
    let dt_api_url = env::var(&amp;quot;DT_API_URL&amp;quot;).unwrap();&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    let mut map = HashMap::new();&lt;br /&gt;
&lt;br /&gt;
    map.insert(&amp;quot;Authorization&amp;quot;.to_string(), format!(&amp;quot;Api-Token {}&amp;quot;, dt_api_token));&lt;br /&gt;
&lt;br /&gt;
    let resource = Resource::builder()&lt;br /&gt;
&lt;br /&gt;
    .with_service_name(&amp;quot;rust-manual-quickstart&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    .with_attributes(read_dt_metadata())&lt;br /&gt;
&lt;br /&gt;
    .build();&lt;br /&gt;
&lt;br /&gt;
    use reqwest::blocking::Client; // Workaround for currently not supported reqwest library&lt;br /&gt;
&lt;br /&gt;
    let client = Client::new();&lt;br /&gt;
&lt;br /&gt;
    // ===== TRACING SETUP =====&lt;br /&gt;
&lt;br /&gt;
    global::set_text_map_propagator(TraceContextPropagator::new());&lt;br /&gt;
&lt;br /&gt;
    let tracer_exporter = SpanExporter::builder()&lt;br /&gt;
&lt;br /&gt;
        .with_http()&lt;br /&gt;
&lt;br /&gt;
        .with_http_client(client.clone())&lt;br /&gt;
&lt;br /&gt;
        .with_headers(map.clone())&lt;br /&gt;
&lt;br /&gt;
        .with_protocol(Protocol::HttpBinary)&lt;br /&gt;
&lt;br /&gt;
        .with_endpoint(dt_api_url.clone() + &amp;quot;/v1/traces&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        .build()&lt;br /&gt;
&lt;br /&gt;
        .unwrap();&lt;br /&gt;
&lt;br /&gt;
    let tracer_provider = SdkTracerProvider::builder()&lt;br /&gt;
&lt;br /&gt;
        .with_resource(resource.clone())&lt;br /&gt;
&lt;br /&gt;
        .with_batch_exporter(tracer_exporter)&lt;br /&gt;
&lt;br /&gt;
        .build();&lt;br /&gt;
&lt;br /&gt;
    global::set_tracer_provider(tracer_provider.clone());&lt;br /&gt;
&lt;br /&gt;
    // ===== METRICS SETUP ======&lt;br /&gt;
&lt;br /&gt;
    let metrics_exporter = MetricExporter::builder()&lt;br /&gt;
&lt;br /&gt;
        .with_http()&lt;br /&gt;
&lt;br /&gt;
        .with_http_client(client.clone())&lt;br /&gt;
&lt;br /&gt;
        .with_headers(map.clone())&lt;br /&gt;
&lt;br /&gt;
        .with_endpoint(dt_api_url.clone() + &amp;quot;/v1/metrics&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        .with_protocol(opentelemetry_otlp::Protocol::HttpBinary)&lt;br /&gt;
&lt;br /&gt;
        .build()&lt;br /&gt;
&lt;br /&gt;
        .unwrap();&lt;br /&gt;
&lt;br /&gt;
    let meter_provider = SdkMeterProvider::builder()&lt;br /&gt;
&lt;br /&gt;
        .with_reader(PeriodicReader::builder(metrics_exporter).build())&lt;br /&gt;
&lt;br /&gt;
        .with_resource(resource.clone())&lt;br /&gt;
&lt;br /&gt;
        .build();&lt;br /&gt;
&lt;br /&gt;
    global::set_meter_provider(meter_provider);&lt;br /&gt;
&lt;br /&gt;
    // ===== LOGS SETUP ======&lt;br /&gt;
&lt;br /&gt;
    let logger_exporter = LogExporter::builder()&lt;br /&gt;
&lt;br /&gt;
        .with_http()&lt;br /&gt;
&lt;br /&gt;
        .with_http_client(client.clone())&lt;br /&gt;
&lt;br /&gt;
        .with_headers(map.clone())&lt;br /&gt;
&lt;br /&gt;
        .with_endpoint(dt_api_url.clone() + &amp;quot;/v1/logs&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        .with_protocol(opentelemetry_otlp::Protocol::HttpBinary)&lt;br /&gt;
&lt;br /&gt;
        .build()&lt;br /&gt;
&lt;br /&gt;
        .unwrap();&lt;br /&gt;
&lt;br /&gt;
    let logger_provider = SdkLoggerProvider::builder()&lt;br /&gt;
&lt;br /&gt;
        .with_batch_exporter(logger_exporter)&lt;br /&gt;
&lt;br /&gt;
        .with_resource(resource.clone())&lt;br /&gt;
&lt;br /&gt;
        .build();      &lt;br /&gt;
&lt;br /&gt;
    let otel_log_appender = OpenTelemetryLogBridge::new(&amp;amp;logger_provider);&lt;br /&gt;
&lt;br /&gt;
    log::set_boxed_logger(Box::new(otel_log_appender)).unwrap();&lt;br /&gt;
&lt;br /&gt;
    log::set_max_level(Level::Debug.to_level_filter());&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;u&amp;gt;Расширение данных Ключ-АСТРОМ&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Операции чтения файлов, анализирующие файлы &amp;lt;code&amp;gt;dt_metadata&amp;lt;/code&amp;gt; в примере кода, пытаются прочитать файлы данных ЕдиногоАгента, чтобы расширить запрос '''OTLP''' и гарантировать, что вся соответствующая информация о топологии доступна в Ключ-АСТРОМ.&lt;br /&gt;
&lt;br /&gt;
4. Убедитесь, что переменные среды &amp;lt;code&amp;gt;DT_API_URL&amp;lt;/code&amp;gt; и &amp;lt;code&amp;gt;DT_API_TOKEN&amp;lt;/code&amp;gt; правильно настроены для '''URL-адреса''' Ключ-АСТРОМ и токена доступа.&lt;br /&gt;
&lt;br /&gt;
5. Вызовите функцию &amp;lt;code&amp;gt;init_opentelemetry()&amp;lt;/code&amp;gt; как можно раньше в стартовом коде.&lt;br /&gt;
&lt;br /&gt;
== Инструментирование своего приложения ==&lt;br /&gt;
&lt;br /&gt;
=== Добавление трассировки ===&lt;br /&gt;
1. Для начала нам нужно получить объект трассировки.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|let tracer = global::tracer(&amp;quot;my-tracer&amp;quot;);&lt;br /&gt;
|}&lt;br /&gt;
2. С помощью &amp;lt;code&amp;gt;tracer&amp;lt;/code&amp;gt; теперь мы можем начинать новые интервалы.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|let mut _span = tracer&lt;br /&gt;
&lt;br /&gt;
    .span_builder(&amp;quot;Call to /myendpoint&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    .with_kind(SpanKind::Internal)&lt;br /&gt;
&lt;br /&gt;
    .start(&amp;amp;tracer);&lt;br /&gt;
&lt;br /&gt;
_span.set_attribute(KeyValue::new(&amp;quot;http.method&amp;quot;, &amp;quot;GET&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
_span.set_attribute(KeyValue::new(&amp;quot;net.protocol.version&amp;quot;, &amp;quot;1.1&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
// TODO: Your code goes here&lt;br /&gt;
&lt;br /&gt;
_span.end();&lt;br /&gt;
|}&lt;br /&gt;
В приведенном выше коде мы:&lt;br /&gt;
&lt;br /&gt;
* Создали новый диапазон и назвали его «'''Call to /myendpoint'''».&lt;br /&gt;
* Добавили два атрибута, следуя [https://opentelemetry.io/docs/specs/semconv/general/trace/ семантическому соглашению об именовании]﻿, специфичные для действия этого диапазона: информацию о методе '''HTTP''' и версии.&lt;br /&gt;
* Добавили &amp;lt;code&amp;gt;TODO&amp;lt;/code&amp;gt; вместо конечной бизнес-логики&lt;br /&gt;
* Вызовали метод span &amp;lt;code&amp;gt;end()&amp;lt;/code&amp;gt; для завершения span.&lt;br /&gt;
&lt;br /&gt;
=== Сбор метрик ===&lt;br /&gt;
1. Для начала нам нужно получить объект метрики.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|let meter = global::meter(&amp;quot;request_counter&amp;quot;);&lt;br /&gt;
|}&lt;br /&gt;
2. С помощью &amp;lt;code&amp;gt;meter&amp;lt;/code&amp;gt; мы теперь можем создавать отдельные инструменты, например, метрику.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|let updown_counter = meter.i64_up_down_counter(&amp;quot;request_counter&amp;quot;).build();&lt;br /&gt;
|}&lt;br /&gt;
3. Теперь мы можем вызвать метод &amp;lt;code&amp;gt;add()&amp;lt;/code&amp;gt; для записи новых значений &amp;lt;code&amp;gt;updown_counter&amp;lt;/code&amp;gt; с помощью счетчика.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|updown_counter.add(1,&amp;amp;[],);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Подключение логов ===&lt;br /&gt;
В &amp;lt;code&amp;gt;init_opentelemetry()&amp;lt;/code&amp;gt;, мы ранее инициализировали [https://docs.rs/log/latest/log/ контейнер логов] с его мостом логов '''OpenTelemetry''' и теперь можем вызывать любой из его [https://docs.rs/log/latest/log/#macros макросов логов] для ведения логов непосредственно в Ключ-АСТРОМ.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|error!(&amp;quot;logging an error&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
debug!(&amp;quot;logging a debug message&amp;quot;);&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Обеспечение распространения контекста (необязательно) ===&lt;br /&gt;
Распространение контекста особенно важно, когда задействованы сетевые вызовы (например, '''REST''').&lt;br /&gt;
&lt;br /&gt;
==== Извлечение контекста при получении запроса ====&lt;br /&gt;
Чтобы продолжить существующую трассировку '''HTTP'''-запроса, необходимо сначала извлечь контекст. Для этого мы объявляем функцию &amp;lt;code&amp;gt;extract_context_from_request()&amp;lt;/code&amp;gt;, которая принимает объект входящего запроса, извлекает переданный контекст с помощью метода пропагатора &amp;lt;code&amp;gt;extract()&amp;lt;/code&amp;gt; и возвращает соответствующий объект контекста.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|// Utility function to extract the context from the incoming request headers&lt;br /&gt;
&lt;br /&gt;
fn extract_context_from_request(req: &amp;amp;Request&amp;lt;Incoming&amp;gt;) -&amp;gt; Context {&lt;br /&gt;
&lt;br /&gt;
    global::get_text_map_propagator(|propagator| {&lt;br /&gt;
&lt;br /&gt;
        propagator.extract(&amp;amp;HeaderExtractor(req.headers()))&lt;br /&gt;
&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
|}&lt;br /&gt;
Затем мы можем использовать &amp;lt;code&amp;gt;extract_context_from_request()&amp;lt;/code&amp;gt; в нашем обработчике запросов для получения этого контекста и передать его как родительский в наш собственный, новый [https://opentelemetry.io/docs/concepts/signals/traces/#server серверный диапазон]﻿ с помощью &amp;lt;code&amp;gt;start_with_context()&amp;lt;/code&amp;gt;.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|async fn router(req: Request&amp;lt;Incoming&amp;gt;) -&amp;gt; Result&amp;lt;Response&amp;lt;BoxBody&amp;lt;Bytes, hyper::Error&amp;gt;&amp;gt;, Infallible&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
    // Extract the context from the incoming request headers&lt;br /&gt;
&lt;br /&gt;
    let parent_cx = extract_context_from_request(&amp;amp;req);&lt;br /&gt;
&lt;br /&gt;
    let response = {&lt;br /&gt;
&lt;br /&gt;
        // Create a span parenting the remote client span.&lt;br /&gt;
&lt;br /&gt;
        let tracer = global::tracer(&amp;quot;example/server&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        let mut span = tracer&lt;br /&gt;
&lt;br /&gt;
            .span_builder(&amp;quot;router&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            .with_kind(SpanKind::Server)&lt;br /&gt;
&lt;br /&gt;
            .start_with_context(&amp;amp;tracer, &amp;amp;parent_cx);&lt;br /&gt;
&lt;br /&gt;
        // Adding custom attributes&lt;br /&gt;
&lt;br /&gt;
        span.set_attribute(KeyValue::new(&amp;quot;my-server-key-1&amp;quot;, &amp;quot;my-server-value-1&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // TODO Handle the HTTP request&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Внедрение контекста при отправке запросов ====&lt;br /&gt;
Чтобы передать текущий контекст другому '''HTTP'''-сервису, мы добавляем информацию о контексте в заголовки '''HTTP'''-запроса. В следующем примере объявляется функция &amp;lt;code&amp;gt;send_request()&amp;lt;/code&amp;gt;, которая принимает '''URL'''-адрес запроса, его содержимое и отправляет запрос с помощью [https://docs.rs/hyper/latest/hyper/index.html hyper]﻿.&lt;br /&gt;
&lt;br /&gt;
После инициализации объекта гиперзапроса мы вызываем метод &amp;lt;code&amp;gt;get_text_map_propagator()&amp;lt;/code&amp;gt; для получения глобального объекта &amp;lt;code&amp;gt;propagator&amp;lt;/code&amp;gt;, а затем используем функцию &amp;lt;code&amp;gt;inject_context()&amp;lt;/code&amp;gt; для добавления текущей контекстной информации к запросу.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|async fn send_request(url: &amp;amp;str, body_content: &amp;amp;str, span_name: &amp;amp;str) -&amp;gt; std::result::Result&amp;lt;(), Box&amp;lt;dyn std::error::Error + Send + Sync + 'static&amp;gt;&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
    let client = Client::builder(TokioExecutor::new()).build_http();&lt;br /&gt;
&lt;br /&gt;
    let tracer = global::tracer(&amp;quot;example/client&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    let span = tracer&lt;br /&gt;
&lt;br /&gt;
        .span_builder(String::from(span_name))&lt;br /&gt;
&lt;br /&gt;
        .with_kind(SpanKind::Client)&lt;br /&gt;
&lt;br /&gt;
        .start(&amp;amp;tracer);&lt;br /&gt;
&lt;br /&gt;
    let cx = Context::current_with_span(span);&lt;br /&gt;
&lt;br /&gt;
    let mut req = hyper::Request::builder().uri(url);&lt;br /&gt;
&lt;br /&gt;
    global::get_text_map_propagator(|propagator| {&lt;br /&gt;
&lt;br /&gt;
        propagator.inject_context(&amp;amp;cx, &amp;amp;mut HeaderInjector(req.headers_mut().unwrap()))&lt;br /&gt;
&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    let res = client&lt;br /&gt;
&lt;br /&gt;
        .request(req.body(Full::new(Bytes::from(body_content.to_string())))?)&lt;br /&gt;
&lt;br /&gt;
        .await?;&lt;br /&gt;
&lt;br /&gt;
    cx.span().add_event(&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;Got response!&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        vec![KeyValue::new(&amp;quot;status&amp;quot;, res.status().to_string())],&lt;br /&gt;
&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    Ok(())&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Настройте сбор данных в соответствии с требованиями конфиденциальности (необязательно) ==&lt;br /&gt;
Хотя Ключ-АСТРОМ автоматически собирает все атрибуты '''OpenTelemetry''', в веб-интерфейсе Ключ-АСТРОМ сохраняются и отображаются только значения атрибутов, указанные в списке разрешенных. Это предотвращает случайное сохранение персональных данных, позволяя вам соблюдать требования к конфиденциальности и контролировать объем хранимых данных мониторинга.&lt;br /&gt;
&lt;br /&gt;
Чтобы просматривать пользовательские атрибуты, необходимо сначала разрешить их использование в веб-интерфейсе Ключ-АСТРОМ.&lt;br /&gt;
&lt;br /&gt;
== Проверка загрузки данных в Ключ-АСТРОМ ==&lt;br /&gt;
После завершения инструментирования вашего приложения выполните несколько тестовых действий для создания и отправки демонстрационных трассировок, метрик и логов, а также проверьте, что они были правильно загружены в Ключ-АСТРОМ.&lt;br /&gt;
&lt;br /&gt;
Чтобы сделать это для трассировок, перейдите в раздел '''Трассировки''' и выберите вкладку '''Распределенные трассировки'''. Если вы используете ЕдиныйАгент, выберите '''PurePaths''' .&lt;br /&gt;
&lt;br /&gt;
Для просмотра метрик и логов перейдите в раздел '''Метрики''' или '''Логов''' или '''Логи и события'''.&lt;/div&gt;</summary>
		<author><name>IKuznetsov</name></author>
	</entry>
</feed>