Erlang OpenTelemetry
В этом пошаговом руководстве показано, как добавить наблюдаемость в ваше приложение Erlang с помощью библиотек и инструментов OpenTelemetry Erlang.
| Особенность | Поддержка |
|---|---|
| Автоматические инструменты | Нет |
| Трассировки | Да |
| Метрики | Нет |
| Логи | Нет |
Получение данных для доступа к Ключ-АСТРОМ
Определение базового URL API
Подробную информацию о том, как собрать базовый URL-адрес конечной точки OTLP, см. в разделе Экспорт с помощью OTLP.
URL-адрес должен заканчиваться на /api/v2/otlp.
Получение токена доступа API
Токен доступа для сбора трассировок, логов и метрик можно создать в разделе Токены доступа.
Экспорт с помощью OTLP содержит более подробную информацию о формате и необходимых областях доступа.
Настройка OpenTelemetry
1. Добавьте текущие версии следующих зависимостей в rebar.config.
| {deps, [
%TODO add any additional dependancies here opentelemetry_api, opentelemetry, opentelemetry_exporter ]}. |
2. Добавьте следующие зависимости в ваш файл .app.src в каталоге src.
| {applications, [kernel,
stdlib, opentelemetry_api, opentelemetry, opentelemetry_exporter]} |
3. Добавьте следующую конфигурацию config/sys.config и замените [URL] и [TOKEN] соответствующими значениями для URL-адреса Ключ-АСТРОМ и токена доступа .
| [
{otel_getting_started, []}, {opentelemetry, [{span_processor, batch}, {traces_exporter, otlp}, {resource, [{service, #{name => "erlang-quickstart", version => "1.0.1"} %%TODO Replace with the name and version of your application }] }, {resource_detectors, [ otel_resource_env_var, otel_resource_app_env, extra_metadata ]} ] }, {opentelemetry_exporter, [{otlp_protocol, http_protobuf}, {otlp_traces_endpoint, "[URL]"}, %%TODO Replace [URL] to your SaaS/Managed URL as mentioned in the next step {otlp_headers, [{"Authorization", "Api-Token [TOKEN]"}]} %%TODO Replace [TOKEN] with your API Token as mentioned in the next step ]} ]. |
4. Сохраните следующий код в src/extra_metadata.erl.
| -module(extra_metadata).
-behaviour(otel_resource_detector). -export([get_resource/1]). get_resource(_) -> Metadata = otel_resource:create(otel_resource_app_env:parse(get_metadata("/var/lib/astromkey/enrichment/dt_metadata.properties")), []), {ok, MetadataFilePath} = file:read_file("dt_metadata_e617c525669e072eebe3d0f08212e8f2.properties"), Metadata2 = otel_resource:create(otel_resource_app_env:parse(get_metadata(MetadataFilePath)), []), Metadata3 = otel_resource:create(otel_resource_app_env:parse(get_metadata("/var/lib/astromkey/enrichment/dt_host_metadata.properties")), []), otel_resource:merge(otel_resource:merge(Metadata, Metadata2), Metadata3), otel_resource:merge(Metadata, Metadata2). get_metadata(FileName) -> try {ok, MetadataFile} = file:read_file(FileName), Lines = binary:split(MetadataFile, <<"\n">>, [trim, global]), make_tuples(Lines, []) catch _:_ -> "Metadata not found, safe to continue" end. make_tuples([Line|Lines], Acc) -> [Key, Value] = binary:split(Line, <<"=">>), make_tuples(Lines, [{Key, Value}|Acc]); make_tuples([], Acc) -> Acc. |
Расширение данных Ключ-АСТРОМ
Операции чтения файлов, анализирующие файлы dt_metadata в примере кода, пытаются прочитать файлы данных ЕдиногоАгента, чтобы обогатить запрос OTLP и гарантировать, что вся соответствующая информация о топологии доступна в Ключ-АСТРОМ.
Инструментирование своего приложения
Добавление трассировки
Спектры запускаются с помощью макроса и принимают необязательный список атрибутов, а также блок кода для этого span. Спектры автоматически завершатся после возврата управления из блока кода with_span.
| -export([init/2]).
-include_lib("opentelemetry_api/include/otel_tracer.hrl"). -include_lib("opentelemetry/include/otel_resource.hrl"). init( Req, State ) -> ?with_span(<<"parent_span">>, #{attributes => [ %%TODO Add span name {<<"my-key-1">>, <<"my-value-1">>}] %%TODO Add attributes at span creation }, fun child_function/1), %% Your code goes here child_function(_SpanCtx) -> ?with_span(<<"child_span">>, #{}, fun(_ChildSpanCtx) -> ?set_attributes([{<<"child-key-1">>, <<"child-value-1">>}]) %%TODO Add attributes after span creation end). |
Сбор метрик
Примера пока нет, поскольку OpenTelemetry для Erlang пока не имеет стабильной поддержки метрик.
Подключение логов
Примера пока нет, поскольку OpenTelemetry для Erlang пока не имеет стабильной поддержки логов.
В зависимости от статуса OpenTelemetry SDK предварительная версия может уже разрешать прием ваших логов.
Обеспечение распространения контекста (необязательно)
Распространение контекста особенно важно, когда задействованы сетевые вызовы (например, REST).
Извлечение контекста при получении запроса
Для извлечения информации о существующем контексте мы передаем заголовки функции otel_propagator_text_map.extract, которая анализирует предоставленную заголовками контекстную информацию и устанавливает текущий контекст на ее основе.
| %% Get Headers from incoming request
Headers = maps:get(headers, Req), otel_propagator_text_map:extract(maps:to_list(Headers)), SpanCtx = ?start_span(<<"span-name">>), %% As we used `otel_propagator_text_map` the current context is from the parent span Ctx = otel_ctx:get_current(), proc_lib:spawn_link(fun() -> %% Start span and set as current otel_ctx:attach(Ctx), ?set_current_span(SpanCtx), %% Create response Resp = cowboy_req:reply( 200, #{<<"content-type">> => <<"application/json">>}, <<"{\"message\": \"hello world\"}">>, Req ), {ok, Resp, State}, ?end_span(SpanCtx) |
Внедрение контекста при отправке запросов
В следующем примере мы используем otel_propagator_text_map:inject для предоставления заголовков HTTP (необходимых для распространения контекста) в NewHeaders, которые мы в конечном итоге объединяем с существующим объектом заголовка Headers и передаем в вызов httpc:request, что позволяет принимающей конечной точке продолжить трассировку с предоставленной информацией.
| ?with_span(<<"span-name">>, #{},
fun(_ChildSpanCtx) -> %% A custom header example Headers = [{"content-type", "application/json"}, {"X-Custom-Header", "some-value"}], %% We convert the traceparent information and merge the 2 headers as %% Httpc:request requires tuples of strings Tmp = [], NewHeaders = headers_list(otel_propagator_text_map:inject(opentelemetry:get_text_map_injector(), Tmp)), MergedHeaders = lists:append(Headers, NewHeaders), {ok, Res} = httpc:request(get, {URL, MergedHeaders}, [], []), io:format("Response: ~p~n", [Res]) end). headers_list(Headers) -> [{binary_to_list(Name), binary_to_list(Value)} || {Name, Value} <- Headers]. |
Настройте сбор данных в соответствии с требованиями конфиденциальности (необязательно)
Хотя Ключ-АСТРОМ автоматически собирает все атрибуты OpenTelemetry, в веб-интерфейсе Ключ-АСТРОМ сохраняются и отображаются только значения атрибутов, указанные в списке разрешенных. Это предотвращает случайное сохранение персональных данных, позволяя вам соблюдать требования к конфиденциальности и контролировать объем хранимых данных мониторинга.
Чтобы просматривать пользовательские атрибуты, необходимо сначала разрешить их использование в веб-интерфейсе Ключ-АСТРОМ.
Проверка загрузки данных в Ключ-АСТРОМ
После завершения инструментирования вашего приложения выполните несколько тестовых действий для создания и отправки демонстрационных трассировок, метрик и логов, а также проверьте, что они были правильно загружены в Ключ-АСТРОМ.
Чтобы сделать это для трассировок, перейдите в раздел Трассировки и выберите вкладку Распределенные трассировки. Если вы используете ЕдиныйАгент, выберите PurePaths .
Для просмотра метрик и логов перейдите в раздел Метрики или Логов или Логи и события.