OpenTelemetry
В Deno встроена поддержка OpenTelemetry.
OpenTelemetry — это набор API, SDK и инструментов. Используйте его для инструментирования, генерации, сбора и экспорта телеметрических данных (метрик, журналов и трассировок), чтобы анализировать производительность и поведение программного обеспечения.
Эта интеграция позволяет отслеживать приложения Deno с помощью инструментов наблюдаемости OpenTelemetry, используя такие инструменты, как журналы, метрики и трассировки.
Deno предоставляет следующие возможности:
- Экспорт собранных метрик, трассировок и журналов на сервер с использованием протокола OpenTelemetry.
- Автоматическое инструментирование среды выполнения Deno с помощью метрик, трассировок и журналов OpenTelemetry.
-
Сбор метрик, трассировок и журналов, определяемых пользователем, созданных с помощью пакета
npm:@opentelemetry/api.
Быстрый старт
Чтобы включить интеграцию OpenTelemetry, задайте переменную среды OTEL_DENO=true:
OTEL_DENO=true deno run my_script.ts
Это автоматически соберёт и экспортирует данные наблюдаемости среды выполнения в конечную точку OpenTelemetry по адресу localhost:4318, используя Protobuf поверх HTTP (http/protobuf).
Если вы хотите быстро посмотреть вывод OpenTelemetry, не настраивая сборщик, можно воспользоваться встроенным экспортёром консоли, который выводит спаны, журналы и метрики непосредственно в stderr в удобочитаемом формате:
OTEL_DENO=true OTEL_EXPORTER_OTLP_PROTOCOL=console deno run my_script.ts
Пример вывода:
SPAN inner span [00000000000000000000000000000001/0000000000000002] Internal 0.495ms
parent: 0000000000000001
scope: example-tracer
key: value
LOG [INFO] 2025-03-14T13:47:07.235Z "hello from inner"
scope: deno@2.7.5
trace: 00000000000000000000000000000001/0000000000000002
Если вы хотите визуализировать телеметрические данные на панели мониторинга, можно начать с локального стека LGTM в Docker (Loki (журналы), Grafana (панель мониторинга), Tempo (трассировки) и Prometheus (метрики)), выполнив следующую команду:
docker run --name lgtm -p 3000:3000 -p 4317:4317 -p 4318:4318 --rm -ti \
-v "$PWD"/lgtm/grafana:/data/grafana \
-v "$PWD"/lgtm/prometheus:/data/prometheus \
-v "$PWD"/lgtm/loki:/data/loki \
-e GF_PATHS_DATA=/data/grafana \
docker.io/grafana/otel-lgtm:0.8.1
Затем можно открыть панель мониторинга Grafana по адресу http://localhost:3000, используя имя пользователя admin и пароль admin.
При этом будут автоматически собираться и экспортироваться данные наблюдаемости среды выполнения, такие как console.log, трассировки HTTP-запросов и метрики среды выполнения Deno. Подробнее об автоматическом инструментировании.
Также можно создавать собственные метрики, трассировки и журналы с помощью пакета npm:@opentelemetry/api. Подробнее о метриках, определяемых пользователем.
Автоматическое инструментирование
Deno автоматически собирает и экспортирует некоторые данные наблюдаемости в конечную точку OTLP.
Эти данные экспортируются в области встроенного инструментирования среды выполнения Deno. Эта область имеет имя deno. Версия среды выполнения Deno является версией области инструментирования deno (например, deno:2.1.4).
Трассировки
Deno автоматически создаёт спаны для различных операций, например:
- Входящие HTTP-запросы, обработанные с помощью
Deno.serve. - Исходящие HTTP-запросы, выполненные с помощью
fetch. - Трафик HTTP/2 через
node:http2— как клиентские запросы, так и входящие запросы к серверу, с передачей контекста трассировки между службами (добавлено в Deno 2.9). -
Deno.cron()— вызовы заданий (добавлено в Deno 2.7).
Deno.serve
При использовании Deno.serve для создания HTTP-сервера для каждого входящего запроса создаётся спан. Спан автоматически завершается после отправки заголовков ответа (а не после завершения отправки тела ответа).
Имя созданного спана — ${method}. Тип спана — server.
При создании спана к нему автоматически добавляются следующие атрибуты:
-
http.request.method: HTTP-метод запроса. -
url.full: полный URL запроса (как его вернул быreq.url). -
url.scheme: схема URL запроса (например,httpилиhttps). -
url.path: путь URL запроса. -
url.query: строка запроса URL.
После обработки запроса добавляются следующие атрибуты:
-
http.response.status_code: код состояния ответа.
Deno не добавляет к спану атрибут http.route автоматически, поскольку среде выполнения неизвестен маршрут: он определяется логикой маршрутизации в функции обработчика пользователя. Чтобы добавить к спану атрибут http.route, это можно сделать в функции обработчика с помощью npm:@opentelemetry/api. В этом случае следует также обновить имя спана, включив в него маршрут.
import { trace } from "npm:@opentelemetry/api@1";
const INDEX_ROUTE = new URLPattern({ pathname: "/" });
const BOOK_ROUTE = new URLPattern({ pathname: "/book/:id" });
Deno.serve(async (req) => {
const span = trace.getActiveSpan();
if (INDEX_ROUTE.test(req.url)) {
span.setAttribute("http.route", "/");
span.updateName(`${req.method} /`);
// handle index route
} else if (BOOK_ROUTE.test(req.url)) {
span.setAttribute("http.route", "/book/:id");
span.updateName(`${req.method} /book/:id`);
// handle book route
} else {
return new Response("Not found", { status: 404 });
}
});
fetch
При использовании fetch для выполнения HTTP-запроса для него создаётся спан. Спан автоматически завершается после получения заголовков ответа.
Имя созданного спана — ${method}. Тип спана — client.
При создании спана к нему автоматически добавляются следующие атрибуты:
-
http.request.method: HTTP-метод запроса. -
url.full: полный URL запроса. -
url.scheme: схема URL запроса. -
url.path: путь URL запроса. -
url.query: строка запроса URL.
После получения ответа добавляются следующие атрибуты:
-
http.status_code: код состояния ответа.
Метрики
Автоматически собираются и экспортируются следующие метрики:
Deno.serve / Deno.serveHttp
http.server.request.duration
Гистограмма длительности входящих HTTP-запросов, обработанных с помощью Deno.serve или Deno.serveHttp. Измеряется время от получения запроса до отправки заголовков ответа. Время отправки тела ответа не учитывается. Единица измерения этой метрики — секунды. Границы сегментов гистограммы: [0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0].
Эта метрика записывается со следующими атрибутами:
-
http.request.method: HTTP-метод запроса. -
url.scheme: схема URL запроса. -
network.protocol.version: версия протокола HTTP, использованного для запроса (например,1.1или2). -
server.address: адрес, на котором прослушивает сервер. -
server.port: порт, на котором прослушивает сервер. -
http.response.status_code: код состояния ответа (если запрос обработан без критической ошибки). -
error.type: тип произошедшей ошибки (если при обработке запроса возникла ошибка).
http.server.active_requests
Показатель количества активных запросов, обрабатываемых Deno.serve или Deno.serveHttp в каждый момент времени. Это количество полученных запросов, на которые ещё не отправлен ответ (заголовки ответа ещё не отправлены). Эта метрика записывается со следующими атрибутами:
-
http.request.method: HTTP-метод запроса. -
url.scheme: схема URL запроса. -
server.address: адрес, на котором прослушивает сервер. -
server.port: порт, на котором прослушивает сервер.
http.server.request.body.size
Гистограмма размера тела входящих HTTP-запросов, обработанных с помощью Deno.serve или Deno.serveHttp. Единица измерения этой метрики — байты. Границы сегментов гистограммы: [0, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000].
Эта метрика записывается со следующими атрибутами:
-
http.request.method: HTTP-метод запроса. -
url.scheme: схема URL запроса. -
network.protocol.version: версия протокола HTTP, использованного для запроса (например,1.1или2). -
server.address: адрес, на котором прослушивает сервер. -
server.port: порт, на котором прослушивает сервер. -
http.response.status_code: код состояния ответа (если запрос обработан без критической ошибки). -
error.type: тип произошедшей ошибки (если при обработке запроса возникла ошибка).
http.server.response.body.size
Гистограмма размера тела ответов на входящие HTTP-запросы, обработанные с помощью Deno.serve или Deno.serveHttp. Единица измерения этой метрики — байты. Границы сегментов гистограммы: [0, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000].
Эта метрика записывается со следующими атрибутами:
-
http.request.method: HTTP-метод запроса. -
url.scheme: схема URL запроса. -
network.protocol.version: версия протокола HTTP, использованного для запроса (например,1.1или2). -
server.address: адрес, на котором прослушивает сервер. -
server.port: порт, на котором прослушивает сервер. -
http.response.status_code: код состояния ответа (если запрос обработан без критической ошибки). -
error.type: тип произошедшей ошибки (если при обработке запроса возникла ошибка).
Журналы
Автоматически собираются и экспортируются следующие журналы:
- Все журналы, созданные методами
console.*, напримерconsole.logиconsole.error. - Все журналы, созданные средой выполнения Deno, например журналы отладки, журналы
Downloadingи другие подобные. - Все ошибки, приводящие к завершению работы среды выполнения Deno (как из пользовательского кода, так и из самой среды выполнения).
Журналы, созданные кодом JavaScript, экспортируются с соответствующим контекстом спана, если запись журнала произошла внутри активного спана.
Автоматическое инструментирование console можно настроить с помощью переменной среды OTEL_DENO_CONSOLE:
-
capture: журналы выводятся в stdout/stderr, а также экспортируются с помощью OpenTelemetry (по умолчанию). -
replace: журналы экспортируются только с помощью OpenTelemetry и не выводятся в stdout/stderr. -
ignore: журналы выводятся только в stdout/stderr и не экспортируются с помощью OpenTelemetry.
Аудит разрешений
Deno может направлять журнал аудита разрешений в экспортёр OpenTelemetry вместе с остальными трассировками, метриками и журналами. Задайте DENO_AUDIT_PERMISSIONS=otel (вместо пути к файлу), и каждое обращение к разрешению — разрешённое или запрещённое — будет выдаваться в виде записи журнала OpenTelemetry со следующими атрибутами:
-
deno.permission.type— имя разрешения (read,net,env, …). -
deno.permission.value— конкретное проверяемое значение (путь, хост, имя переменной и т. д.). -
deno.permission.stack— кадры стека JavaScript в месте обращения; присутствуют только если задано такжеDENO_TRACE_PERMISSIONS.
OTEL_DENO=true DENO_AUDIT_PERMISSIONS=otel deno run -A main.ts
Это полезно, если вы уже собираете данные OpenTelemetry: аудит попадает в то же хранилище, что и трассировки запросов, поэтому можно сопоставить запрос с обращением к разрешению, которое он вызвал. Полный набор атрибутов и режим указания пути к файлу JSONL см. в разделе аудит разрешений.
Пользовательские метрики
Помимо автоматически собираемых телеметрических данных, вы также можете создавать собственные метрики и трассировки с помощью пакета npm:@opentelemetry/api.
Для использования пакета npm:@opentelemetry/api в Deno его не нужно настраивать. Deno автоматически настраивает пакет npm:@opentelemetry/api. Вызывать metrics.setGlobalMeterProvider(), trace.setGlobalTracerProvider() или context.setGlobalContextManager() не нужно. Вся конфигурация ресурсов, настроек экспортёра и т. д. задаётся с помощью переменных среды.
Deno работает с версией 1.x пакета npm:@opentelemetry/api. Можно импортировать напрямую из npm:@opentelemetry/api@1 или установить пакет локально с помощью deno add и импортировать из @opentelemetry/api.
deno add npm:@opentelemetry/api@1
Для трассировок и метрик нужно задать имя для трейсера и метра соответственно. При инструментировании библиотеки следует указать в качестве имени трейсера или метра имя библиотеки (например, my-awesome-lib). При инструментировании приложения следует указать имя приложения (например, my-app). В качестве версии трейсера или метра следует указать версию библиотеки или приложения.
Трассировки
Чтобы создать новый спан, сначала импортируйте объект trace из npm:@opentelemetry/api и создайте новый трейсер:
import { trace } from "npm:@opentelemetry/api@1";
const tracer = trace.getTracer("my-app", "1.0.0");
Затем создайте спан с помощью метода tracer.startActiveSpan и передайте ему функцию обратного вызова. Спан необходимо завершить вручную, вызвав метод end у объекта спана, возвращённого методом startActiveSpan.
function myFunction() {
return tracer.startActiveSpan("myFunction", (span) => {
try {
// do myFunction's work
} catch (error) {
span.recordException(error);
span.setStatus({
code: trace.SpanStatusCode.ERROR,
message: (error as Error).message,
});
throw error;
} finally {
span.end();
}
});
}
Метод span.end() следует вызывать в блоке finally, чтобы спан завершился даже в случае ошибки. span.recordException и span.setStatus также следует вызывать в блоке catch, чтобы записать все произошедшие ошибки.
Внутри функции обратного вызова созданный спан является «активным спаном». Получить активный спан можно с помощью trace.getActiveSpan(). «Активный спан» будет использоваться в качестве родительского для любых спанов, созданных внутри функции обратного вызова (вручную или автоматически средой выполнения), а также внутри любых функций, вызванных из неё. Подробнее о передаче контекста.
Метод startActiveSpan возвращает значение, возвращённое функцией обратного вызова.
В течение жизненного цикла спана к нему можно добавлять атрибуты. Атрибуты — это пары «ключ — значение», представляющие структурированные метаданные о спане. Их можно добавлять с помощью методов setAttribute и setAttributes объекта спана.
span.setAttribute("key", "value");
span.setAttributes({ success: true, "bar.count": 42n, "foo.duration": 123.45 });
Значениями атрибутов могут быть строки, числа (с плавающей точкой), bigints (ограниченные диапазоном u64), логические значения или массивы значений этих типов. Значение атрибута, не принадлежащее ни к одному из этих типов, будет проигнорировано.
Имя спана можно изменить с помощью метода updateName объекта спана.
span.updateName("new name");
Статус спана можно задать с помощью метода setStatus объекта спана. Метод recordException можно использовать для записи исключения, возникшего в течение жизненного цикла спана. recordException создаёт событие с трассировкой стека и именем исключения и прикрепляет его к спану. recordException не задаёт статус спана как ERROR — это необходимо сделать вручную.
import { SpanStatusCode } from "npm:@opentelemetry/api@1";
span.setStatus({
code: SpanStatusCode.ERROR,
message: "An error occurred",
});
span.recordException(new Error("An error occurred"));
// or
span.setStatus({
code: SpanStatusCode.OK,
});
К спанам также можно добавлять события и ссылки. События — это моменты времени, связанные со спаном. Ссылки — это ссылки на другие спаны.
// Add an event to the span
span.addEvent("button_clicked", {
id: "submit-button",
action: "submit",
});
// Add an event with a timestamp
span.addEvent("process_completed", { status: "success" }, Date.now());
События могут содержать необязательные атрибуты, как и спаны. Они позволяют отмечать важные моменты в течение жизненного цикла спана, не создавая отдельные спаны.
Спаны также можно создавать вручную с помощью tracer.startSpan, который возвращает объект спана. Этот метод не задаёт созданный спан как активный, поэтому он не будет автоматически использоваться как родительский для последующих спанов или вызовов console.log. Спан можно вручную задать активным для функции обратного вызова с помощью API передачи контекста.
Методам tracer.startActiveSpan и tracer.startSpan можно передать необязательный объект параметров со следующими свойствами:
-
kind: тип спана. Может бытьSpanKind.CLIENT,SpanKind.SERVER,SpanKind.PRODUCER,SpanKind.CONSUMERилиSpanKind.INTERNAL. По умолчанию —SpanKind.INTERNAL. -
startTime: объектDate, представляющий время начала спана, либо число, представляющее время начала в миллисекундах с начала эпохи Unix. Если значение не задано, используется текущее время. -
attributes: объект с атрибутами, которые нужно добавить к спану. -
links: массив ссылок, которые нужно добавить к спану. -
root: логическое значение, указывающее, должен ли спан быть корневым. Если значение равноtrue, у спана не будет родительского спана (даже если есть активный спан).
После объекта параметров методам tracer.startActiveSpan и tracer.startSpan также можно передать объект context из API передачи контекста.
Подробнее о полном API трассировок см. в документации по API OpenTelemetry JS.
Метрики
Чтобы создать метрику, сначала импортируйте объект metrics из npm:@opentelemetry/api и создайте новый метр:
import { metrics } from "npm:@opentelemetry/api@1";
const meter = metrics.getMeter("my-app", "1.0.0");
Затем можно создать инструмент на основе метра и использовать его для записи значений:
const counter = meter.createCounter("my_counter", {
description: "A simple counter",
unit: "1",
});
counter.add(1);
counter.add(2);
Для каждой записи также можно указать связанные с ней атрибуты:
counter.add(1, { color: "red" });
counter.add(2, { color: "blue" });
В OpenTelemetry атрибуты метрик обычно должны иметь низкую кардинальность. Это означает, что уникальных сочетаний значений атрибутов не должно быть слишком много. Например, атрибут, указывающий континент проживания пользователя, скорее всего, вполне допустим, а атрибут с точными широтой и долготой пользователя будет иметь слишком высокую кардинальность. Атрибуты с высокой кардинальностью могут создавать проблемы при хранении и экспорте метрик, поэтому их следует избегать. Для данных с высокой кардинальностью используйте спаны и журналы.
С помощью метра можно создать несколько типов инструментов:
-
Counter: счётчик — это монотонно возрастающее значение. Значения счётчика могут быть только положительными. Его можно использовать для величин, которые постоянно растут, например для количества обработанных запросов.
-
UpDownCounter: восходящий-нисходящий счётчик — это значение, которое может как увеличиваться, так и уменьшаться. Его можно использовать для величин, которые способны как увеличиваться, так и уменьшаться, например для числа активных подключений или запросов в обработке.
-
Gauge: датчик — это значение, которому можно присвоить любое значение. Он используется для величин, которые не «накапливаются» со временем, а имеют определённое значение в любой момент, например для текущей температуры.
-
Histogram: гистограмма — это значение, записываемое как распределение. Гистограммы можно использовать для значений, которые представляют собой не одно число, а распределение чисел, например для времени ответа на запрос в миллисекундах. С их помощью можно вычислять перцентили, средние значения и другие статистические показатели. Для гистограмм заранее задан набор границ, определяющих сегменты, в которые попадают значения. По умолчанию границы:
[0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0].
Существует также несколько типов наблюдаемых инструментов. У этих инструментов нет синхронного метода записи; вместо этого они возвращают функцию обратного вызова, которую можно вызвать для записи значения. Функция обратного вызова вызывается, когда SDK OpenTelemetry готов записать значение, например непосредственно перед экспортом.
const counter = meter.createObservableCounter("my_counter", {
description: "A simple counter",
unit: "1",
});
counter.addCallback((res) => {
res.observe(1);
// or
res.observe(1, { color: "red" });
});
Существует три типа наблюдаемых инструментов:
- ObservableCounter: наблюдаемый счётчик — это счётчик, который можно наблюдать асинхронно. Его можно использовать для величин, которые постоянно растут, например для количества обработанных запросов.
- ObservableUpDownCounter: наблюдаемый восходящий-нисходящий счётчик — это значение, которое может как увеличиваться, так и уменьшаться и которое можно наблюдать асинхронно. Его можно использовать для величин, которые способны как увеличиваться, так и уменьшаться, например для числа активных подключений или запросов в обработке.
- ObservableGauge: наблюдаемый датчик — это значение, которому можно присвоить любое значение и которое можно наблюдать асинхронно. Он используется для величин, которые не «накапливаются» со временем, а имеют определённое значение в любой момент, например для текущей температуры.
Подробнее о полном API метрик см. в документации по API OpenTelemetry JS.
Практические примеры
Практические примеры реализации OpenTelemetry в приложениях Deno см. в наших руководствах:
- Основное руководство по OpenTelemetry — простой HTTP-сервер с пользовательскими метриками и трассировками
- Руководство по распределённой трассировке — расширенные методы трассировки на границах служб
Передача контекста
В OpenTelemetry передача контекста — это процесс передачи некоторой контекстной информации (например, текущего спана) из одной части приложения в другую без необходимости явно передавать её в качестве аргумента каждой функции.
В Deno передача контекста выполняется в соответствии с правилами AsyncContext — предложения TC39 по передаче асинхронного контекста. API AsyncContext пока недоступен пользователям Deno, но используется внутри системы для передачи активного спана и другой контекстной информации через асинхронные границы.
Краткий обзор работы передачи контекста AsyncContext:
- При запуске новой асинхронной задачи (например, промиса или таймера) сохраняется текущий контекст.
- Затем другой код может выполняться параллельно с асинхронной задачей в другом контексте.
- После завершения асинхронной задачи сохранённый контекст восстанавливается.
Таким образом, передача асинхронного контекста по сути ведёт себя как глобальная переменная, область видимости которой ограничена текущей асинхронной задачей и которая автоматически копируется во все новые асинхронные задачи, запущенные из текущей задачи.
API context из npm:@opentelemetry/api@1 предоставляет эту функциональность пользователям. Он работает следующим образом:
import { context } from "npm:@opentelemetry/api@1";
// Get the currently active context
const currentContext = context.active();
// You can add create a new context with a value added to it
const newContext = currentContext.setValue("id", 1);
// The current context is not changed by calling setValue
console.log(currentContext.getValue("id")); // undefined
// You can run a function inside a new context
context.with(newContext, () => {
// Any code in this block will run with the new context
console.log(context.active().getValue("id")); // 1
// The context is also available in any functions called from this block
function myFunction() {
return context.active().getValue("id");
}
console.log(myFunction()); // 1
// And it is also available in any asynchronous callbacks scheduled from here
setTimeout(() => {
console.log(context.active().getValue("id")); // 1
}, 10);
});
// Outside, the context is still the same
console.log(context.active().getValue("id")); // undefined
API контекста также интегрируется со спанами. Например, чтобы выполнить функцию в контексте определённого спана, можно добавить спан в контекст, а затем запустить функцию в этом контексте:
import { context, trace } from "npm:@opentelemetry/api@1";
const tracer = trace.getTracer("my-app", "1.0.0");
const span = tracer.startSpan("myFunction");
const contextWithSpan = trace.setSpan(context.active(), span);
context.with(contextWithSpan, () => {
const activeSpan = trace.getActiveSpan();
console.log(activeSpan === span); // true
});
// Don't forget to end the span!
span.end();
Подробнее о полном API контекста см. в документации по API OpenTelemetry JS.
Конфигурация
Интеграцию OpenTelemetry можно включить, задав переменную среды OTEL_DENO=true.
Конечную точку и протокол экспортёра OTLP можно настроить с помощью переменных среды OTEL_EXPORTER_OTLP_ENDPOINT и OTEL_EXPORTER_OTLP_PROTOCOL. Поддерживаются следующие значения OTEL_EXPORTER_OTLP_PROTOCOL:
-
http/protobuf(по умолчанию): экспорт с использованием Protobuf поверх HTTP на настроенную конечную точку. -
http/json: экспорт с использованием JSON поверх HTTP на настроенную конечную точку. -
grpc: экспорт с использованием gRPC (Protobuf поверх HTTP/2). Доступно в Deno 2.8 и новее. Полезно для сборщиков, которые принимают только gRPC, например для управляемого агента OpenTelemetry в Azure Container Apps. По умолчанию порт gRPC OTLP —4317, поэтому обычно также задаютOTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317. -
console: вывод спанов, журналов и метрик в stderr в удобочитаемом текстовом формате. Это полезно для отладки и тестирования инструментирования без запуска сборщика OTLP. При использованииconsoleнастройка конечной точки не требуется.
Если для конечной точки требуется аутентификация, заголовки можно настроить с помощью переменной среды OTEL_EXPORTER_OTLP_HEADERS.
Конечную точку также можно переопределить отдельно для метрик, трассировок и журналов с помощью специальных переменных среды, например:
OTEL_EXPORTER_OTLP_METRICS_ENDPOINTOTEL_EXPORTER_OTLP_TRACES_ENDPOINTOTEL_EXPORTER_OTLP_LOGS_ENDPOINT
Подробнее о заголовках, которые можно использовать для настройки экспортёра OTLP, см. на сайте OpenTelemetry.
Ресурс, связанный с телеметрическими данными, можно настроить с помощью переменных среды OTEL_SERVICE_NAME и OTEL_RESOURCE_ATTRIBUTES. Помимо атрибутов, заданных с помощью переменной среды OTEL_RESOURCE_ATTRIBUTES, автоматически задаются следующие атрибуты:
-
service.name: еслиOTEL_SERVICE_NAMEне задано, используется значение<unknown_service>. -
process.runtime.name:deno -
process.runtime.version: версия среды выполнения Deno. -
telemetry.sdk.name:deno-opentelemetry -
telemetry.sdk.language:deno-rust -
telemetry.sdk.version: версия среды выполнения Deno и версия используемого Deno крейта Rustopentelemetry, разделённые символом-.
Пропагаторы можно настроить с помощью переменной среды OTEL_PROPAGATORS. Значение по умолчанию — tracecontext,baggage. Можно указать несколько пропагаторов, разделив их запятыми. В настоящее время поддерживаются следующие пропагаторы:
-
tracecontext: формат передачи контекста трассировки W3C -
baggage: формат передачи Baggage W3C
Сэмплирование трассировок можно настроить с помощью переменной среды OTEL_TRACES_SAMPLER. Поддерживаются следующие значения:
-
always_on(по умолчанию): сэмплировать каждую трассировку. -
always_off: не сэмплировать трассировки. -
traceidratio: сэмплировать долю трассировок на основе идентификатора трассировки. -
parentbased_always_on,parentbased_always_off,parentbased_traceidratio: учитывать решение родительского спана о сэмплировании, если он есть, а в противном случае использовать соответствующий корневой сэмплер.
Для сэмплеров, основанных на коэффициенте, OTEL_TRACES_SAMPLER_ARG задаёт вероятность сэмплирования числом от 0 до 1. По умолчанию используется 1.0:
OTEL_DENO=true OTEL_TRACES_SAMPLER=traceidratio OTEL_TRACES_SAMPLER_ARG=0.1 deno run -A main.ts
Частоту сбора метрик можно настроить с помощью переменной среды OTEL_METRIC_EXPORT_INTERVAL. Значение по умолчанию — 60000 миллисекунд (60 секунд).
Пакетную обработку спанов экспортёром можно настроить с помощью переменных среды пакетного процессора спанов, описанных в спецификации OpenTelemetry.
Пакетную обработку экспортера журналов можно настроить с помощью переменных среды для процессора пакетной обработки записей журналов, описанных в спецификации OpenTelemetry.
Распространители контекста
Deno поддерживает распространители контекста, которые обеспечивают автоматическую передачу контекста трассировки через границы процессов для распределенной трассировки и позволяют отслеживать запросы при их прохождении через различные службы.
Распространители контекста отвечают за кодирование и декодирование информации о контексте (например, идентификаторов трассировок и спанов) при преобразовании в формат переносчика и обратно (например, заголовки HTTP). Это позволяет сохранять контекст трассировки при пересечении границ служб.
По умолчанию Deno поддерживает следующие распространители контекста:
-
tracecontext: формат распространения контекста трассировки W3C — стандартный способ передавать контекст трассировки через заголовки HTTP. -
baggage: формат распространения данных W3C Baggage, позволяющий передавать пары «ключ-значение» между службами.
Эти распространители контекста автоматически работают с API fetch и Deno.serve в Deno, обеспечивая сквозную трассировку HTTP-запросов без ручного управления контекстом.
Доступ к API распространения контекста можно получить через пакет @opentelemetry/api:
import { context, propagation, trace } from "npm:@opentelemetry/api@1";
// Extract context from incoming headers
function extractContextFromHeaders(headers: Headers) {
const ctx = context.active();
return propagation.extract(ctx, headers);
}
// Inject context into outgoing headers
function injectContextIntoHeaders(headers: Headers) {
const ctx = context.active();
propagation.inject(ctx, headers);
return headers;
}
// Example: Making a fetch request that propagates trace context
async function tracedFetch(url: string) {
const headers = new Headers();
injectContextIntoHeaders(headers);
return await fetch(url, { headers });
}
Ограничения
Интеграция OpenTelemetry для Deno находится в разработке, поэтому следует учитывать следующие ограничения:
- Трассировки поддерживают только связи без атрибутов.
- Примеры метрик не поддерживаются.
- Пользовательские потоки журналов (например, журналы, отличные от
console.logиconsole.error) не поддерживаются. - Поддерживаются экспортеры OTLP (
http/protobuf,http/json,grpc) иconsole. Другие форматы экспортеров не поддерживаются. - Метрики наблюдаемых (асинхронных) измерителей не собираются при завершении или аварийном завершении процесса, поэтому последнее значение метрик может не экспортироваться. Синхронные метрики экспортируются при завершении или аварийном завершении процесса.
- Ограничения, заданные в переменных среды
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT,OTEL_SPAN_LINK_COUNT_LIMIT,OTEL_EVENT_ATTRIBUTE_COUNT_LIMITиOTEL_LINK_ATTRIBUTE_COUNT_LIMIT, не применяются к спанам трассировок. Применяются ограничение на количество атрибутов одного спана (OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, при отсутствии значения используетсяOTEL_ATTRIBUTE_COUNT_LIMIT) и ограничение на количество событий одного спана (OTEL_SPAN_EVENT_COUNT_LIMIT); значение каждого по умолчанию — 128. - Переменная среды
OTEL_METRIC_EXPORT_TIMEOUTне учитывается. - Неизвестные методы HTTP не нормализуются до
_OTHERв атрибуте спанаhttp.request.method, как того требуют семантические соглашения OpenTelemetry. - Для серверного спана HTTP, создаваемого
Deno.serve, статус OpenTelemetry не устанавливается. Если обработчик выбрасывает исключение (то есть вызываетсяonError), для спана не устанавливается статус ошибки, а сама ошибка не добавляется к спану в виде события. - Нет механизма для добавления атрибута
http.routeк спану HTTP-клиента дляfetchили для обновления имени спана, чтобы включить в него маршрут.
Последнее обновление:
© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/runtime/fundamentals/open_telemetry