本页内容
Deno 中 OpenTelemetry 入门
OpenTelemetry 为您的应用程序提供了强大的可观测性工具。借助 Deno 内置的 OpenTelemetry 支持,您可以轻松地对代码进行插桩,以收集指标、追踪和日志。
本教程将引导您设置一个带有 OpenTelemetry 插桩的简单 Deno 应用程序。
先决条件 Jump to heading
- Deno 2.3 或更高版本
步骤 1:创建一个简单的 HTTP 服务器 Jump to heading
我们首先创建一个模拟小型 Web 应用程序的基本 HTTP 服务器
server.ts
import { metrics, trace } from "npm:@opentelemetry/api@1";
// Create a tracer and meter for our application
const tracer = trace.getTracer("my-server", "1.0.0");
const meter = metrics.getMeter("my-server", "1.0.0");
// Create some metrics
const requestCounter = meter.createCounter("http_requests_total", {
description: "Total number of HTTP requests",
});
const requestDuration = meter.createHistogram("http_request_duration_ms", {
description: "HTTP request duration in milliseconds",
unit: "ms",
});
// Start the server
Deno.serve({ port: 8000 }, (req) => {
// Record the start time for measuring request duration
const startTime = performance.now();
// Create a span for this request
return tracer.startActiveSpan("handle_request", async (span) => {
try {
// Extract the path from the URL
const url = new URL(req.url);
const path = url.pathname;
// Add attributes to the span
span.setAttribute("http.route", path);
span.setAttribute("http.method", req.method);
span.updateName(`${req.method} ${path}`);
// Add an event to the span
span.addEvent("request_started", {
timestamp: startTime,
request_path: path,
});
// Simulate some processing time
const waitTime = Math.random() * 100;
await new Promise((resolve) => setTimeout(resolve, waitTime));
// Add another event to the span
span.addEvent("processing_completed");
// Create the response
const response = new Response(`Hello from ${path}!`, {
headers: { "Content-Type": "text/plain" },
});
// Record metrics
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) {
// Record error in span
if (error instanceof Error) {
span.recordException(error);
span.setStatus({
code: trace.SpanStatusCode.ERROR,
message: error.message,
});
}
return new Response("Internal Server Error", { status: 500 });
} finally {
// Always end the span
span.end();
}
});
});
该服务器
- 为我们的应用程序创建追踪器和计量器
- 设置指标以统计请求并测量其持续时间
- 为每个请求创建包含属性和事件的 span
- 模拟一些处理时间
- 记录每个请求的指标
步骤 2:启用 OpenTelemetry 运行服务器 Jump to heading
要启用 OpenTelemetry 运行服务器,请使用以下标志
OTEL_DENO=true OTEL_SERVICE_NAME=my-server deno run --unstable-otel --allow-net server.ts
步骤 3:创建一个测试客户端 Jump to heading
让我们创建一个简单的客户端来向我们的服务器发送请求
client.ts
// Send 10 requests to different paths
for (let i = 0; i < 10; i++) {
const path = ["", "about", "users", "products", "contact"][i % 5];
const url = `http://localhost:8000/${path}`;
console.log(`Sending request to ${url}`);
try {
const response = await fetch(url);
const text = await response.text();
console.log(`Response from ${url}: ${text}`);
} catch (error) {
console.error(`Error fetching ${url}:`, error);
}
}
步骤 4:运行客户端 Jump to heading
在另一个终端中,运行客户端
deno run --allow-net client.ts
步骤 5:查看遥测数据 Jump to heading
默认情况下,Deno 使用 OTLP 协议将遥测数据导出到 http://localhost:4318
。您需要一个 OpenTelemetry 收集器来接收和可视化这些数据。
设置本地收集器 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
然后访问 Grafana,地址为 http://localhost:3000(用户名:admin,密码:admin)。
在 Grafana 中,您可以
- 在 Tempo 中查看追踪,以查看单个请求 span
- 在 Mimir/Prometheus 中查看指标,以查看请求计数和持续时间
- 在 Loki 中查看日志,以查看应用程序的任何日志
理解你所看到的数据 Jump to heading
追踪 Jump to heading
在追踪视图中,您将看到以下 span:
- 服务器处理的每个 HTTP 请求
- 客户端发出的每个 fetch 请求
- 这些 span 之间的关系
点击任何 span 以查看其详细信息,包括:
- 持续时间
- 属性(http.route、http.method 等)
- 事件(request_started, processing_completed)
指标 Jump to heading
在指标视图中,您可以查询以下内容:
http_requests_total
- 跟踪 HTTP 请求数量的计数器http_request_duration_ms
- 请求持续时间的直方图
您还可以看到 Deno 内置指标,例如:
http.server.request.duration
http.server.active_requests
日志 Jump to heading
在日志视图中,您将看到应用程序的所有控制台日志,并附带正确的追踪上下文。
故障排除 Jump to heading
如果您在收集器中没有看到数据
- 检查您是否已设置
OTEL_DENO=true
并使用了--unstable-otel
标志 - 验证收集器是否正在运行并可在默认端点访问
- 检查您是否需要将
OTEL_EXPORTER_OTLP_ENDPOINT
设置为不同的 URL - 查看 Deno 控制台输出中的错误
请记住,Deno 中的 OpenTelemetry 支持仍标记为不稳定,并且可能会在未来版本中更改。
🦕 本教程为希望在 Deno 中试用 OpenTelemetry 但不立即深入复杂概念的用户提供了一个简单的起点。
这个基本示例可以通过多种方式进行扩展
- 为业务逻辑添加更多自定义指标
- 为重要操作创建额外的 span
- 使用 baggage 在服务之间传递上下文属性
- 根据指标阈值设置警报
有关更高级的用法,请参阅我们的 使用上下文传播的分布式追踪 教程。