Skip to content

OpenTelemetry

要开始使用 OpenTelemetry,请安装 @elysiajs/opentelemetry 并将插件应用于任何实例。

typescript
import { Elysia } from 'elysia'
import { opentelemetry } from '@elysiajs/opentelemetry'

import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-node'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'

new Elysia().use(
	opentelemetry({
		spanProcessors: [new BatchSpanProcessor(new OTLPTraceExporter())]
	})
)

jaeger 显示收集到的跟踪信息

Elysia OpenTelemetry 将 收集与 OpenTelemetry 标准兼容的任何库的 span,并会自动应用父子 span。

在上面的代码中,我们应用 Prisma 来跟踪每个查询所花费的时间。

通过应用 OpenTelemetry,Elysia 将:

  • 收集遥测数据
  • 将相关生命周期分组
  • 测量每个函数所花费的时间
  • 对 HTTP 请求和响应进行仪器化
  • 收集错误和异常

您可以将遥测数据导出到 Jaeger、Zipkin、New Relic、Axiom 或任何其他与 OpenTelemetry 兼容的后端。

axiom 显示收集到的 OpenTelemetry 跟踪信息

以下是将遥测数据导出到 Axiom 的示例

typescript
import { Elysia } from 'elysia'
import { opentelemetry } from '@elysiajs/opentelemetry'

import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-node'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'

new Elysia().use(
	opentelemetry({
		spanProcessors: [
			new BatchSpanProcessor(
				new OTLPTraceExporter({
					url: 'https://api.axiom.co/v1/traces', 
					headers: {

						Authorization: `Bearer ${Bun.env.AXIOM_TOKEN}`, 
						'X-Axiom-Dataset': Bun.env.AXIOM_DATASET
					} 
				})
			)
		]
	})
)

Instrumentations

Many instrumentation libraries required that the SDK MUST run before importing the module.

For example, to use PgInstrumentation, the OpenTelemetry SDK must run before importing the pg module.

To achieve this in Bun, we can

  1. Separate an OpenTelemetry setup into a different file
  2. create bunfig.toml to preload the OpenTelemetry setup file

Let's create a new file in src/instrumentation.ts

ts
import { opentelemetry } from '@elysiajs/opentelemetry'
import { PgInstrumentation } from '@opentelemetry/instrumentation-pg'

export const instrumentation = opentelemetry({
	instrumentations: [new PgInstrumentation()]
})

Then we can apply this instrumentaiton plugin into our main instance in src/index.ts

ts
import { Elysia } from 'elysia'
import { instrumentation } from './instrumentation.ts'

new Elysia().use(instrumentation).listen(3000)

Then create a bunfig.toml with the following:

toml
preload = ["./src/instrumentation.ts"]

This will tell Bun to load and setup instrumentation before running the src/index.ts allowing OpenTelemetry to do its setup as needed.

OpenTelemetry SDK

Elysia OpenTelemetry 仅用于将 OpenTelemetry 应用到 Elysia 服务器。

您可以正常使用 OpenTelemetry SDK,并且 span 在 Elysia 的请求 span 下运行,它将自动出现在 Elysia 的跟踪中。

然而,我们也提供 getTracerrecord 实用工具,以便从您应用的任何部分收集 span。

typescript
import { Elysia } from 'elysia'
import { record } from '@elysiajs/opentelemetry'

export const plugin = new Elysia().get('', () => {
	return record('database.query', () => {
		return db.query('SELECT * FROM users')
	})
})

Record 实用工具

record 相当于 OpenTelemetry 的 startActiveSpan,但它将自动处理关闭并捕获异常。

您可以将 record 看作是您的代码的标签,这将在跟踪中显示。

为可观察性准备您的代码库

Elysia OpenTelemetry 将分组生命周期并读取每个钩子的 函数名称 作为 span 的名称。

现在是 命名您的函数 的好时机。

如果您的钩子处理程序是一个箭头函数,您可以将其重构为命名函数,以便更好地理解跟踪,否则,您的跟踪 span 将被命名为 anonymous

typescript
const bad = new Elysia()
	// ⚠️ span 名称将是匿名的
	.derive(async ({ cookie: { session } }) => {
		return {
			user: await getProfile(session)
		}
	})

const good = new Elysia()
	// ✅ span 名称将是 getProfile
	.derive(async function getProfile({ cookie: { session } }) {
		return {
			user: await getProfile(session)
		}
	})

getCurrentSpan

getCurrentSpan 是一个实用工具,用于在处理程序外部获取当前请求的当前 span。

typescript
import { getCurrentSpan } from '@elysiajs/opentelemetry'

function utility() {
	const span = getCurrentSpan()
	span.setAttributes({
		'custom.attribute': 'value'
	})
}

这在处理程序外部通过从 AsyncLocalStorage 获取当前 span 而工作。

setAttribute

setAttribute 是一个用于将属性设置为当前 span 的实用工具。

typescript
import { setAttribute } from '@elysiajs/opentelemetry'

function utility() {
	setAttribute('custom.attribute', 'value')
}

这是 getCurrentSpan().setAttributes 的语法糖。

配置

请查看 opentelemetry 插件 以获取配置选项和定义。

贡献者

The avatar of contributor named as 一纸忘忧 一纸忘忧

页面历史