On this page
在 Deno 中入门 OpenTelemetry
OpenTelemetry 为您的应用提供强大的可观察性工具。借助 Deno 内置的 OpenTelemetry 支持,您可以轻松地对代码进行监测,收集指标、跟踪和日志。
本教程将指导您如何设置一个带有 OpenTelemetry 监测的简单 Deno 应用。
前提条件 Jump to heading
- Deno 2.3 或更高版本
第一步:创建一个简单的 HTTP 服务器 Jump to heading
让我们开始创建一个基础的 HTTP 服务器,模拟一个小型的网页应用:
import { metrics, trace } from "npm:@opentelemetry/api@1";
// 为我们的应用创建 tracer 和 meter
const tracer = trace.getTracer("my-server", "1.0.0");
const meter = metrics.getMeter("my-server", "1.0.0");
// 创建一些指标
const requestCounter = meter.createCounter("http_requests_total", {
description: "HTTP 请求总数",
});
const requestDuration = meter.createHistogram("http_request_duration_ms", {
description: "HTTP 请求持续时间(毫秒)",
unit: "ms",
});
// 启动服务器
Deno.serve({ port: 8000 }, (req) => {
// 记录请求开始时间,以测量请求持续时间
const startTime = performance.now();
// 为该请求创建一个 span
return tracer.startActiveSpan("handle_request", async (span) => {
try {
// 从 URL 中提取路径
const url = new URL(req.url);
const path = url.pathname;
// 为 span 添加属性
span.setAttribute("http.route", path);
span.setAttribute("http.method", req.method);
span.updateName(`${req.method} ${path}`);
// 为 span 添加事件
span.addEvent("request_started", {
timestamp: startTime,
request_path: path,
});
// 模拟一些处理时间
const waitTime = Math.random() * 100;
await new Promise((resolve) => setTimeout(resolve, waitTime));
// 为 span 添加另一个事件
span.addEvent("processing_completed");
// 创建响应
const response = new Response(`Hello from ${path}!`, {
headers: { "Content-Type": "text/plain" },
});
// 记录指标
requestCounter.add(1, {
method: req.method,
path,
status: 200,
});
const duration = performance.now() - startTime;
requestDuration.record(duration, {
method: req.method,
path,
});
span.setAttribute("request.duration_ms", duration);
return response;
} catch (error) {
// 在 span 中记录错误
if (error instanceof Error) {
span.recordException(error);
span.setStatus({
code: trace.SpanStatusCode.ERROR,
message: error.message,
});
}
return new Response("内部服务器错误", { status: 500 });
} finally {
// 始终结束 span
span.end();
}
});
});
该服务器功能:
- 为应用创建 tracer 和 meter
- 设置指标以统计请求数量并测量请求持续时间
- 为每个请求创建带有属性和事件的 span
- 模拟处理时间
- 记录每个请求的指标
第二步:启用 OpenTelemetry 并运行服务器 Jump to heading
使用以下命令行标志运行服务器以启用 OpenTelemetry:
OTEL_DENO=true OTEL_SERVICE_NAME=my-server deno run --allow-net server.ts
第三步:创建测试客户端 Jump to heading
让我们创建一个简单客户端,向服务器发送请求:
// 向不同路径发送 10 个请求
for (let i = 0; i < 10; i++) {
const path = ["", "about", "users", "products", "contact"][i % 5];
const url = `http://localhost:8000/${path}`;
console.log(`正在向 ${url} 发送请求`);
try {
const response = await fetch(url);
const text = await response.text();
console.log(`来自 ${url} 的响应:${text}`);
} catch (error) {
console.error(`获取 ${url} 时出错:`, error);
}
}
第四步:运行客户端 Jump to heading
在另一个终端中运行客户端:
deno run --allow-net client.ts
第五步:查看遥测数据 Jump to heading
默认情况下,Deno 会使用 OTLP 协议将遥测数据导出到 http://localhost:4318。您需要一个 OpenTelemetry collector 来接收并可视化这些数据。
安装本地 Collector Jump to heading
最快速的方式是使用 Docker 运行本地 LGTM 堆栈(Loki, Grafana, Tempo, Mimir):
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
然后访问 http://localhost:3000 登录 Grafana(用户名:admin,密码:admin)。
在 Grafana 中,您可以:
- 在 Tempo 中查看 Traces(跟踪),查看每个请求的 span
- 在 Mimir/Prometheus 中查看 Metrics(指标),查看请求计数和持续时间
- 在 Loki 中查看 Logs(日志),查看应用的任何日志
理解你所看到的内容 Jump to heading
跟踪(Traces) Jump to heading
在 Traces 视图中,您将看到:
- 服务器处理的每个 HTTP 请求的 span
- 客户端发出的每个 fetch 请求的 span
- 这些 span 之间的关联关系
点击任一 span 可查看详细信息,包括:
- 持续时间
- 属性(如 http.route、http.method 等)
- 事件(request_started、processing_completed)
指标(Metrics) Jump to heading
在 Metrics 视图中,您可以查询:
http_requests_total— 统计 HTTP 请求数量的计数器http_request_duration_ms— 请求持续时间的直方图
您还可以看到内置的 Deno 指标,如:
http.server.request.durationhttp.server.active_requests
日志(Logs) Jump to heading
在 Logs 视图中,您将看到应用程序的所有控制台日志,且带有正确的跟踪上下文。
故障排除 Jump to heading
如果您在 Collector 中看不到数据:
- 检查是否设置了
OTEL_DENO=true - 确认 Collector 正在运行且在默认端点可访问
- 检查是否需要将
OTEL_EXPORTER_OTLP_ENDPOINT设置为其他 URL - 查看 Deno 控制台输出中是否有错误信息
请记住,Deno 中的 OpenTelemetry 支持仍处于不稳定阶段,未来版本可能会有所变动。
🦕 本教程为希望在 Deno 中尝试 OpenTelemetry 的用户提供了一个简单的起点,无需立即深入复杂概念。
此基础示例可以通过多种方式扩展:
- 为业务逻辑添加更多自定义指标
- 为重要操作创建额外的 span
- 使用 baggage 在服务间传递上下文属性
- 基于指标阈值设置告警
欲了解更高级的用法,请参阅我们的 分布式跟踪与上下文传播 教程。